@rarible/external-contracts 3.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +201 -0
- package/README.md +144 -0
- package/contracts/base/ERC1155Base.sol +282 -0
- package/contracts/base/ERC1155DelayedReveal.sol +117 -0
- package/contracts/base/ERC1155Drop.sol +368 -0
- package/contracts/base/ERC1155LazyMint.sol +286 -0
- package/contracts/base/ERC1155SignatureMint.sol +132 -0
- package/contracts/base/ERC20Base.sol +111 -0
- package/contracts/base/ERC20Drop.sol +157 -0
- package/contracts/base/ERC20DropVote.sol +135 -0
- package/contracts/base/ERC20SignatureMint.sol +100 -0
- package/contracts/base/ERC20SignatureMintVote.sol +107 -0
- package/contracts/base/ERC20Vote.sol +111 -0
- package/contracts/base/ERC721Base.sol +210 -0
- package/contracts/base/ERC721DelayedReveal.sol +118 -0
- package/contracts/base/ERC721Drop.sol +312 -0
- package/contracts/base/ERC721LazyMint.sol +219 -0
- package/contracts/base/ERC721Multiwrap.sol +262 -0
- package/contracts/base/ERC721SignatureMint.sol +120 -0
- package/contracts/base/Staking1155Base.sol +189 -0
- package/contracts/base/Staking20Base.sol +179 -0
- package/contracts/base/Staking721Base.sol +186 -0
- package/contracts/eip/ERC1155.sol +294 -0
- package/contracts/eip/ERC1271.sol +18 -0
- package/contracts/eip/ERC165.sol +29 -0
- package/contracts/eip/ERC721A.sol +580 -0
- package/contracts/eip/ERC721AUpgradeable.sol +625 -0
- package/contracts/eip/ERC721AVirtualApprove.sol +582 -0
- package/contracts/eip/ERC721AVirtualApproveUpgradeable.sol +598 -0
- package/contracts/eip/interface/IERC1155.sol +132 -0
- package/contracts/eip/interface/IERC1155Enumerable.sol +11 -0
- package/contracts/eip/interface/IERC1155Metadata.sol +15 -0
- package/contracts/eip/interface/IERC1155Receiver.sol +58 -0
- package/contracts/eip/interface/IERC1155Supply.sol +11 -0
- package/contracts/eip/interface/IERC165.sol +25 -0
- package/contracts/eip/interface/IERC20.sol +24 -0
- package/contracts/eip/interface/IERC20Metadata.sol +14 -0
- package/contracts/eip/interface/IERC20Permit.sol +60 -0
- package/contracts/eip/interface/IERC2981.sol +23 -0
- package/contracts/eip/interface/IERC4906.sol +17 -0
- package/contracts/eip/interface/IERC721.sol +128 -0
- package/contracts/eip/interface/IERC721A.sol +109 -0
- package/contracts/eip/interface/IERC721Enumerable.sol +24 -0
- package/contracts/eip/interface/IERC721Metadata.sol +20 -0
- package/contracts/eip/interface/IERC721Receiver.sol +27 -0
- package/contracts/eip/interface/IERC721Supply.sol +13 -0
- package/contracts/eip/queryable/ERC721AQueryable.sol +168 -0
- package/contracts/eip/queryable/ERC721AQueryableUpgradeable.sol +193 -0
- package/contracts/eip/queryable/ERC721AStorage.sol +57 -0
- package/contracts/eip/queryable/ERC721AUpgradeable.sol +1075 -0
- package/contracts/eip/queryable/ERC721A__Initializable.sol +75 -0
- package/contracts/eip/queryable/ERC721A__InitializableStorage.sol +29 -0
- package/contracts/eip/queryable/IERC721AQueryable.sol +69 -0
- package/contracts/eip/queryable/IERC721AQueryableUpgradeable.sol +69 -0
- package/contracts/eip/queryable/IERC721AUpgradeable.sol +269 -0
- package/contracts/extension/AppURI.sol +37 -0
- package/contracts/extension/BatchMintMetadata.sol +143 -0
- package/contracts/extension/BurnToClaim.sol +60 -0
- package/contracts/extension/ContractMetadata.sol +48 -0
- package/contracts/extension/DelayedReveal.sol +111 -0
- package/contracts/extension/Drop.sol +284 -0
- package/contracts/extension/Drop1155.sol +300 -0
- package/contracts/extension/DropSinglePhase.sol +237 -0
- package/contracts/extension/DropSinglePhase1155.sol +215 -0
- package/contracts/extension/Initializable.sol +136 -0
- package/contracts/extension/LazyMint.sol +56 -0
- package/contracts/extension/LazyMintWithTier.sol +112 -0
- package/contracts/extension/Multicall.sol +40 -0
- package/contracts/extension/NFTMetadata.sol +58 -0
- package/contracts/extension/OperatorFilterToggle.sol +22 -0
- package/contracts/extension/OperatorFilterer.sol +73 -0
- package/contracts/extension/OperatorFiltererUpgradeable.sol +69 -0
- package/contracts/extension/Ownable.sol +58 -0
- package/contracts/extension/Permissions.sol +159 -0
- package/contracts/extension/PermissionsEnumerable.sol +111 -0
- package/contracts/extension/PlatformFee.sol +117 -0
- package/contracts/extension/PrimarySale.sol +57 -0
- package/contracts/extension/Proxy.sol +84 -0
- package/contracts/extension/ProxyForUpgradeable.sol +32 -0
- package/contracts/extension/Royalty.sol +134 -0
- package/contracts/extension/SeaportEIP1271.sol +88 -0
- package/contracts/extension/SeaportOrderParser.sol +550 -0
- package/contracts/extension/SharedMetadata.sol +63 -0
- package/contracts/extension/SignatureAction.sol +67 -0
- package/contracts/extension/SignatureActionUpgradeable.sol +71 -0
- package/contracts/extension/SignatureMintERC1155.sol +78 -0
- package/contracts/extension/SignatureMintERC1155Upgradeable.sol +84 -0
- package/contracts/extension/SignatureMintERC20.sol +70 -0
- package/contracts/extension/SignatureMintERC20Upgradeable.sol +77 -0
- package/contracts/extension/SignatureMintERC721.sol +96 -0
- package/contracts/extension/SignatureMintERC721Upgradeable.sol +102 -0
- package/contracts/extension/SoulboundERC721A.sol +51 -0
- package/contracts/extension/Staking1155.sol +516 -0
- package/contracts/extension/Staking1155Upgradeable.sol +516 -0
- package/contracts/extension/Staking20.sol +376 -0
- package/contracts/extension/Staking20Upgradeable.sol +383 -0
- package/contracts/extension/Staking721.sol +362 -0
- package/contracts/extension/Staking721Upgradeable.sol +364 -0
- package/contracts/extension/TokenBundle.sol +130 -0
- package/contracts/extension/TokenStore.sol +97 -0
- package/contracts/extension/Upgradeable.sol +95 -0
- package/contracts/extension/interface/IAccountPermissions.sol +114 -0
- package/contracts/extension/interface/IAppURI.sol +24 -0
- package/contracts/extension/interface/IBurnToClaim.sol +43 -0
- package/contracts/extension/interface/IBurnableERC1155.sol +16 -0
- package/contracts/extension/interface/IBurnableERC20.sol +26 -0
- package/contracts/extension/interface/IBurnableERC721.sol +15 -0
- package/contracts/extension/interface/IClaimCondition.sol +48 -0
- package/contracts/extension/interface/IClaimConditionMultiPhase.sol +39 -0
- package/contracts/extension/interface/IClaimConditionsSinglePhase.sol +31 -0
- package/contracts/extension/interface/IClaimableERC1155.sol +39 -0
- package/contracts/extension/interface/IClaimableERC721.sol +37 -0
- package/contracts/extension/interface/IContractFactory.sol +20 -0
- package/contracts/extension/interface/IContractMetadata.sol +25 -0
- package/contracts/extension/interface/IDelayedReveal.sol +33 -0
- package/contracts/extension/interface/IDelayedRevealDeprecated.sol +38 -0
- package/contracts/extension/interface/IDrop.sol +72 -0
- package/contracts/extension/interface/IDrop1155.sol +75 -0
- package/contracts/extension/interface/IDropSinglePhase.sol +70 -0
- package/contracts/extension/interface/IDropSinglePhase1155.sol +74 -0
- package/contracts/extension/interface/IERC2771Context.sol +6 -0
- package/contracts/extension/interface/ILazyMint.sol +33 -0
- package/contracts/extension/interface/ILazyMintWithTier.sol +43 -0
- package/contracts/extension/interface/IMintableERC1155.sol +24 -0
- package/contracts/extension/interface/IMintableERC20.sol +20 -0
- package/contracts/extension/interface/IMintableERC721.sol +19 -0
- package/contracts/extension/interface/IMulticall.sol +16 -0
- package/contracts/extension/interface/INFTMetadata.sol +17 -0
- package/contracts/extension/interface/IOperatorFilterRegistry.sol +54 -0
- package/contracts/extension/interface/IOperatorFilterToggle.sol +12 -0
- package/contracts/extension/interface/IOwnable.sol +21 -0
- package/contracts/extension/interface/IPermissions.sol +88 -0
- package/contracts/extension/interface/IPermissionsEnumerable.sol +31 -0
- package/contracts/extension/interface/IPlatformFee.sol +33 -0
- package/contracts/extension/interface/IPrimarySale.sol +21 -0
- package/contracts/extension/interface/IRoyalty.sol +39 -0
- package/contracts/extension/interface/IRoyaltyEngineV1.sol +42 -0
- package/contracts/extension/interface/IRoyaltyPayments.sol +37 -0
- package/contracts/extension/interface/IRulesEngine.sol +58 -0
- package/contracts/extension/interface/ISharedMetadata.sol +30 -0
- package/contracts/extension/interface/ISharedMetadataBatch.sol +57 -0
- package/contracts/extension/interface/ISignatureAction.sol +44 -0
- package/contracts/extension/interface/ISignatureMintERC1155.sol +77 -0
- package/contracts/extension/interface/ISignatureMintERC20.sol +64 -0
- package/contracts/extension/interface/ISignatureMintERC721.sol +75 -0
- package/contracts/extension/interface/IStaking1155.sol +110 -0
- package/contracts/extension/interface/IStaking20.sol +97 -0
- package/contracts/extension/interface/IStaking721.sol +83 -0
- package/contracts/extension/interface/ITokenBundle.sol +52 -0
- package/contracts/extension/interface/plugin/IContext.sol +10 -0
- package/contracts/extension/interface/plugin/IPluginMap.sol +31 -0
- package/contracts/extension/interface/plugin/IRouter.sol +30 -0
- package/contracts/extension/plugin/ContractMetadataLogic.sol +52 -0
- package/contracts/extension/plugin/ContractMetadataStorage.sol +25 -0
- package/contracts/extension/plugin/ERC2771ContextConsumer.sol +34 -0
- package/contracts/extension/plugin/ERC2771ContextLogic.sol +43 -0
- package/contracts/extension/plugin/ERC2771ContextStorage.sol +22 -0
- package/contracts/extension/plugin/ERC2771ContextUpgradeableLogic.sol +47 -0
- package/contracts/extension/plugin/ERC2771ContextUpgradeableStorage.sol +20 -0
- package/contracts/extension/plugin/PermissionsEnumerableLogic.sol +101 -0
- package/contracts/extension/plugin/PermissionsEnumerableStorage.sol +41 -0
- package/contracts/extension/plugin/PermissionsLogic.sol +182 -0
- package/contracts/extension/plugin/PermissionsStorage.sol +28 -0
- package/contracts/extension/plugin/PlatformFeeLogic.sol +56 -0
- package/contracts/extension/plugin/PlatformFeeStorage.sol +28 -0
- package/contracts/extension/plugin/PluginMap.sol +81 -0
- package/contracts/extension/plugin/ReentrancyGuardLogic.sol +69 -0
- package/contracts/extension/plugin/ReentrancyGuardStorage.sol +22 -0
- package/contracts/extension/plugin/Router.sol +270 -0
- package/contracts/extension/plugin/RouterImmutable.sol +26 -0
- package/contracts/extension/plugin/RoyaltyPayments.sol +121 -0
- package/contracts/extension/upgradeable/AccountPermissions.sol +253 -0
- package/contracts/extension/upgradeable/BatchMintMetadata.sol +144 -0
- package/contracts/extension/upgradeable/BurnToClaim.sol +83 -0
- package/contracts/extension/upgradeable/ContractMetadata.sol +73 -0
- package/contracts/extension/upgradeable/DelayedReveal.sol +126 -0
- package/contracts/extension/upgradeable/Drop.sol +278 -0
- package/contracts/extension/upgradeable/ERC2771Context.sol +64 -0
- package/contracts/extension/upgradeable/ERC2771ContextConsumer.sol +32 -0
- package/contracts/extension/upgradeable/ERC2771ContextUpgradeable.sol +72 -0
- package/contracts/extension/upgradeable/Initializable.sol +110 -0
- package/contracts/extension/upgradeable/LazyMint.sol +77 -0
- package/contracts/extension/upgradeable/OperatorFilterToggle.sol +47 -0
- package/contracts/extension/upgradeable/OperatorFiltererUpgradeable.sol +58 -0
- package/contracts/extension/upgradeable/Ownable.sol +75 -0
- package/contracts/extension/upgradeable/Permissions.sol +197 -0
- package/contracts/extension/upgradeable/PermissionsEnumerable.sol +134 -0
- package/contracts/extension/upgradeable/PlatformFee.sol +131 -0
- package/contracts/extension/upgradeable/PrimarySale.sol +69 -0
- package/contracts/extension/upgradeable/ReentrancyGuard.sol +53 -0
- package/contracts/extension/upgradeable/Royalty.sol +144 -0
- package/contracts/extension/upgradeable/RoyaltyPayments.sol +121 -0
- package/contracts/extension/upgradeable/RulesEngine.sol +163 -0
- package/contracts/extension/upgradeable/SharedMetadataBatch.sol +98 -0
- package/contracts/extension/upgradeable/impl/ContractMetadataImpl.sol +34 -0
- package/contracts/extension/upgradeable/impl/MetaTx.sol +8 -0
- package/contracts/extension/upgradeable/impl/PermissionsEnumerableImpl.sol +28 -0
- package/contracts/extension/upgradeable/impl/PlatformFeeImpl.sol +34 -0
- package/contracts/extension/upgradeable/init/ContractMetadataInit.sol +17 -0
- package/contracts/extension/upgradeable/init/ERC2771ContextInit.sol +19 -0
- package/contracts/extension/upgradeable/init/ERC721AInit.sol +23 -0
- package/contracts/extension/upgradeable/init/ERC721AQueryableInit.sol +21 -0
- package/contracts/extension/upgradeable/init/OwnableInit.sol +18 -0
- package/contracts/extension/upgradeable/init/PermissionsEnumerableInit.sol +23 -0
- package/contracts/extension/upgradeable/init/PermissionsInit.sol +27 -0
- package/contracts/extension/upgradeable/init/PlatformFeeInit.sol +25 -0
- package/contracts/extension/upgradeable/init/PrimarySaleInit.sol +19 -0
- package/contracts/extension/upgradeable/init/ReentrancyGuardInit.sol +18 -0
- package/contracts/extension/upgradeable/init/RoyaltyInit.sol +22 -0
- package/contracts/external-deps/chainlink/LinkTokenInterface.sol +28 -0
- package/contracts/external-deps/chainlink/VRFV2WrapperConsumerBase.sol +83 -0
- package/contracts/external-deps/chainlink/VRFV2WrapperInterface.sol +35 -0
- package/contracts/external-deps/openzeppelin/ERC1155PresetUpgradeable.sol +160 -0
- package/contracts/external-deps/openzeppelin/cryptography/EIP712ChainlessDomain.sol +100 -0
- package/contracts/external-deps/openzeppelin/finance/PaymentSplitterUpgradeable.sol +231 -0
- package/contracts/external-deps/openzeppelin/governance/utils/IVotes.sol +54 -0
- package/contracts/external-deps/openzeppelin/metatx/ERC2771Context.sol +44 -0
- package/contracts/external-deps/openzeppelin/metatx/ERC2771ContextUpgradeable.sol +50 -0
- package/contracts/external-deps/openzeppelin/metatx/MinimalForwarderEOAOnly.sol +67 -0
- package/contracts/external-deps/openzeppelin/proxy/Clones.sol +88 -0
- package/contracts/external-deps/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol +32 -0
- package/contracts/external-deps/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol +173 -0
- package/contracts/external-deps/openzeppelin/proxy/IERC1822Proxiable.sol +20 -0
- package/contracts/external-deps/openzeppelin/proxy/Proxy.sol +86 -0
- package/contracts/external-deps/openzeppelin/proxy/beacon/IBeacon.sol +16 -0
- package/contracts/external-deps/openzeppelin/proxy/utils/Initializable.sol +138 -0
- package/contracts/external-deps/openzeppelin/security/ReentrancyGuard.sol +32 -0
- package/contracts/external-deps/openzeppelin/security/ReentrancyGuardUpgradeable.sol +44 -0
- package/contracts/external-deps/openzeppelin/token/ERC1155/IERC1155Receiver.sol +58 -0
- package/contracts/external-deps/openzeppelin/token/ERC1155/utils/ERC1155Holder.sol +36 -0
- package/contracts/external-deps/openzeppelin/token/ERC1155/utils/ERC1155Receiver.sol +19 -0
- package/contracts/external-deps/openzeppelin/token/ERC20/ERC20.sol +359 -0
- package/contracts/external-deps/openzeppelin/token/ERC20/extensions/ERC20Permit.sol +117 -0
- package/contracts/external-deps/openzeppelin/token/ERC20/extensions/ERC20Votes.sol +246 -0
- package/contracts/external-deps/openzeppelin/token/ERC20/utils/SafeERC20.sol +78 -0
- package/contracts/external-deps/openzeppelin/token/ERC721/IERC721Receiver.sol +27 -0
- package/contracts/external-deps/openzeppelin/token/ERC721/utils/ERC721Holder.sol +23 -0
- package/contracts/external-deps/openzeppelin/utils/Base64.sol +92 -0
- package/contracts/external-deps/openzeppelin/utils/Context.sol +24 -0
- package/contracts/external-deps/openzeppelin/utils/Counters.sol +43 -0
- package/contracts/external-deps/openzeppelin/utils/Create2.sol +58 -0
- package/contracts/external-deps/openzeppelin/utils/ERC1155/ERC1155Holder.sol +36 -0
- package/contracts/external-deps/openzeppelin/utils/ERC1155/ERC1155Receiver.sol +19 -0
- package/contracts/external-deps/openzeppelin/utils/ERC721/ERC721Holder.sol +23 -0
- package/contracts/external-deps/openzeppelin/utils/EnumerableSet.sol +367 -0
- package/contracts/external-deps/openzeppelin/utils/cryptography/ECDSA.sol +217 -0
- package/contracts/external-deps/openzeppelin/utils/cryptography/EIP712.sol +104 -0
- package/contracts/external-deps/openzeppelin/utils/math/Math.sol +43 -0
- package/contracts/external-deps/openzeppelin/utils/math/SafeCast.sol +241 -0
- package/contracts/external-deps/openzeppelin/utils/math/SafeMath.sol +215 -0
- package/contracts/external-deps/openzeppelin/utils/structs/EnumerableSet.sol +367 -0
- package/contracts/infra/ContractPublisher.sol +268 -0
- package/contracts/infra/TWFactory.sol +140 -0
- package/contracts/infra/TWFee.sol +162 -0
- package/contracts/infra/TWMinimalFactory.sol +47 -0
- package/contracts/infra/TWMultichainRegistry.sol +116 -0
- package/contracts/infra/TWProxy.sol +42 -0
- package/contracts/infra/TWRegistry.sol +70 -0
- package/contracts/infra/TWStatelessFactory.sol +47 -0
- package/contracts/infra/forwarder/Forwarder.sol +76 -0
- package/contracts/infra/forwarder/ForwarderChainlessDomain.sol +90 -0
- package/contracts/infra/forwarder/ForwarderConsumer.sol +25 -0
- package/contracts/infra/forwarder/ForwarderEOAOnly.sol +23 -0
- package/contracts/infra/interface/IContractDeployer.sol +54 -0
- package/contracts/infra/interface/IContractPublisher.sol +128 -0
- package/contracts/infra/interface/ITWFee.sol +6 -0
- package/contracts/infra/interface/ITWMultichainRegistry.sol +28 -0
- package/contracts/infra/interface/ITWRegistry.sol +24 -0
- package/contracts/infra/interface/IThirdwebContract.sol +19 -0
- package/contracts/infra/interface/IWETH.sol +10 -0
- package/contracts/infra/registry/entrypoint/TWMultichainRegistryRouter.sol +61 -0
- package/contracts/infra/registry/registry-extension/TWMultichainRegistryLogic.sol +120 -0
- package/contracts/infra/registry/registry-extension/TWMultichainRegistryStorage.sol +30 -0
- package/contracts/legacy-contracts/extension/BatchMintMetadata_V1.sol +89 -0
- package/contracts/legacy-contracts/extension/DropSinglePhase1155_V1.sol +268 -0
- package/contracts/legacy-contracts/extension/DropSinglePhase_V1.sol +252 -0
- package/contracts/legacy-contracts/extension/LazyMintWithTier_V1.sol +112 -0
- package/contracts/legacy-contracts/extension/LazyMint_V1.sol +52 -0
- package/contracts/legacy-contracts/extension/PlatformFee_V1.sol +69 -0
- package/contracts/legacy-contracts/extension/PrimarySale_V1.sol +53 -0
- package/contracts/legacy-contracts/extension/interface/IClaimCondition_V1.sol +54 -0
- package/contracts/legacy-contracts/extension/interface/IDropSinglePhase1155_V1.sol +58 -0
- package/contracts/legacy-contracts/extension/interface/IDropSinglePhase_V1.sol +54 -0
- package/contracts/legacy-contracts/extension/interface/IPlatformFee_V1.sol +21 -0
- package/contracts/legacy-contracts/extension/interface/IPrimarySale_V1.sol +21 -0
- package/contracts/legacy-contracts/interface/ISignatureMintERC721_V1.sol +18 -0
- package/contracts/legacy-contracts/interface/drop/IDropClaimCondition_V2.sol +82 -0
- package/contracts/legacy-contracts/interface/drop/IDropERC1155_V2.sol +96 -0
- package/contracts/legacy-contracts/interface/drop/IDropERC20_V2.sol +73 -0
- package/contracts/legacy-contracts/interface/drop/IDropERC721_V3.sol +98 -0
- package/contracts/legacy-contracts/pre-builts/DropERC1155_V2.sol +731 -0
- package/contracts/legacy-contracts/pre-builts/DropERC20_V2.sol +521 -0
- package/contracts/legacy-contracts/pre-builts/DropERC721_V3.sol +745 -0
- package/contracts/legacy-contracts/pre-builts/SignatureDrop_V4.sol +360 -0
- package/contracts/legacy-contracts/smart-wallet/interface/IAccountPermissions_V1.sol +115 -0
- package/contracts/lib/Address.sol +244 -0
- package/contracts/lib/BitMaps.sol +52 -0
- package/contracts/lib/BytesLib.sol +18 -0
- package/contracts/lib/CurrencyTransferLib.sol +96 -0
- package/contracts/lib/FeeType.sol +10 -0
- package/contracts/lib/MerkleProof.sol +40 -0
- package/contracts/lib/NFTMetadataRenderer.sol +91 -0
- package/contracts/lib/StorageSlot.sol +54 -0
- package/contracts/lib/StringSet.sol +107 -0
- package/contracts/lib/Strings.sol +195 -0
- package/contracts/prebuilts/account/dynamic/DynamicAccount.sol +48 -0
- package/contracts/prebuilts/account/dynamic/DynamicAccountFactory.sol +61 -0
- package/contracts/prebuilts/account/interfaces/IAccount.sol +39 -0
- package/contracts/prebuilts/account/interfaces/IAccountCore.sol +11 -0
- package/contracts/prebuilts/account/interfaces/IAccountExecute.sol +17 -0
- package/contracts/prebuilts/account/interfaces/IAccountFactory.sol +16 -0
- package/contracts/prebuilts/account/interfaces/IAccountFactoryCore.sol +40 -0
- package/contracts/prebuilts/account/interfaces/IAggregator.sol +41 -0
- package/contracts/prebuilts/account/interfaces/IEntryPoint.sol +204 -0
- package/contracts/prebuilts/account/interfaces/INonceManager.sol +25 -0
- package/contracts/prebuilts/account/interfaces/IOracle.sol +10 -0
- package/contracts/prebuilts/account/interfaces/IPaymaster.sol +63 -0
- package/contracts/prebuilts/account/interfaces/IStakeManager.sol +94 -0
- package/contracts/prebuilts/account/interfaces/PackedUserOperation.sol +28 -0
- package/contracts/prebuilts/account/managed/ManagedAccount.sol +33 -0
- package/contracts/prebuilts/account/managed/ManagedAccountFactory.sol +68 -0
- package/contracts/prebuilts/account/non-upgradeable/Account.sol +169 -0
- package/contracts/prebuilts/account/non-upgradeable/AccountFactory.sol +54 -0
- package/contracts/prebuilts/account/token-bound-account/TokenBoundAccount.sol +252 -0
- package/contracts/prebuilts/account/token-bound-account/erc6551-utils/ERC6551AccountLib.sol +44 -0
- package/contracts/prebuilts/account/token-bound-account/erc6551-utils/ERC6551BytecodeLib.sol +20 -0
- package/contracts/prebuilts/account/token-bound-account/erc6551-utils/IERC6551Account.sol +51 -0
- package/contracts/prebuilts/account/token-paymaster/BasePaymaster.sol +151 -0
- package/contracts/prebuilts/account/token-paymaster/TokenPaymaster.sol +212 -0
- package/contracts/prebuilts/account/utils/AccountCore.sol +245 -0
- package/contracts/prebuilts/account/utils/AccountCoreStorage.sol +21 -0
- package/contracts/prebuilts/account/utils/AccountExtension.sol +172 -0
- package/contracts/prebuilts/account/utils/AccountSeaportBulkSigSupport.sol +40 -0
- package/contracts/prebuilts/account/utils/BaseAccount.sol +106 -0
- package/contracts/prebuilts/account/utils/BaseAccountFactory.sol +168 -0
- package/contracts/prebuilts/account/utils/EntryPoint.sol +725 -0
- package/contracts/prebuilts/account/utils/Exec.sol +56 -0
- package/contracts/prebuilts/account/utils/Helpers.sol +88 -0
- package/contracts/prebuilts/account/utils/NonceManager.sol +39 -0
- package/contracts/prebuilts/account/utils/OracleHelper.sol +154 -0
- package/contracts/prebuilts/account/utils/SenderCreator.sol +28 -0
- package/contracts/prebuilts/account/utils/StakeManager.sol +126 -0
- package/contracts/prebuilts/account/utils/TokenCallbackHandler.sol +55 -0
- package/contracts/prebuilts/account/utils/UniswapHelper.sol +119 -0
- package/contracts/prebuilts/account/utils/UserOperationLib.sol +127 -0
- package/contracts/prebuilts/airdrop/Airdrop.sol +616 -0
- package/contracts/prebuilts/drop/DropERC1155.sol +388 -0
- package/contracts/prebuilts/drop/DropERC20.sol +262 -0
- package/contracts/prebuilts/drop/DropERC721.sol +397 -0
- package/contracts/prebuilts/evolving-nfts/EvolvingNFT.sol +101 -0
- package/contracts/prebuilts/evolving-nfts/EvolvingNFTLogic.sol +251 -0
- package/contracts/prebuilts/evolving-nfts/extension/RulesEngineExtension.sol +26 -0
- package/contracts/prebuilts/interface/ILoyaltyCard.sol +27 -0
- package/contracts/prebuilts/interface/ILoyaltyPoints.sol +24 -0
- package/contracts/prebuilts/interface/IMultiwrap.sol +49 -0
- package/contracts/prebuilts/interface/IPack.sol +69 -0
- package/contracts/prebuilts/interface/IPackVRFDirect.sol +85 -0
- package/contracts/prebuilts/interface/airdrop/IAirdropERC1155.sol +45 -0
- package/contracts/prebuilts/interface/airdrop/IAirdropERC1155Claimable.sol +40 -0
- package/contracts/prebuilts/interface/airdrop/IAirdropERC20.sol +46 -0
- package/contracts/prebuilts/interface/airdrop/IAirdropERC20Claimable.sol +33 -0
- package/contracts/prebuilts/interface/airdrop/IAirdropERC721.sol +42 -0
- package/contracts/prebuilts/interface/airdrop/IAirdropERC721Claimable.sol +33 -0
- package/contracts/prebuilts/interface/drop/IDropClaimCondition.sol +82 -0
- package/contracts/prebuilts/interface/drop/IDropERC1155.sol +92 -0
- package/contracts/prebuilts/interface/drop/IDropERC20.sol +68 -0
- package/contracts/prebuilts/interface/drop/IDropERC721.sol +94 -0
- package/contracts/prebuilts/interface/marketplace/IMarketplace.sol +329 -0
- package/contracts/prebuilts/interface/staking/IEditionStake.sol +45 -0
- package/contracts/prebuilts/interface/staking/INFTStake.sol +45 -0
- package/contracts/prebuilts/interface/staking/ITokenStake.sol +46 -0
- package/contracts/prebuilts/interface/token/ITokenERC1155.sol +84 -0
- package/contracts/prebuilts/interface/token/ITokenERC20.sol +68 -0
- package/contracts/prebuilts/interface/token/ITokenERC721.sol +77 -0
- package/contracts/prebuilts/loyalty/LoyaltyCard.sol +339 -0
- package/contracts/prebuilts/marketplace/IMarketplace.sol +512 -0
- package/contracts/prebuilts/marketplace/direct-listings/DirectListingsLogic.sol +579 -0
- package/contracts/prebuilts/marketplace/direct-listings/DirectListingsStorage.sol +30 -0
- package/contracts/prebuilts/marketplace/english-auctions/EnglishAuctionsLogic.sol +546 -0
- package/contracts/prebuilts/marketplace/english-auctions/EnglishAuctionsStorage.sol +30 -0
- package/contracts/prebuilts/marketplace/entrypoint/MarketplaceV3.sol +184 -0
- package/contracts/prebuilts/marketplace/offers/OffersLogic.sol +358 -0
- package/contracts/prebuilts/marketplace/offers/OffersStorage.sol +28 -0
- package/contracts/prebuilts/marketplace-legacy/Marketplace.sol +907 -0
- package/contracts/prebuilts/multiwrap/Multiwrap.sol +264 -0
- package/contracts/prebuilts/open-edition/OpenEditionERC721.sol +268 -0
- package/contracts/prebuilts/open-edition/OpenEditionERC721FlatFee.sol +298 -0
- package/contracts/prebuilts/pack/Pack.sol +463 -0
- package/contracts/prebuilts/pack/PackVRFDirect.sol +516 -0
- package/contracts/prebuilts/signature-drop/SignatureDrop.sol +371 -0
- package/contracts/prebuilts/split/Split.sol +182 -0
- package/contracts/prebuilts/staking/EditionStake.sol +211 -0
- package/contracts/prebuilts/staking/NFTStake.sol +201 -0
- package/contracts/prebuilts/staking/TokenStake.sol +197 -0
- package/contracts/prebuilts/tiered-drop/TieredDrop.sol +607 -0
- package/contracts/prebuilts/token/TokenERC1155.sol +576 -0
- package/contracts/prebuilts/token/TokenERC20.sol +312 -0
- package/contracts/prebuilts/token/TokenERC721.sol +469 -0
- package/contracts/prebuilts/unaudited/airdrop/AirdropERC1155.sol +154 -0
- package/contracts/prebuilts/unaudited/airdrop/AirdropERC1155Claimable.sol +199 -0
- package/contracts/prebuilts/unaudited/airdrop/AirdropERC20.sol +194 -0
- package/contracts/prebuilts/unaudited/airdrop/AirdropERC20Claimable.sol +180 -0
- package/contracts/prebuilts/unaudited/airdrop/AirdropERC721.sol +143 -0
- package/contracts/prebuilts/unaudited/airdrop/AirdropERC721Claimable.sol +197 -0
- package/contracts/prebuilts/unaudited/burn-to-claim-drop/BurnToClaimDropERC721.sol +137 -0
- package/contracts/prebuilts/unaudited/burn-to-claim-drop/extension/BurnToClaimDrop721Logic.sol +362 -0
- package/contracts/prebuilts/unaudited/burn-to-claim-drop/extension/BurnToClaimDrop721Storage.sol +21 -0
- package/contracts/prebuilts/unaudited/contract-builder/CoreRouter.sol +60 -0
- package/contracts/prebuilts/unaudited/contract-builder/extension/PermissionOverride.sol +52 -0
- package/contracts/prebuilts/unaudited/loyalty/LoyaltyPoints.sol +249 -0
- package/contracts/prebuilts/vote/VoteERC20.sol +167 -0
- package/js/DropERC1155.d.ts +1198 -0
- package/js/DropERC1155.js +2 -0
- package/js/DropERC1155.js.map +1 -0
- package/js/DropERC721.d.ts +1247 -0
- package/js/DropERC721.js +2 -0
- package/js/DropERC721.js.map +1 -0
- package/js/OpenEditionERC721FlatFee.d.ts +1207 -0
- package/js/OpenEditionERC721FlatFee.js +2 -0
- package/js/OpenEditionERC721FlatFee.js.map +1 -0
- package/js/common.d.ts +22 -0
- package/js/common.js +2 -0
- package/js/common.js.map +1 -0
- package/js/factories/DropERC1155__factory.d.ts +1751 -0
- package/js/factories/DropERC1155__factory.js +2279 -0
- package/js/factories/DropERC1155__factory.js.map +1 -0
- package/js/factories/DropERC721__factory.d.ts +1826 -0
- package/js/factories/DropERC721__factory.js +2380 -0
- package/js/factories/DropERC721__factory.js.map +1 -0
- package/js/factories/OpenEditionERC721FlatFee__factory.d.ts +1707 -0
- package/js/factories/OpenEditionERC721FlatFee__factory.js +2219 -0
- package/js/factories/OpenEditionERC721FlatFee__factory.js.map +1 -0
- package/js/factories/index.d.ts +1 -0
- package/js/factories/index.js +5 -0
- package/js/factories/index.js.map +1 -0
- package/js/index.d.ts +3 -0
- package/js/index.js +3 -0
- package/js/index.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,907 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
pragma solidity ^0.8.11;
|
|
3
|
+
|
|
4
|
+
/// @author thirdweb
|
|
5
|
+
|
|
6
|
+
// $$\ $$\ $$\ $$\ $$\
|
|
7
|
+
// $$ | $$ | \__| $$ | $$ |
|
|
8
|
+
// $$$$$$\ $$$$$$$\ $$\ $$$$$$\ $$$$$$$ |$$\ $$\ $$\ $$$$$$\ $$$$$$$\
|
|
9
|
+
// \_$$ _| $$ __$$\ $$ |$$ __$$\ $$ __$$ |$$ | $$ | $$ |$$ __$$\ $$ __$$\
|
|
10
|
+
// $$ | $$ | $$ |$$ |$$ | \__|$$ / $$ |$$ | $$ | $$ |$$$$$$$$ |$$ | $$ |
|
|
11
|
+
// $$ |$$\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ |
|
|
12
|
+
// \$$$$ |$$ | $$ |$$ |$$ | \$$$$$$$ |\$$$$$\$$$$ |\$$$$$$$\ $$$$$$$ |
|
|
13
|
+
// \____/ \__| \__|\__|\__| \_______| \_____\____/ \_______|\_______/
|
|
14
|
+
|
|
15
|
+
// ========== External imports ==========
|
|
16
|
+
|
|
17
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
|
|
18
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
|
|
19
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
|
|
20
|
+
|
|
21
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol";
|
|
22
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol";
|
|
23
|
+
|
|
24
|
+
import "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol";
|
|
25
|
+
import "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol";
|
|
26
|
+
|
|
27
|
+
import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol";
|
|
28
|
+
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
|
|
29
|
+
|
|
30
|
+
// ========== Internal imports ==========
|
|
31
|
+
|
|
32
|
+
import { IMarketplace } from "../interface/marketplace/IMarketplace.sol";
|
|
33
|
+
|
|
34
|
+
import "../../external-deps/openzeppelin/metatx/ERC2771ContextUpgradeable.sol";
|
|
35
|
+
|
|
36
|
+
import "../../extension/Multicall.sol";
|
|
37
|
+
import "../../lib/CurrencyTransferLib.sol";
|
|
38
|
+
import "../../lib/FeeType.sol";
|
|
39
|
+
|
|
40
|
+
contract Marketplace is
|
|
41
|
+
Initializable,
|
|
42
|
+
IMarketplace,
|
|
43
|
+
ReentrancyGuardUpgradeable,
|
|
44
|
+
ERC2771ContextUpgradeable,
|
|
45
|
+
Multicall,
|
|
46
|
+
AccessControlEnumerableUpgradeable,
|
|
47
|
+
IERC721ReceiverUpgradeable,
|
|
48
|
+
IERC1155ReceiverUpgradeable
|
|
49
|
+
{
|
|
50
|
+
/*///////////////////////////////////////////////////////////////
|
|
51
|
+
State variables
|
|
52
|
+
//////////////////////////////////////////////////////////////*/
|
|
53
|
+
|
|
54
|
+
bytes32 private constant MODULE_TYPE = bytes32("Marketplace");
|
|
55
|
+
uint256 private constant VERSION = 2;
|
|
56
|
+
|
|
57
|
+
/// @dev Only lister role holders can create listings, when listings are restricted by lister address.
|
|
58
|
+
bytes32 private constant LISTER_ROLE = keccak256("LISTER_ROLE");
|
|
59
|
+
/// @dev Only assets from NFT contracts with asset role can be listed, when listings are restricted by asset address.
|
|
60
|
+
bytes32 private constant ASSET_ROLE = keccak256("ASSET_ROLE");
|
|
61
|
+
|
|
62
|
+
/// @dev The address of the native token wrapper contract.
|
|
63
|
+
address private immutable nativeTokenWrapper;
|
|
64
|
+
|
|
65
|
+
/// @dev Total number of listings ever created in the marketplace.
|
|
66
|
+
uint256 public totalListings;
|
|
67
|
+
|
|
68
|
+
/// @dev Contract level metadata.
|
|
69
|
+
string public contractURI;
|
|
70
|
+
|
|
71
|
+
/// @dev The address that receives all platform fees from all sales.
|
|
72
|
+
address private platformFeeRecipient;
|
|
73
|
+
|
|
74
|
+
/// @dev The max bps of the contract. So, 10_000 == 100 %
|
|
75
|
+
uint64 public constant MAX_BPS = 10_000;
|
|
76
|
+
|
|
77
|
+
/// @dev The % of primary sales collected as platform fees.
|
|
78
|
+
uint64 private platformFeeBps;
|
|
79
|
+
|
|
80
|
+
/// @dev
|
|
81
|
+
/**
|
|
82
|
+
* @dev The amount of time added to an auction's 'endTime', if a bid is made within `timeBuffer`
|
|
83
|
+
* seconds of the existing `endTime`. Default: 15 minutes.
|
|
84
|
+
*/
|
|
85
|
+
uint64 public timeBuffer;
|
|
86
|
+
|
|
87
|
+
/// @dev The minimum % increase required from the previous winning bid. Default: 5%.
|
|
88
|
+
uint64 public bidBufferBps;
|
|
89
|
+
|
|
90
|
+
/*///////////////////////////////////////////////////////////////
|
|
91
|
+
Mappings
|
|
92
|
+
//////////////////////////////////////////////////////////////*/
|
|
93
|
+
|
|
94
|
+
/// @dev Mapping from uid of listing => listing info.
|
|
95
|
+
mapping(uint256 => Listing) public listings;
|
|
96
|
+
|
|
97
|
+
/// @dev Mapping from uid of a direct listing => offeror address => offer made to the direct listing by the respective offeror.
|
|
98
|
+
mapping(uint256 => mapping(address => Offer)) public offers;
|
|
99
|
+
|
|
100
|
+
/// @dev Mapping from uid of an auction listing => current winning bid in an auction.
|
|
101
|
+
mapping(uint256 => Offer) public winningBid;
|
|
102
|
+
|
|
103
|
+
/*///////////////////////////////////////////////////////////////
|
|
104
|
+
Modifiers
|
|
105
|
+
//////////////////////////////////////////////////////////////*/
|
|
106
|
+
|
|
107
|
+
/// @dev Checks whether caller is a listing creator.
|
|
108
|
+
modifier onlyListingCreator(uint256 _listingId) {
|
|
109
|
+
require(listings[_listingId].tokenOwner == _msgSender(), "!OWNER");
|
|
110
|
+
_;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// @dev Checks whether a listing exists.
|
|
114
|
+
modifier onlyExistingListing(uint256 _listingId) {
|
|
115
|
+
require(listings[_listingId].assetContract != address(0), "DNE");
|
|
116
|
+
_;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/*///////////////////////////////////////////////////////////////
|
|
120
|
+
Constructor + initializer logic
|
|
121
|
+
//////////////////////////////////////////////////////////////*/
|
|
122
|
+
|
|
123
|
+
constructor(address _nativeTokenWrapper) initializer {
|
|
124
|
+
nativeTokenWrapper = _nativeTokenWrapper;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// @dev Initializes the contract, like a constructor.
|
|
128
|
+
function initialize(
|
|
129
|
+
address _defaultAdmin,
|
|
130
|
+
string memory _contractURI,
|
|
131
|
+
address[] memory _trustedForwarders,
|
|
132
|
+
address _platformFeeRecipient,
|
|
133
|
+
uint256 _platformFeeBps
|
|
134
|
+
) external initializer {
|
|
135
|
+
// Initialize inherited contracts, most base-like -> most derived.
|
|
136
|
+
__ReentrancyGuard_init();
|
|
137
|
+
__ERC2771Context_init(_trustedForwarders);
|
|
138
|
+
|
|
139
|
+
// Initialize this contract's state.
|
|
140
|
+
timeBuffer = 15 minutes;
|
|
141
|
+
bidBufferBps = 500;
|
|
142
|
+
|
|
143
|
+
contractURI = _contractURI;
|
|
144
|
+
platformFeeBps = uint64(_platformFeeBps);
|
|
145
|
+
platformFeeRecipient = _platformFeeRecipient;
|
|
146
|
+
|
|
147
|
+
_setupRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);
|
|
148
|
+
_setupRole(LISTER_ROLE, address(0));
|
|
149
|
+
_setupRole(ASSET_ROLE, address(0));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/*///////////////////////////////////////////////////////////////
|
|
153
|
+
Generic contract logic
|
|
154
|
+
//////////////////////////////////////////////////////////////*/
|
|
155
|
+
|
|
156
|
+
/// @dev Lets the contract receives native tokens from `nativeTokenWrapper` withdraw.
|
|
157
|
+
receive() external payable {}
|
|
158
|
+
|
|
159
|
+
/// @dev Returns the type of the contract.
|
|
160
|
+
function contractType() external pure returns (bytes32) {
|
|
161
|
+
return MODULE_TYPE;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/// @dev Returns the version of the contract.
|
|
165
|
+
function contractVersion() external pure returns (uint8) {
|
|
166
|
+
return uint8(VERSION);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/*///////////////////////////////////////////////////////////////
|
|
170
|
+
ERC 165 / 721 / 1155 logic
|
|
171
|
+
//////////////////////////////////////////////////////////////*/
|
|
172
|
+
|
|
173
|
+
function onERC1155Received(
|
|
174
|
+
address,
|
|
175
|
+
address,
|
|
176
|
+
uint256,
|
|
177
|
+
uint256,
|
|
178
|
+
bytes memory
|
|
179
|
+
) public virtual override returns (bytes4) {
|
|
180
|
+
return this.onERC1155Received.selector;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function onERC1155BatchReceived(
|
|
184
|
+
address,
|
|
185
|
+
address,
|
|
186
|
+
uint256[] memory,
|
|
187
|
+
uint256[] memory,
|
|
188
|
+
bytes memory
|
|
189
|
+
) public virtual override returns (bytes4) {
|
|
190
|
+
return this.onERC1155BatchReceived.selector;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function onERC721Received(address, address, uint256, bytes calldata) external pure override returns (bytes4) {
|
|
194
|
+
return this.onERC721Received.selector;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function supportsInterface(
|
|
198
|
+
bytes4 interfaceId
|
|
199
|
+
) public view virtual override(AccessControlEnumerableUpgradeable, IERC165Upgradeable) returns (bool) {
|
|
200
|
+
return
|
|
201
|
+
interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId ||
|
|
202
|
+
interfaceId == type(IERC721ReceiverUpgradeable).interfaceId ||
|
|
203
|
+
super.supportsInterface(interfaceId);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/*///////////////////////////////////////////////////////////////
|
|
207
|
+
Listing (create-update-delete) logic
|
|
208
|
+
//////////////////////////////////////////////////////////////*/
|
|
209
|
+
|
|
210
|
+
/// @dev Lets a token owner list tokens for sale: Direct Listing or Auction.
|
|
211
|
+
function createListing(ListingParameters memory _params) external override {
|
|
212
|
+
// Get values to populate `Listing`.
|
|
213
|
+
uint256 listingId = totalListings;
|
|
214
|
+
totalListings += 1;
|
|
215
|
+
|
|
216
|
+
address tokenOwner = _msgSender();
|
|
217
|
+
TokenType tokenTypeOfListing = getTokenType(_params.assetContract);
|
|
218
|
+
uint256 tokenAmountToList = getSafeQuantity(tokenTypeOfListing, _params.quantityToList);
|
|
219
|
+
|
|
220
|
+
require(tokenAmountToList > 0, "QUANTITY");
|
|
221
|
+
require(hasRole(LISTER_ROLE, address(0)) || hasRole(LISTER_ROLE, _msgSender()), "!LISTER");
|
|
222
|
+
require(hasRole(ASSET_ROLE, address(0)) || hasRole(ASSET_ROLE, _params.assetContract), "!ASSET");
|
|
223
|
+
|
|
224
|
+
uint256 startTime = _params.startTime;
|
|
225
|
+
if (startTime < block.timestamp) {
|
|
226
|
+
// do not allow listing to start in the past (1 hour buffer)
|
|
227
|
+
require(block.timestamp - startTime < 1 hours, "ST");
|
|
228
|
+
startTime = block.timestamp;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
validateOwnershipAndApproval(
|
|
232
|
+
tokenOwner,
|
|
233
|
+
_params.assetContract,
|
|
234
|
+
_params.tokenId,
|
|
235
|
+
tokenAmountToList,
|
|
236
|
+
tokenTypeOfListing
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
Listing memory newListing = Listing({
|
|
240
|
+
listingId: listingId,
|
|
241
|
+
tokenOwner: tokenOwner,
|
|
242
|
+
assetContract: _params.assetContract,
|
|
243
|
+
tokenId: _params.tokenId,
|
|
244
|
+
startTime: startTime,
|
|
245
|
+
endTime: startTime + _params.secondsUntilEndTime,
|
|
246
|
+
quantity: tokenAmountToList,
|
|
247
|
+
currency: _params.currencyToAccept,
|
|
248
|
+
reservePricePerToken: _params.reservePricePerToken,
|
|
249
|
+
buyoutPricePerToken: _params.buyoutPricePerToken,
|
|
250
|
+
tokenType: tokenTypeOfListing,
|
|
251
|
+
listingType: _params.listingType
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
listings[listingId] = newListing;
|
|
255
|
+
|
|
256
|
+
// Tokens listed for sale in an auction are escrowed in Marketplace.
|
|
257
|
+
if (newListing.listingType == ListingType.Auction) {
|
|
258
|
+
require(
|
|
259
|
+
newListing.buyoutPricePerToken == 0 ||
|
|
260
|
+
newListing.buyoutPricePerToken >= newListing.reservePricePerToken,
|
|
261
|
+
"RESERVE"
|
|
262
|
+
);
|
|
263
|
+
transferListingTokens(tokenOwner, address(this), tokenAmountToList, newListing);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
emit ListingAdded(listingId, _params.assetContract, tokenOwner, newListing);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/// @dev Lets a listing's creator edit the listing's parameters.
|
|
270
|
+
function updateListing(
|
|
271
|
+
uint256 _listingId,
|
|
272
|
+
uint256 _quantityToList,
|
|
273
|
+
uint256 _reservePricePerToken,
|
|
274
|
+
uint256 _buyoutPricePerToken,
|
|
275
|
+
address _currencyToAccept,
|
|
276
|
+
uint256 _startTime,
|
|
277
|
+
uint256 _secondsUntilEndTime
|
|
278
|
+
) external override onlyListingCreator(_listingId) {
|
|
279
|
+
Listing memory targetListing = listings[_listingId];
|
|
280
|
+
uint256 safeNewQuantity = getSafeQuantity(targetListing.tokenType, _quantityToList);
|
|
281
|
+
bool isAuction = targetListing.listingType == ListingType.Auction;
|
|
282
|
+
|
|
283
|
+
require(safeNewQuantity != 0, "QUANTITY");
|
|
284
|
+
|
|
285
|
+
// Can only edit auction listing before it starts.
|
|
286
|
+
if (isAuction) {
|
|
287
|
+
require(block.timestamp < targetListing.startTime, "STARTED");
|
|
288
|
+
require(_buyoutPricePerToken == 0 || _buyoutPricePerToken >= _reservePricePerToken, "RESERVE");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (_startTime < block.timestamp) {
|
|
292
|
+
// do not allow listing to start in the past (1 hour buffer)
|
|
293
|
+
require(block.timestamp - _startTime < 1 hours, "ST");
|
|
294
|
+
_startTime = block.timestamp;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
uint256 newStartTime = _startTime == 0 ? targetListing.startTime : _startTime;
|
|
298
|
+
listings[_listingId] = Listing({
|
|
299
|
+
listingId: _listingId,
|
|
300
|
+
tokenOwner: _msgSender(),
|
|
301
|
+
assetContract: targetListing.assetContract,
|
|
302
|
+
tokenId: targetListing.tokenId,
|
|
303
|
+
startTime: newStartTime,
|
|
304
|
+
endTime: _secondsUntilEndTime == 0 ? targetListing.endTime : newStartTime + _secondsUntilEndTime,
|
|
305
|
+
quantity: safeNewQuantity,
|
|
306
|
+
currency: _currencyToAccept,
|
|
307
|
+
reservePricePerToken: _reservePricePerToken,
|
|
308
|
+
buyoutPricePerToken: _buyoutPricePerToken,
|
|
309
|
+
tokenType: targetListing.tokenType,
|
|
310
|
+
listingType: targetListing.listingType
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// Must validate ownership and approval of the new quantity of tokens for direct listing.
|
|
314
|
+
if (targetListing.quantity != safeNewQuantity) {
|
|
315
|
+
// Transfer all escrowed tokens back to the lister, to be reflected in the lister's
|
|
316
|
+
// balance for the upcoming ownership and approval check.
|
|
317
|
+
if (isAuction) {
|
|
318
|
+
transferListingTokens(address(this), targetListing.tokenOwner, targetListing.quantity, targetListing);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
validateOwnershipAndApproval(
|
|
322
|
+
targetListing.tokenOwner,
|
|
323
|
+
targetListing.assetContract,
|
|
324
|
+
targetListing.tokenId,
|
|
325
|
+
safeNewQuantity,
|
|
326
|
+
targetListing.tokenType
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
// Escrow the new quantity of tokens to list in the auction.
|
|
330
|
+
if (isAuction) {
|
|
331
|
+
transferListingTokens(targetListing.tokenOwner, address(this), safeNewQuantity, targetListing);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
emit ListingUpdated(_listingId, targetListing.tokenOwner);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/// @dev Lets a direct listing creator cancel their listing.
|
|
339
|
+
function cancelDirectListing(uint256 _listingId) external onlyListingCreator(_listingId) {
|
|
340
|
+
Listing memory targetListing = listings[_listingId];
|
|
341
|
+
|
|
342
|
+
require(targetListing.listingType == ListingType.Direct, "!DIRECT");
|
|
343
|
+
|
|
344
|
+
delete listings[_listingId];
|
|
345
|
+
|
|
346
|
+
emit ListingRemoved(_listingId, targetListing.tokenOwner);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/*///////////////////////////////////////////////////////////////
|
|
350
|
+
Direct lisitngs sales logic
|
|
351
|
+
//////////////////////////////////////////////////////////////*/
|
|
352
|
+
|
|
353
|
+
/// @dev Lets an account buy a given quantity of tokens from a listing.
|
|
354
|
+
function buy(
|
|
355
|
+
uint256 _listingId,
|
|
356
|
+
address _buyFor,
|
|
357
|
+
uint256 _quantityToBuy,
|
|
358
|
+
address _currency,
|
|
359
|
+
uint256 _totalPrice
|
|
360
|
+
) external payable override nonReentrant onlyExistingListing(_listingId) {
|
|
361
|
+
Listing memory targetListing = listings[_listingId];
|
|
362
|
+
address payer = _msgSender();
|
|
363
|
+
|
|
364
|
+
// Check whether the settled total price and currency to use are correct.
|
|
365
|
+
require(
|
|
366
|
+
_currency == targetListing.currency && _totalPrice == (targetListing.buyoutPricePerToken * _quantityToBuy),
|
|
367
|
+
"!PRICE"
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
executeSale(
|
|
371
|
+
targetListing,
|
|
372
|
+
payer,
|
|
373
|
+
_buyFor,
|
|
374
|
+
targetListing.currency,
|
|
375
|
+
targetListing.buyoutPricePerToken * _quantityToBuy,
|
|
376
|
+
_quantityToBuy
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/// @dev Lets a listing's creator accept an offer for their direct listing.
|
|
381
|
+
function acceptOffer(
|
|
382
|
+
uint256 _listingId,
|
|
383
|
+
address _offeror,
|
|
384
|
+
address _currency,
|
|
385
|
+
uint256 _pricePerToken
|
|
386
|
+
) external override nonReentrant onlyListingCreator(_listingId) onlyExistingListing(_listingId) {
|
|
387
|
+
Offer memory targetOffer = offers[_listingId][_offeror];
|
|
388
|
+
Listing memory targetListing = listings[_listingId];
|
|
389
|
+
|
|
390
|
+
require(_currency == targetOffer.currency && _pricePerToken == targetOffer.pricePerToken, "!PRICE");
|
|
391
|
+
require(targetOffer.expirationTimestamp > block.timestamp, "EXPIRED");
|
|
392
|
+
|
|
393
|
+
delete offers[_listingId][_offeror];
|
|
394
|
+
|
|
395
|
+
executeSale(
|
|
396
|
+
targetListing,
|
|
397
|
+
_offeror,
|
|
398
|
+
_offeror,
|
|
399
|
+
targetOffer.currency,
|
|
400
|
+
targetOffer.pricePerToken * targetOffer.quantityWanted,
|
|
401
|
+
targetOffer.quantityWanted
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/// @dev Performs a direct listing sale.
|
|
406
|
+
function executeSale(
|
|
407
|
+
Listing memory _targetListing,
|
|
408
|
+
address _payer,
|
|
409
|
+
address _receiver,
|
|
410
|
+
address _currency,
|
|
411
|
+
uint256 _currencyAmountToTransfer,
|
|
412
|
+
uint256 _listingTokenAmountToTransfer
|
|
413
|
+
) internal {
|
|
414
|
+
validateDirectListingSale(
|
|
415
|
+
_targetListing,
|
|
416
|
+
_payer,
|
|
417
|
+
_listingTokenAmountToTransfer,
|
|
418
|
+
_currency,
|
|
419
|
+
_currencyAmountToTransfer
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
_targetListing.quantity -= _listingTokenAmountToTransfer;
|
|
423
|
+
listings[_targetListing.listingId] = _targetListing;
|
|
424
|
+
|
|
425
|
+
payout(_payer, _targetListing.tokenOwner, _currency, _currencyAmountToTransfer, _targetListing);
|
|
426
|
+
transferListingTokens(_targetListing.tokenOwner, _receiver, _listingTokenAmountToTransfer, _targetListing);
|
|
427
|
+
|
|
428
|
+
emit NewSale(
|
|
429
|
+
_targetListing.listingId,
|
|
430
|
+
_targetListing.assetContract,
|
|
431
|
+
_targetListing.tokenOwner,
|
|
432
|
+
_receiver,
|
|
433
|
+
_listingTokenAmountToTransfer,
|
|
434
|
+
_currencyAmountToTransfer
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/*///////////////////////////////////////////////////////////////
|
|
439
|
+
Offer/bid logic
|
|
440
|
+
//////////////////////////////////////////////////////////////*/
|
|
441
|
+
|
|
442
|
+
/// @dev Lets an account (1) make an offer to a direct listing, or (2) make a bid in an auction.
|
|
443
|
+
function offer(
|
|
444
|
+
uint256 _listingId,
|
|
445
|
+
uint256 _quantityWanted,
|
|
446
|
+
address _currency,
|
|
447
|
+
uint256 _pricePerToken,
|
|
448
|
+
uint256 _expirationTimestamp
|
|
449
|
+
) external payable override nonReentrant onlyExistingListing(_listingId) {
|
|
450
|
+
Listing memory targetListing = listings[_listingId];
|
|
451
|
+
|
|
452
|
+
require(
|
|
453
|
+
targetListing.endTime > block.timestamp && targetListing.startTime < block.timestamp,
|
|
454
|
+
"inactive listing."
|
|
455
|
+
);
|
|
456
|
+
|
|
457
|
+
// Both - (1) offers to direct listings, and (2) bids to auctions - share the same structure.
|
|
458
|
+
Offer memory newOffer = Offer({
|
|
459
|
+
listingId: _listingId,
|
|
460
|
+
offeror: _msgSender(),
|
|
461
|
+
quantityWanted: _quantityWanted,
|
|
462
|
+
currency: _currency,
|
|
463
|
+
pricePerToken: _pricePerToken,
|
|
464
|
+
expirationTimestamp: _expirationTimestamp
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
if (targetListing.listingType == ListingType.Auction) {
|
|
468
|
+
// A bid to an auction must be made in the auction's desired currency.
|
|
469
|
+
require(newOffer.currency == targetListing.currency, "must use approved currency to bid");
|
|
470
|
+
require(newOffer.pricePerToken != 0, "bidding zero amount");
|
|
471
|
+
|
|
472
|
+
// A bid must be made for all auction items.
|
|
473
|
+
newOffer.quantityWanted = getSafeQuantity(targetListing.tokenType, targetListing.quantity);
|
|
474
|
+
|
|
475
|
+
handleBid(targetListing, newOffer);
|
|
476
|
+
} else if (targetListing.listingType == ListingType.Direct) {
|
|
477
|
+
// Prevent potentially lost/locked native token.
|
|
478
|
+
require(msg.value == 0, "no value needed");
|
|
479
|
+
|
|
480
|
+
// Offers to direct listings cannot be made directly in native tokens.
|
|
481
|
+
newOffer.currency = _currency == CurrencyTransferLib.NATIVE_TOKEN ? nativeTokenWrapper : _currency;
|
|
482
|
+
newOffer.quantityWanted = getSafeQuantity(targetListing.tokenType, _quantityWanted);
|
|
483
|
+
|
|
484
|
+
handleOffer(targetListing, newOffer);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/// @dev Processes a new offer to a direct listing.
|
|
489
|
+
function handleOffer(Listing memory _targetListing, Offer memory _newOffer) internal {
|
|
490
|
+
require(
|
|
491
|
+
_newOffer.quantityWanted <= _targetListing.quantity && _targetListing.quantity > 0,
|
|
492
|
+
"insufficient tokens in listing."
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
validateERC20BalAndAllowance(
|
|
496
|
+
_newOffer.offeror,
|
|
497
|
+
_newOffer.currency,
|
|
498
|
+
_newOffer.pricePerToken * _newOffer.quantityWanted
|
|
499
|
+
);
|
|
500
|
+
|
|
501
|
+
offers[_targetListing.listingId][_newOffer.offeror] = _newOffer;
|
|
502
|
+
|
|
503
|
+
emit NewOffer(
|
|
504
|
+
_targetListing.listingId,
|
|
505
|
+
_newOffer.offeror,
|
|
506
|
+
_targetListing.listingType,
|
|
507
|
+
_newOffer.quantityWanted,
|
|
508
|
+
_newOffer.pricePerToken * _newOffer.quantityWanted,
|
|
509
|
+
_newOffer.currency
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/// @dev Processes an incoming bid in an auction.
|
|
514
|
+
function handleBid(Listing memory _targetListing, Offer memory _incomingBid) internal {
|
|
515
|
+
Offer memory currentWinningBid = winningBid[_targetListing.listingId];
|
|
516
|
+
uint256 currentOfferAmount = currentWinningBid.pricePerToken * currentWinningBid.quantityWanted;
|
|
517
|
+
uint256 incomingOfferAmount = _incomingBid.pricePerToken * _incomingBid.quantityWanted;
|
|
518
|
+
address _nativeTokenWrapper = nativeTokenWrapper;
|
|
519
|
+
|
|
520
|
+
// Close auction and execute sale if there's a buyout price and incoming offer amount is buyout price.
|
|
521
|
+
if (
|
|
522
|
+
_targetListing.buyoutPricePerToken > 0 &&
|
|
523
|
+
incomingOfferAmount >= _targetListing.buyoutPricePerToken * _targetListing.quantity
|
|
524
|
+
) {
|
|
525
|
+
_closeAuctionForBidder(_targetListing, _incomingBid);
|
|
526
|
+
} else {
|
|
527
|
+
/**
|
|
528
|
+
* If there's an existng winning bid, incoming bid amount must be bid buffer % greater.
|
|
529
|
+
* Else, bid amount must be at least as great as reserve price
|
|
530
|
+
*/
|
|
531
|
+
require(
|
|
532
|
+
isNewWinningBid(
|
|
533
|
+
_targetListing.reservePricePerToken * _targetListing.quantity,
|
|
534
|
+
currentOfferAmount,
|
|
535
|
+
incomingOfferAmount
|
|
536
|
+
),
|
|
537
|
+
"not winning bid."
|
|
538
|
+
);
|
|
539
|
+
|
|
540
|
+
// Update the winning bid and listing's end time before external contract calls.
|
|
541
|
+
winningBid[_targetListing.listingId] = _incomingBid;
|
|
542
|
+
|
|
543
|
+
if (_targetListing.endTime - block.timestamp <= timeBuffer) {
|
|
544
|
+
_targetListing.endTime += timeBuffer;
|
|
545
|
+
listings[_targetListing.listingId] = _targetListing;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Payout previous highest bid.
|
|
550
|
+
if (currentWinningBid.offeror != address(0) && currentOfferAmount > 0) {
|
|
551
|
+
CurrencyTransferLib.transferCurrencyWithWrapper(
|
|
552
|
+
_targetListing.currency,
|
|
553
|
+
address(this),
|
|
554
|
+
currentWinningBid.offeror,
|
|
555
|
+
currentOfferAmount,
|
|
556
|
+
_nativeTokenWrapper
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Collect incoming bid
|
|
561
|
+
CurrencyTransferLib.transferCurrencyWithWrapper(
|
|
562
|
+
_targetListing.currency,
|
|
563
|
+
_incomingBid.offeror,
|
|
564
|
+
address(this),
|
|
565
|
+
incomingOfferAmount,
|
|
566
|
+
_nativeTokenWrapper
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
emit NewOffer(
|
|
570
|
+
_targetListing.listingId,
|
|
571
|
+
_incomingBid.offeror,
|
|
572
|
+
_targetListing.listingType,
|
|
573
|
+
_incomingBid.quantityWanted,
|
|
574
|
+
_incomingBid.pricePerToken * _incomingBid.quantityWanted,
|
|
575
|
+
_incomingBid.currency
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/// @dev Checks whether an incoming bid is the new current highest bid.
|
|
580
|
+
function isNewWinningBid(
|
|
581
|
+
uint256 _reserveAmount,
|
|
582
|
+
uint256 _currentWinningBidAmount,
|
|
583
|
+
uint256 _incomingBidAmount
|
|
584
|
+
) internal view returns (bool isValidNewBid) {
|
|
585
|
+
if (_currentWinningBidAmount == 0) {
|
|
586
|
+
isValidNewBid = _incomingBidAmount >= _reserveAmount;
|
|
587
|
+
} else {
|
|
588
|
+
isValidNewBid = (_incomingBidAmount > _currentWinningBidAmount &&
|
|
589
|
+
((_incomingBidAmount - _currentWinningBidAmount) * MAX_BPS) / _currentWinningBidAmount >= bidBufferBps);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/*///////////////////////////////////////////////////////////////
|
|
594
|
+
Auction lisitngs sales logic
|
|
595
|
+
//////////////////////////////////////////////////////////////*/
|
|
596
|
+
|
|
597
|
+
/// @dev Lets an account close an auction for either the (1) winning bidder, or (2) auction creator.
|
|
598
|
+
function closeAuction(
|
|
599
|
+
uint256 _listingId,
|
|
600
|
+
address _closeFor
|
|
601
|
+
) external override nonReentrant onlyExistingListing(_listingId) {
|
|
602
|
+
Listing memory targetListing = listings[_listingId];
|
|
603
|
+
|
|
604
|
+
require(targetListing.listingType == ListingType.Auction, "not an auction.");
|
|
605
|
+
|
|
606
|
+
Offer memory targetBid = winningBid[_listingId];
|
|
607
|
+
|
|
608
|
+
// Cancel auction if (1) auction hasn't started, or (2) auction doesn't have any bids.
|
|
609
|
+
bool toCancel = targetListing.startTime > block.timestamp || targetBid.offeror == address(0);
|
|
610
|
+
|
|
611
|
+
if (toCancel) {
|
|
612
|
+
// cancel auction listing owner check
|
|
613
|
+
_cancelAuction(targetListing);
|
|
614
|
+
} else {
|
|
615
|
+
require(targetListing.endTime < block.timestamp, "cannot close auction before it has ended.");
|
|
616
|
+
|
|
617
|
+
// No `else if` to let auction close in 1 tx when targetListing.tokenOwner == targetBid.offeror.
|
|
618
|
+
if (_closeFor == targetListing.tokenOwner) {
|
|
619
|
+
_closeAuctionForAuctionCreator(targetListing, targetBid);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (_closeFor == targetBid.offeror) {
|
|
623
|
+
_closeAuctionForBidder(targetListing, targetBid);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/// @dev Cancels an auction.
|
|
629
|
+
function _cancelAuction(Listing memory _targetListing) internal {
|
|
630
|
+
require(listings[_targetListing.listingId].tokenOwner == _msgSender(), "caller is not the listing creator.");
|
|
631
|
+
|
|
632
|
+
delete listings[_targetListing.listingId];
|
|
633
|
+
|
|
634
|
+
transferListingTokens(address(this), _targetListing.tokenOwner, _targetListing.quantity, _targetListing);
|
|
635
|
+
|
|
636
|
+
emit AuctionClosed(_targetListing.listingId, _msgSender(), true, _targetListing.tokenOwner, address(0));
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/// @dev Closes an auction for an auction creator; distributes winning bid amount to auction creator.
|
|
640
|
+
function _closeAuctionForAuctionCreator(Listing memory _targetListing, Offer memory _winningBid) internal {
|
|
641
|
+
uint256 payoutAmount = _winningBid.pricePerToken * _targetListing.quantity;
|
|
642
|
+
|
|
643
|
+
_targetListing.quantity = 0;
|
|
644
|
+
_targetListing.endTime = block.timestamp;
|
|
645
|
+
listings[_targetListing.listingId] = _targetListing;
|
|
646
|
+
|
|
647
|
+
_winningBid.pricePerToken = 0;
|
|
648
|
+
winningBid[_targetListing.listingId] = _winningBid;
|
|
649
|
+
|
|
650
|
+
payout(address(this), _targetListing.tokenOwner, _targetListing.currency, payoutAmount, _targetListing);
|
|
651
|
+
|
|
652
|
+
emit AuctionClosed(
|
|
653
|
+
_targetListing.listingId,
|
|
654
|
+
_msgSender(),
|
|
655
|
+
false,
|
|
656
|
+
_targetListing.tokenOwner,
|
|
657
|
+
_winningBid.offeror
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/// @dev Closes an auction for the winning bidder; distributes auction items to the winning bidder.
|
|
662
|
+
function _closeAuctionForBidder(Listing memory _targetListing, Offer memory _winningBid) internal {
|
|
663
|
+
uint256 quantityToSend = _winningBid.quantityWanted;
|
|
664
|
+
|
|
665
|
+
_targetListing.endTime = block.timestamp;
|
|
666
|
+
_winningBid.quantityWanted = 0;
|
|
667
|
+
|
|
668
|
+
winningBid[_targetListing.listingId] = _winningBid;
|
|
669
|
+
listings[_targetListing.listingId] = _targetListing;
|
|
670
|
+
|
|
671
|
+
transferListingTokens(address(this), _winningBid.offeror, quantityToSend, _targetListing);
|
|
672
|
+
|
|
673
|
+
emit AuctionClosed(
|
|
674
|
+
_targetListing.listingId,
|
|
675
|
+
_msgSender(),
|
|
676
|
+
false,
|
|
677
|
+
_targetListing.tokenOwner,
|
|
678
|
+
_winningBid.offeror
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/*///////////////////////////////////////////////////////////////
|
|
683
|
+
Shared (direct+auction listings) internal functions
|
|
684
|
+
//////////////////////////////////////////////////////////////*/
|
|
685
|
+
|
|
686
|
+
/// @dev Transfers tokens listed for sale in a direct or auction listing.
|
|
687
|
+
function transferListingTokens(address _from, address _to, uint256 _quantity, Listing memory _listing) internal {
|
|
688
|
+
if (_listing.tokenType == TokenType.ERC1155) {
|
|
689
|
+
IERC1155Upgradeable(_listing.assetContract).safeTransferFrom(_from, _to, _listing.tokenId, _quantity, "");
|
|
690
|
+
} else if (_listing.tokenType == TokenType.ERC721) {
|
|
691
|
+
IERC721Upgradeable(_listing.assetContract).safeTransferFrom(_from, _to, _listing.tokenId, "");
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/// @dev Pays out stakeholders in a sale.
|
|
696
|
+
function payout(
|
|
697
|
+
address _payer,
|
|
698
|
+
address _payee,
|
|
699
|
+
address _currencyToUse,
|
|
700
|
+
uint256 _totalPayoutAmount,
|
|
701
|
+
Listing memory _listing
|
|
702
|
+
) internal {
|
|
703
|
+
uint256 platformFeeCut = (_totalPayoutAmount * platformFeeBps) / MAX_BPS;
|
|
704
|
+
|
|
705
|
+
uint256 royaltyCut;
|
|
706
|
+
address royaltyRecipient;
|
|
707
|
+
|
|
708
|
+
// Distribute royalties. See Sushiswap's https://github.com/sushiswap/shoyu/blob/master/contracts/base/BaseExchange.sol#L296
|
|
709
|
+
try IERC2981Upgradeable(_listing.assetContract).royaltyInfo(_listing.tokenId, _totalPayoutAmount) returns (
|
|
710
|
+
address royaltyFeeRecipient,
|
|
711
|
+
uint256 royaltyFeeAmount
|
|
712
|
+
) {
|
|
713
|
+
if (royaltyFeeRecipient != address(0) && royaltyFeeAmount > 0) {
|
|
714
|
+
require(royaltyFeeAmount + platformFeeCut <= _totalPayoutAmount, "fees exceed the price");
|
|
715
|
+
royaltyRecipient = royaltyFeeRecipient;
|
|
716
|
+
royaltyCut = royaltyFeeAmount;
|
|
717
|
+
}
|
|
718
|
+
} catch {}
|
|
719
|
+
|
|
720
|
+
// Distribute price to token owner
|
|
721
|
+
address _nativeTokenWrapper = nativeTokenWrapper;
|
|
722
|
+
|
|
723
|
+
CurrencyTransferLib.transferCurrencyWithWrapper(
|
|
724
|
+
_currencyToUse,
|
|
725
|
+
_payer,
|
|
726
|
+
platformFeeRecipient,
|
|
727
|
+
platformFeeCut,
|
|
728
|
+
_nativeTokenWrapper
|
|
729
|
+
);
|
|
730
|
+
CurrencyTransferLib.transferCurrencyWithWrapper(
|
|
731
|
+
_currencyToUse,
|
|
732
|
+
_payer,
|
|
733
|
+
royaltyRecipient,
|
|
734
|
+
royaltyCut,
|
|
735
|
+
_nativeTokenWrapper
|
|
736
|
+
);
|
|
737
|
+
CurrencyTransferLib.transferCurrencyWithWrapper(
|
|
738
|
+
_currencyToUse,
|
|
739
|
+
_payer,
|
|
740
|
+
_payee,
|
|
741
|
+
_totalPayoutAmount - (platformFeeCut + royaltyCut),
|
|
742
|
+
_nativeTokenWrapper
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/// @dev Validates that `_addrToCheck` owns and has approved markeplace to transfer the appropriate amount of currency
|
|
747
|
+
function validateERC20BalAndAllowance(
|
|
748
|
+
address _addrToCheck,
|
|
749
|
+
address _currency,
|
|
750
|
+
uint256 _currencyAmountToCheckAgainst
|
|
751
|
+
) internal view {
|
|
752
|
+
require(
|
|
753
|
+
IERC20Upgradeable(_currency).balanceOf(_addrToCheck) >= _currencyAmountToCheckAgainst &&
|
|
754
|
+
IERC20Upgradeable(_currency).allowance(_addrToCheck, address(this)) >= _currencyAmountToCheckAgainst,
|
|
755
|
+
"!BAL20"
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/// @dev Validates that `_tokenOwner` owns and has approved Market to transfer NFTs.
|
|
760
|
+
function validateOwnershipAndApproval(
|
|
761
|
+
address _tokenOwner,
|
|
762
|
+
address _assetContract,
|
|
763
|
+
uint256 _tokenId,
|
|
764
|
+
uint256 _quantity,
|
|
765
|
+
TokenType _tokenType
|
|
766
|
+
) internal view {
|
|
767
|
+
address market = address(this);
|
|
768
|
+
bool isValid;
|
|
769
|
+
|
|
770
|
+
if (_tokenType == TokenType.ERC1155) {
|
|
771
|
+
isValid =
|
|
772
|
+
IERC1155Upgradeable(_assetContract).balanceOf(_tokenOwner, _tokenId) >= _quantity &&
|
|
773
|
+
IERC1155Upgradeable(_assetContract).isApprovedForAll(_tokenOwner, market);
|
|
774
|
+
} else if (_tokenType == TokenType.ERC721) {
|
|
775
|
+
isValid =
|
|
776
|
+
IERC721Upgradeable(_assetContract).ownerOf(_tokenId) == _tokenOwner &&
|
|
777
|
+
(IERC721Upgradeable(_assetContract).getApproved(_tokenId) == market ||
|
|
778
|
+
IERC721Upgradeable(_assetContract).isApprovedForAll(_tokenOwner, market));
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
require(isValid, "!BALNFT");
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/// @dev Validates conditions of a direct listing sale.
|
|
785
|
+
function validateDirectListingSale(
|
|
786
|
+
Listing memory _listing,
|
|
787
|
+
address _payer,
|
|
788
|
+
uint256 _quantityToBuy,
|
|
789
|
+
address _currency,
|
|
790
|
+
uint256 settledTotalPrice
|
|
791
|
+
) internal {
|
|
792
|
+
require(_listing.listingType == ListingType.Direct, "cannot buy from listing.");
|
|
793
|
+
|
|
794
|
+
// Check whether a valid quantity of listed tokens is being bought.
|
|
795
|
+
require(
|
|
796
|
+
_listing.quantity > 0 && _quantityToBuy > 0 && _quantityToBuy <= _listing.quantity,
|
|
797
|
+
"invalid amount of tokens."
|
|
798
|
+
);
|
|
799
|
+
|
|
800
|
+
// Check if sale is made within the listing window.
|
|
801
|
+
require(block.timestamp < _listing.endTime && block.timestamp > _listing.startTime, "not within sale window.");
|
|
802
|
+
|
|
803
|
+
// Check: buyer owns and has approved sufficient currency for sale.
|
|
804
|
+
if (_currency == CurrencyTransferLib.NATIVE_TOKEN) {
|
|
805
|
+
require(msg.value == settledTotalPrice, "msg.value != price");
|
|
806
|
+
} else {
|
|
807
|
+
validateERC20BalAndAllowance(_payer, _currency, settledTotalPrice);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// Check whether token owner owns and has approved `quantityToBuy` amount of listing tokens from the listing.
|
|
811
|
+
validateOwnershipAndApproval(
|
|
812
|
+
_listing.tokenOwner,
|
|
813
|
+
_listing.assetContract,
|
|
814
|
+
_listing.tokenId,
|
|
815
|
+
_quantityToBuy,
|
|
816
|
+
_listing.tokenType
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/*///////////////////////////////////////////////////////////////
|
|
821
|
+
Getter functions
|
|
822
|
+
//////////////////////////////////////////////////////////////*/
|
|
823
|
+
|
|
824
|
+
/// @dev Enforces quantity == 1 if tokenType is TokenType.ERC721.
|
|
825
|
+
function getSafeQuantity(
|
|
826
|
+
TokenType _tokenType,
|
|
827
|
+
uint256 _quantityToCheck
|
|
828
|
+
) internal pure returns (uint256 safeQuantity) {
|
|
829
|
+
if (_quantityToCheck == 0) {
|
|
830
|
+
safeQuantity = 0;
|
|
831
|
+
} else {
|
|
832
|
+
safeQuantity = _tokenType == TokenType.ERC721 ? 1 : _quantityToCheck;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/// @dev Returns the interface supported by a contract.
|
|
837
|
+
function getTokenType(address _assetContract) internal view returns (TokenType tokenType) {
|
|
838
|
+
if (IERC165Upgradeable(_assetContract).supportsInterface(type(IERC1155Upgradeable).interfaceId)) {
|
|
839
|
+
tokenType = TokenType.ERC1155;
|
|
840
|
+
} else if (IERC165Upgradeable(_assetContract).supportsInterface(type(IERC721Upgradeable).interfaceId)) {
|
|
841
|
+
tokenType = TokenType.ERC721;
|
|
842
|
+
} else {
|
|
843
|
+
revert("token must be ERC1155 or ERC721.");
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/// @dev Returns the platform fee recipient and bps.
|
|
848
|
+
function getPlatformFeeInfo() external view returns (address, uint16) {
|
|
849
|
+
return (platformFeeRecipient, uint16(platformFeeBps));
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/*///////////////////////////////////////////////////////////////
|
|
853
|
+
Setter functions
|
|
854
|
+
//////////////////////////////////////////////////////////////*/
|
|
855
|
+
|
|
856
|
+
/// @dev Lets a contract admin update platform fee recipient and bps.
|
|
857
|
+
function setPlatformFeeInfo(
|
|
858
|
+
address _platformFeeRecipient,
|
|
859
|
+
uint256 _platformFeeBps
|
|
860
|
+
) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
861
|
+
require(_platformFeeBps <= MAX_BPS, "bps <= 10000.");
|
|
862
|
+
|
|
863
|
+
platformFeeBps = uint64(_platformFeeBps);
|
|
864
|
+
platformFeeRecipient = _platformFeeRecipient;
|
|
865
|
+
|
|
866
|
+
emit PlatformFeeInfoUpdated(_platformFeeRecipient, _platformFeeBps);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/// @dev Lets a contract admin set auction buffers.
|
|
870
|
+
function setAuctionBuffers(uint256 _timeBuffer, uint256 _bidBufferBps) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
871
|
+
require(_bidBufferBps < MAX_BPS, "invalid BPS.");
|
|
872
|
+
|
|
873
|
+
timeBuffer = uint64(_timeBuffer);
|
|
874
|
+
bidBufferBps = uint64(_bidBufferBps);
|
|
875
|
+
|
|
876
|
+
emit AuctionBuffersUpdated(_timeBuffer, _bidBufferBps);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/// @dev Lets a contract admin set the URI for the contract-level metadata.
|
|
880
|
+
function setContractURI(string calldata _uri) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
881
|
+
contractURI = _uri;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/*///////////////////////////////////////////////////////////////
|
|
885
|
+
Miscellaneous
|
|
886
|
+
//////////////////////////////////////////////////////////////*/
|
|
887
|
+
|
|
888
|
+
function _msgSender()
|
|
889
|
+
internal
|
|
890
|
+
view
|
|
891
|
+
virtual
|
|
892
|
+
override(ContextUpgradeable, ERC2771ContextUpgradeable, Multicall)
|
|
893
|
+
returns (address sender)
|
|
894
|
+
{
|
|
895
|
+
return ERC2771ContextUpgradeable._msgSender();
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
function _msgData()
|
|
899
|
+
internal
|
|
900
|
+
view
|
|
901
|
+
virtual
|
|
902
|
+
override(ContextUpgradeable, ERC2771ContextUpgradeable)
|
|
903
|
+
returns (bytes calldata)
|
|
904
|
+
{
|
|
905
|
+
return ERC2771ContextUpgradeable._msgData();
|
|
906
|
+
}
|
|
907
|
+
}
|