-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auction Modules and Base Implementation #4
Auction Modules and Base Implementation #4
Conversation
PRO-220 Auction module interface and base implementation
First goal: should be compatible with our existing formats (see buy edition)
Compare delegate call vs pure extension options and write out a doc. We will discuss + get some input on the path forwards. Tradeoffs in terms of security, flexibility, provenenance/tx history, etc. |
|
|
||
pragma solidity ^0.8.15; | ||
|
||
contract OwnedMintees { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed SoundNft
to SoundEdition
in this PR, and I think it might be more clear to use "edition" whenever we're referring to that contract (ie: instead of "mintee").
Also using "owner" makes it sound like SoundEdition.owner()
, so maybe MintController
instead?
So for this contract, maybe MintControllers
or EditionMintControllers
instead of OwnedMintees
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me.
I will rename it to EditionMinter
.
062b855
to
c9a21d2
Compare
723da8e
to
7c74f00
Compare
For simplicity, I've not added the following features for now
|
// ================================ | ||
// CONSTANTS | ||
// ================================ | ||
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows for multiple minters to be set per edition. Is this something we want?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
An artist may want to run different kinds of sales simultaneously.
ERC721AQueryableUpgradeable, | ||
IERC2981Upgradeable, | ||
OwnableUpgradeable, | ||
AccessControlUpgradeable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why build in upgradability if SoundEdition is to be immutable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good question on the team level we may need to revisit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elenadimitrova as the SoundEditions are currently being deployed via Clone Proxy, that's why the base contract is using Upgradeable contracts.
function _deleteEditionMint(address edition) internal virtual { | ||
address controller = _controllers[edition]; | ||
if (controller == address(0)) revert MintNotFound(); | ||
if (msg.sender != controller) revert MintControllerUnauthorized(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can reuse the existing onlyEditionMintController
modifier here instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
virtual | ||
onlyEditionMintController(edition) | ||
{ | ||
if (controller == address(0)) revert MintControllerSetToZeroAddress(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this condition we can remove _deleteEditionMint
implementation and simply allow controller
address to be set to 0
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds ok to me.
} | ||
|
||
function editionMintController(address edition) public view returns (address) { | ||
return _controllers[edition]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this explicit function we can simply make _controllers
mapping public and expose it in the minter interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to give it a descriptive public accessor, but still keep the internal name short.
|
||
pragma solidity ^0.8.15; | ||
|
||
abstract contract EditionMinter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify what purpose does this contract serve? I see that the minters are based off it and they write to the controllers
mapping but I don't understand why we need that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think however that we need a specific interface for Minters which external developers can implement in a way of a standard our interface can integrate with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that our own minter classes have the common logic to allow different wallets to control different edition mints. This is simply for code reuse.
chiru-labs/ERC721A-Upgradeable/=./lib/ERC721A-Upgradeable/contracts/ | ||
solady/=./lib/solady/src/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use Open Zeppelin ECDSA.sol
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For performance reasons. This saves 700 gas. It also has a much simpler API: returns a zero-address in any case of errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we submit that as an improvement proposal to OZ? Or is it not applicable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code snippets in Solady are designed as PRs to Solmate. transmissions11/solmate#247
Not applicable to OZ — their maintainers have expressed interest to keep the various errors OpenZeppelin/openzeppelin-contracts#3457 (comment)
Solady also contains the very optimized on-chain sort that may be useful for building the cap tables later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is something on OZ's backlog for the next release related to this though (https://github.com/OpenZeppelin/openzeppelin-contracts/milestone/12) 🤔
@@ -30,8 +30,16 @@ Sound Protocol 2.0 enables creators to permissinonlessly deploy gas-efficient NF | |||
- `tokenURI` uses `baseURI` instead, if `metadataModule` is not present | |||
- Implements `contractURI` (https://docs.opensea.io/docs/contract-level-metadata) | |||
- Allows freezing of metadata, beyond which the variables can't be modified by `owner` | |||
- Minters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add the detail that we allow multiple minters enabled on a SoundEdition at the same time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I think it's worth describing the model for developing Minter extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike metadata module, minters are free to be in any shape and form — our edition contracts will not call them. Only the minters contracts will call the edition contract. It’s a one-way data flow.
Will add into the comments.
…Vectorized/sound-protocol into vectorized/pro-220-auction-base
Ah but why close it? We'll lose all traceability of reviews |
I mistakenly opened a fork for PR cuz didn’t have permission to create a branch back then. I’ll keep a link on the new PR’s description to this closed PR. |
Actually, I'd prefer to call it minting, so that it can generalize to all kinds of drops.
Terminology:
Minter contracts are current non-upgradeable (will change later if needed).
Actually, we don't need to make these Minting contracts upgradeable.
Flow:
createEdition
on a Minter contract.mint
function on the Minter contract, which will then call themint
function on theedition
, passing along themsg.value
.Details:
So, instead of having the public auction and the permissioned auction combined, we split them into two different files.
If we want, we can add a combined public and permissioned auction like ArtistV6.
createEdition
anddeleteEdition
functions on theMinter
contract. Do we need functions to edit each of the fields individually? This will add quite a bit of work.