artblocks-contracts icon indicating copy to clipboard operation
artblocks-contracts copied to clipboard

Exponential DA w/Refund

Open ryley-o opened this issue 2 years ago • 9 comments

Add new minter - Dutch Auction with Refund.

terms:

  • sellout price: price at which an auction sells out, if above the auction base price
  • auction base price: settling price of auction

This minter enables the following:

  • User may purchase a mint at any point in time with the promise that the net-price paid for a token, after claiming refund(s), will be equal to the minimum price paid for a project's token on this minter, or the base price of the auction if an artist withdraws revenues after reaching base price.
  • User may use previously sent funds to fund new purchases (for a given project)
  • User may claim refund(s) at any time
    • Users are likely to only claim refunds after sellout or purchase at auction base price is reached, to minimize their gas to claim refunds

The minter has the following protections, prior to an artist withdrawing revenues:

  • The admin may reset/stop an auction at any point
    • This enables pausing if there is an ongoing issue preventing many users from purchasing (e.g. website outage)
    • When an auction is resumed, it must have a starting price less than or equal to the most recent purchase price on the minter (enforcing monotonically decreasing purchase prices)
  • The admin may declare an emergency reduction in sellout price (after an auction is sold out)
    • This increases refund amounts for purchasers, and is intended to only be used in emergency cases
    • The new "sellout price" must be less than existing sellout price, but >= auction base price
    • This emergency reduction may only be performed before admin or the artist withdraws revenues on the project (ensuring the minter does not owe users more than it has in its balance)

Trust Assumptions

A purchaser must trust privileged roles in the following manners (beyond the typical set of Art Blocks minter trust assumptions):

  • Artist:
    • The artist will not purchase excessive mints near the end of the auction in an effort to artificially inflate the sellout price of the auction (which would reduce purchaser refunds and potentially increase Artist revenues)
    • The artist will not unexpectedly reduce a project's maxInvocations on the core token contract during an ongoing auction in an effort to artificially inflate the sellout price of the auction (which would reduce purchaser refunds and potentially increase Artist revenues)
    • The artist will not increase auction base price after admin resets an ongoing auction with previous purchases (which would reduce the maximum possible purchaser refund if a project does not sell out before reaching base price, and potentially increase Artist revenues)

Note that an artist is disincentivized from the above actions because of community backlash that would occur against them, resulting in a loss of future art project profits. Also note that Art Blocks Admin may reset auctions and/or reduce sellout prices in emergency situations to mitigate some of these risks.

Other Design Considerations

  • Includes claimRefunds and claimRefundsTo functions that enable claiming of a user's refunds across many different projects in a single tx (improved ux and gas efficiency)
    • similar to what was implemented in #143, could make enumerable mappings that would enable a "claim all available refunds" across all projects. However, I have a slight preference to rely on indexing for enumeration, and allow our frontend to intelligently populate a call to claimRefunds with all relevant project IDs. This reduces user gas costs and the on-chain complexity associated with enumerable mappings.
  • Could (maybe?) simplify this minter by having it not become a minter once its base price is reached. However, this would likely result in a poor UX and would induce many failed transactions near the end of a DA. The current design seems like a local minimum of complexity while maintaining a very intuitive user experience.

Tests

Tests for coverage + edge cases of this minter are added in this PR.


  • To see the specific tasks where the Asana app for GitHub is being used, see below:
    • https://app.asana.com/0/0/1203322016837458

ryley-o avatar Nov 08 '22 07:11 ryley-o

@jakerockland - would appreciate your thoughts and review on this initial implementation, before I go write a bunch of tests.

diff between DAExpV2 and DAExpRefundV0: https://www.diffchecker.com/5X7KY4xK

ryley-o avatar Nov 08 '22 08:11 ryley-o

cc @mchrupcala @lyaunzbe for added vis.

jakerockland avatar Nov 08 '22 19:11 jakerockland

I've added events that are emitted every time a user's receipt is updated in e17c8ae

ryley-o avatar Nov 08 '22 21:11 ryley-o

Added functions that enable a user to claim refunds across multiple projects in a single transaction in commit b839fd0

ryley-o avatar Nov 08 '22 21:11 ryley-o

@jakerockland - I've updated this PR's description based on recent merge of #386, and tagged you in a design-ish question in the TODO section 🙏 Also tagged you in a note in ## Trust Assumptions 🙏

ryley-o avatar Nov 15 '22 22:11 ryley-o

@jakerockland - tagging this as ready for review now that tests have been added and some minor iterations have been completed. Although you have already given a ✅ , would appreciate a second read-though of the minter.

diffchecker between DAExpV2 and DAExpRefundV0 here: https://www.diffchecker.com/WnpFrP0c

Any suggestions on any additional reviewers for this?

ryley-o avatar Nov 17 '22 19:11 ryley-o

@jakerockland - tagging this as ready for review now that tests have been added and some minor iterations have been completed. Although you have already given a ✅ , would appreciate a second read-though of the minter.

diffchecker between DAExpV2 and DAExpRefundV0 here: https://www.diffchecker.com/WnpFrP0c

Any suggestions on any additional reviewers for this?

I will do an initial review pass by EOD–but given the sensitivity of this functionality lets add @yoshiwarab @lyaunzbe and @mchrupcala as additional reviewers here as well.

jakerockland avatar Nov 17 '22 20:11 jakerockland

I do want to note that there is probably some gas golf that can be played on this minter, but I'm comfortable merging and doing that as follow-on work. totally open to feedback that improves gas efficiency here though, too!

ryley-o avatar Nov 17 '22 21:11 ryley-o

@jakerockland - heads-up that I added a convenience getter function to help with subgraph code efficiency in commit 7a7bf22 🙏 Also - added a convenience getter function for number of refundable invocations, for same reason, in commit e0b7890

ryley-o avatar Nov 23 '22 20:11 ryley-o

@mchrupcala - thank you for your review! I've pushed an update to fix typo. please see my responses and either resolve if you are satisfied or continue the convo 🙏 ✌️ (also, please excuse/ignore the outdated warning on your comments - we updated some of the nomenclature to better reflect that this minter is acting as a settlement layer, and the term "refund" is a bit of a misnomer)

ryley-o avatar Nov 30 '22 06:11 ryley-o