diff --git a/forge-cache/solidity-files-cache.json b/forge-cache/solidity-files-cache.json index 2309ac2..e50fc96 100644 --- a/forge-cache/solidity-files-cache.json +++ b/forge-cache/solidity-files-cache.json @@ -4494,7 +4494,7 @@ } }, "script/base/deploy-implementations.s.sol": { - "lastModificationDate": 1695887535699, + "lastModificationDate": 1696247985519, "contentHash": "7b91a7e4dd208eed116e3d6df13ec06b", "sourceName": "script/base/deploy-implementations.s.sol", "solcConfig": { @@ -4596,7 +4596,7 @@ } }, "script/base/deploy-platform.s.sol": { - "lastModificationDate": 1695887542037, + "lastModificationDate": 1696247985519, "contentHash": "b249659654ea2b392c4629c74cc3f49e", "sourceName": "script/base/deploy-platform.s.sol", "solcConfig": { @@ -4989,7 +4989,7 @@ } }, "script/base-goerli/deploy-implementations.s.sol": { - "lastModificationDate": 1695887525422, + "lastModificationDate": 1696247985518, "contentHash": "05dbd9c58bd38f549b31bb572d64d339", "sourceName": "script/base-goerli/deploy-implementations.s.sol", "solcConfig": { @@ -5091,7 +5091,7 @@ } }, "script/base-goerli/deploy-platform.s.sol": { - "lastModificationDate": 1695887530527, + "lastModificationDate": 1696247985518, "contentHash": "bbc66cfe0dd45bbb847a00b608e770df", "sourceName": "script/base-goerli/deploy-platform.s.sol", "solcConfig": { @@ -5383,7 +5383,7 @@ } }, "script/op/deploy-platform.s.sol": { - "lastModificationDate": 1695887548109, + "lastModificationDate": 1696247985519, "contentHash": "bd1558a2a1b08abdadcab46e1dc68d55", "sourceName": "script/op/deploy-platform.s.sol", "solcConfig": { @@ -5971,8 +5971,8 @@ } }, "src/token/ERC721/ERC721AB.sol": { - "lastModificationDate": 1695988116327, - "contentHash": "bcd226b30367a6e00094a07dca959719", + "lastModificationDate": 1696837042875, + "contentHash": "2ca82d9e75a899414e8ca74f38bd820e", "sourceName": "src/token/ERC721/ERC721AB.sol", "solcConfig": { "settings": { @@ -6029,6 +6029,66 @@ } } }, + "src/token/ERC721/ERC721ABDS.sol": { + "lastModificationDate": 1696924739124, + "contentHash": "baf6571b84c293af23184edc5b044cd7", + "sourceName": "src/token/ERC721/ERC721ABDS.sol", + "solcConfig": { + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "metadata": { + "useLiteralContent": false, + "bytecodeHash": "ipfs", + "appendCBOR": true + }, + "outputSelection": { + "*": { + "": [ + "ast" + ], + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ] + } + }, + "evmVersion": "paris", + "libraries": {} + } + }, + "imports": [ + "lib/ERC721A-Upgradeable/contracts/ERC721AStorage.sol", + "lib/ERC721A-Upgradeable/contracts/ERC721AUpgradeable.sol", + "lib/ERC721A-Upgradeable/contracts/ERC721A__Initializable.sol", + "lib/ERC721A-Upgradeable/contracts/ERC721A__InitializableStorage.sol", + "lib/ERC721A-Upgradeable/contracts/IERC721AUpgradeable.sol", + "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol", + "lib/openzeppelin-contracts/contracts/utils/Strings.sol", + "lib/openzeppelin-contracts/contracts/utils/math/Math.sol", + "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol", + "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol", + "lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol", + "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol", + "src/libraries/ABDataTypes.sol", + "src/libraries/ABErrors.sol", + "src/libraries/ABEvents.sol", + "src/token/ERC721/ERC721AB.sol", + "src/utils/IABDataRegistry.sol", + "src/utils/IABVerifier.sol" + ], + "versionRequirement": "^0.8.18", + "artifacts": { + "ERC721ABDS": { + "0.8.19+commit.7dd6d404.Darwin.appleclang": "ERC721ABDS.sol/ERC721ABDS.json" + } + } + }, "src/token/ERC721/ERC721ABLE.sol": { "lastModificationDate": 1695988127296, "contentHash": "53ccb4f12581345ed405955c2c70231c", @@ -6090,7 +6150,7 @@ } }, "src/token/ERC721/ERC721ABOE.sol": { - "lastModificationDate": 1696322758850, + "lastModificationDate": 1696836443263, "contentHash": "f31648078435acf839a046f667fd03c2", "sourceName": "src/token/ERC721/ERC721ABOE.sol", "solcConfig": { @@ -6808,7 +6868,7 @@ } }, "test/factory/AnotherCloneFactory.t.sol": { - "lastModificationDate": 1695887552259, + "lastModificationDate": 1696247985522, "contentHash": "28aa74940b4b4cac784b2cc9b9a6d370", "sourceName": "test/factory/AnotherCloneFactory.t.sol", "solcConfig": { @@ -6930,7 +6990,7 @@ } }, "test/royalty/ABRoyalty.t.sol": { - "lastModificationDate": 1695887559758, + "lastModificationDate": 1696247985522, "contentHash": "1709c4b58e65fec2eb5d4f2a98d2dab4", "sourceName": "test/royalty/ABRoyalty.t.sol", "solcConfig": { @@ -7068,7 +7128,7 @@ } }, "test/token/ERC1155/ERC1155AB.t.sol": { - "lastModificationDate": 1695887569562, + "lastModificationDate": 1696247985523, "contentHash": "7e601132d94c61b0b8aea76a591768ba", "sourceName": "test/token/ERC1155/ERC1155AB.t.sol", "solcConfig": { @@ -7214,7 +7274,7 @@ } }, "test/token/ERC721/ERC721ABLE.t.sol": { - "lastModificationDate": 1695887446720, + "lastModificationDate": 1696247985523, "contentHash": "c3871a4701ce436512f1844c328b512f", "sourceName": "test/token/ERC721/ERC721ABLE.t.sol", "solcConfig": { @@ -7355,7 +7415,7 @@ } }, "test/token/ERC721/ERC721ABOE.t.sol": { - "lastModificationDate": 1696324340850, + "lastModificationDate": 1696836443264, "contentHash": "a7b541a46d9274042a34a4f4a02dbbde", "sourceName": "test/token/ERC721/ERC721ABOE.t.sol", "solcConfig": { diff --git a/src/token/ERC721/ERC721ABDS.sol b/src/token/ERC721/ERC721ABDS.sol index fbbf1bc..e1b83c4 100644 --- a/src/token/ERC721/ERC721ABDS.sol +++ b/src/token/ERC721/ERC721ABDS.sol @@ -28,7 +28,7 @@ /** * @title ERC721ABDS * @author anotherblock Technical Team - * @notice anotherblock ERC721 contract used for regular mint mechanism & limited edition + * @notice anotherblock ERC721 contract used for dynamic share NFTs * */ @@ -49,8 +49,14 @@ contract ERC721ABDS is ERC721AB { // ___/ / /_/ /_/ / /_/ __(__ ) // /____/\__/\__,_/\__/\___/____/ - /// @dev Supply cap for this collection - uint256 public maxSupply; + /// @dev maximum amount of share units for this collection + uint256 public maxUnits; + + /// @dev amount of units sold for this collection + uint256 public soldUnits; + + /// @dev units associated to a given token + mapping(uint256 tokenId => uint256 units) public tokenUnits; /// @dev Implementation Type bytes32 public constant IMPLEMENTATION_TYPE = keccak256("DYNAMIC_SHARE"); @@ -85,10 +91,10 @@ contract ERC721ABDS is ERC721AB { * * @param _to token recipient address (must be whitelisted) * @param _phaseId current minting phase (must be started) - * @param _quantity quantity of tokens requested (must be less than max mint per phase) + * @param _units amount of units requested * @param _signature signature to verify allowlist status */ - function mint(address _to, uint256 _phaseId, uint256 _quantity, bytes calldata _signature) external payable { + function mint(address _to, uint256 _phaseId, uint256 _units, bytes calldata _signature) external payable { // Check that the requested minting phase has started if (!_isPhaseActive(_phaseId)) revert ABErrors.PHASE_NOT_ACTIVE(); @@ -96,7 +102,7 @@ contract ERC721ABDS is ERC721AB { ABDataTypes.Phase memory phase = phases[_phaseId]; // Check that there are enough tokens available for sale - if (_totalMinted() + _quantity > maxSupply) { + if (soldUnits + _units > maxUnits) { revert ABErrors.NOT_ENOUGH_TOKEN_AVAILABLE(); } @@ -108,17 +114,20 @@ contract ERC721ABDS is ERC721AB { } } - // Check that user did not mint / is not asking to mint more than the max mint per address for the current phase - if (mintedPerPhase[_to][_phaseId] + _quantity > phase.maxMint) revert ABErrors.MAX_MINT_PER_ADDRESS(); + // Check that user did not mint / is not asking to mint more units than the max mint per address for the current phase + if (mintedPerPhase[_to][_phaseId] + _units > phase.maxMint) revert ABErrors.MAX_MINT_PER_ADDRESS(); // Check that user is sending the correct amount of ETH (will revert if user send too much or not enough) - if (msg.value != phase.price * _quantity) revert ABErrors.INCORRECT_ETH_SENT(); + if (msg.value != phase.price * _units) revert ABErrors.INCORRECT_ETH_SENT(); // Set quantity minted for `_to` during the current phase - mintedPerPhase[_to][_phaseId] += _quantity; + mintedPerPhase[_to][_phaseId] += _units; + + // Set the token units for the token to be minted + tokenUnits[_nextTokenId()] = _units; // Mint `_quantity` amount to `_to` address - _mint(_to, _quantity); + _mint(_to, 1); } // ____ __ ___ __ _ @@ -133,37 +142,64 @@ contract ERC721ABDS is ERC721AB { * Initialize the Drop parameters * Only the contract owner can perform this operation * - * @param _maxSupply supply cap for this drop + * @param _maxUnits maximum amount of units to be set * @param _sharePerToken percentage ownership of the full master right for one token (to be divided by 1e6) - * @param _mintGenesis amount of genesis tokens to be minted + * @param _mintGenesisUnits amount of units associated to the genesis token to be minted * @param _genesisRecipient recipient address of genesis tokens * @param _royaltyCurrency royalty currency contract address * @param _baseUri base URI for this drop */ function initDrop( - uint256 _maxSupply, + uint256 _maxUnits, uint256 _sharePerToken, - uint256 _mintGenesis, + uint256 _mintGenesisUnits, address _genesisRecipient, address _royaltyCurrency, string calldata _baseUri ) external onlyOwner { - // Set supply cap - maxSupply = _maxSupply; - if (_mintGenesis > _maxSupply) revert ABErrors.INVALID_PARAMETER(); + if (_mintGenesisUnits > _maxUnits) revert ABErrors.INVALID_PARAMETER(); + + // Set the maximum amount of units + maxUnits = _maxUnits; + + if (_mintGenesisUnits > 0) { + // Set the token units for the token to be minted + tokenUnits[_nextTokenId()] = _mintGenesisUnits; - _initDrop(_sharePerToken, _mintGenesis, _genesisRecipient, _royaltyCurrency, _baseUri); + // Increment the amount of units sold + soldUnits += _mintGenesisUnits; + + // Initialize the drop + _initDrop(_sharePerToken, 1, _genesisRecipient, _royaltyCurrency, _baseUri); + } else { + // Initialize the drop + _initDrop(_sharePerToken, 0, _genesisRecipient, _royaltyCurrency, _baseUri); + } } /** * @notice - * Set the maximum supply + * Set the maximum amount of units * Only the contract owner can perform this operation * - * @param _maxSupply new maximum supply to be set + * @param _maxUnits new maximum amount of units to be set */ - function setMaxSupply(uint256 _maxSupply) external onlyOwner { - if (_maxSupply < _totalMinted()) revert ABErrors.INVALID_PARAMETER(); - maxSupply = _maxSupply; + function setMaxUnits(uint256 _maxUnits) external onlyOwner { + if (_maxUnits < soldUnits) revert ABErrors.INVALID_PARAMETER(); + maxUnits = _maxUnits; + } + + // ____ __ __ ______ __ _ + // / _/___ / /____ _________ ____ _/ / / ____/_ ______ _____/ /_(_)___ ____ _____ + // / // __ \/ __/ _ \/ ___/ __ \/ __ `/ / / /_ / / / / __ \/ ___/ __/ / __ \/ __ \/ ___/ + // _/ // / / / /_/ __/ / / / / / /_/ / / / __/ / /_/ / / / / /__/ /_/ / /_/ / / / (__ ) + // /___/_/ /_/\__/\___/_/ /_/ /_/\__,_/_/ /_/ \__,_/_/ /_/\___/\__/_/\____/_/ /_/____/ + + function _beforeTokenTransfers(address _from, address _to, uint256 _tokenId, uint256 _quantity) + internal + virtual + override(ERC721AB) + { + abDataRegistry.on721TokenTransfer(publisher, _from, _to, dropId, _quantity * tokenUnits[_tokenId]); } }