Skip to content
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

Closed

Conversation

Vectorized
Copy link
Collaborator

@Vectorized Vectorized commented Jul 20, 2022

Actually, I'd prefer to call it minting, so that it can generalize to all kinds of drops.

Terminology:

  • Minter (A contract that calls the mint function on the NFT contract)
  • Edition (The NFT contract called by the minter)

Minter contracts are current non-upgradeable (will change later if needed).

Actually, we don't need to make these Minting contracts upgradeable.

Flow:

  • Artist call createEdition on a Minter contract.
  • Buyers will call the mint function on the Minter contract, which will then call the mint function on the edition, passing along the msg.value.

Details:

  • Each type of auction is in a different Solidity file. This is for modularity and code reuse.
    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.
  • For now, we only have the createEdition and deleteEdition functions on the Minter contract. Do we need functions to edit each of the fields individually? This will add quite a bit of work.

@linear
Copy link

linear bot commented Jul 20, 2022

PRO-220 Auction module interface and base implementation

First goal: should be compatible with our existing formats (see buy edition)

  • signature gated minting, range editions / open editions
  • should be able to support out of the box formats with ability to plug in custom ones + rules
    • airdrop to a passed in list
    • reserve x amount of tokens for manual transfers by the artist
    • set price discounts for a given list of users for a given song
    • set minting rules e.g. address can only buy a maximum of 3 of this song
    • auction: fixed mint, dutch auction, free mint for x period, bonding curves
  • Nice to haves: compatibility or easy porting of existing Manifold extensions
  • Freeze function

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.

@changeset-bot
Copy link

changeset-bot bot commented Jul 20, 2022

⚠️ No Changeset found

Latest commit: 1fa1b97

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR


pragma solidity ^0.8.15;

contract OwnedMintees {
Copy link
Contributor

@gigamesh gigamesh Jul 20, 2022

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?

Copy link
Collaborator Author

@Vectorized Vectorized Jul 20, 2022

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.

@Vectorized Vectorized force-pushed the vectorized/pro-220-auction-base branch 3 times, most recently from 062b855 to c9a21d2 Compare July 21, 2022 21:11
@Vectorized Vectorized force-pushed the vectorized/pro-220-auction-base branch from 723da8e to 7c74f00 Compare July 21, 2022 23:12
@Vectorized Vectorized marked this pull request as ready for review July 21, 2022 23:12
@Vectorized
Copy link
Collaborator Author

For simplicity, I've not added the following features for now
(cuz I'll need to write way more tests for them):

  • Edit the fields in the EditionMintData.
  • Restrict a wallet to mint up to a certain number of NFTs.

// ================================
// CONSTANTS
// ================================
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

@Vectorized Vectorized changed the title Auctions Proof of Concept 0 [WIP] Auction Modules and Base Implementation Jul 25, 2022
ERC721AQueryableUpgradeable,
IERC2981Upgradeable,
OwnableUpgradeable,
AccessControlUpgradeable
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

@apoorvlathey apoorvlathey Jul 27, 2022

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();
Copy link
Contributor

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.

Copy link
Collaborator Author

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();
Copy link
Contributor

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.

Copy link
Collaborator Author

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];
Copy link
Contributor

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.

Copy link
Collaborator Author

@Vectorized Vectorized Jul 26, 2022

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 {
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Collaborator Author

@Vectorized Vectorized Jul 26, 2022

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/
Copy link
Contributor

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 ?

Copy link
Collaborator Author

@Vectorized Vectorized Jul 26, 2022

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.

Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Collaborator Author

@Vectorized Vectorized Jul 26, 2022

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.

@elenadimitrova
Copy link
Contributor

Ah but why close it? We'll lose all traceability of reviews

@Vectorized
Copy link
Collaborator Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants