Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
30699 | 66 days ago | Contract Creation | 0 APE |
Loading...
Loading
Contract Name:
SignedZoneV16Royalty
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {ZoneParameters, Schema} from "../lib/ConsiderationStructs.sol"; import {ZoneInterfaceV16} from "../interfaces/ZoneInterfaceV16.sol"; import {SignedZoneV16RoyaltyEventsAndErrors} from "./interfaces/SignedZoneV16RoyaltyEventsAndErrors.sol"; import {SIP5Interface} from "./interfaces/SIP5Interface.sol"; import {SignedZoneControllerInterface} from "./interfaces/SignedZoneControllerInterface.sol"; import {IAuthorizedTransferSecurityRegistry} from "./interfaces/IAuthorizedTransferSecurityRegistry.sol"; import "./lib/SignedZoneV16RoyaltyConstants.sol"; /** * @title SignedZoneV16Royalty * @author ryanio, BCLeFevre * @notice SignedZoneV16Royalty is an implementation of SIP-7 that requires orders * to be signed by an approved signer. * https://github.com/ProjectOpenSea/SIPs/blob/main/SIPS/sip-7.md */ contract SignedZoneV16Royalty is SignedZoneV16RoyaltyEventsAndErrors, ZoneInterfaceV16, SIP5Interface { /// @dev The zone's controller that is set during deployment. address private immutable _controller; /// @dev The authorized signers, and if they are active. mapping(address => bool) private _signers; /// @dev The EIP-712 digest parameters. bytes32 internal immutable _NAME_HASH; bytes32 internal immutable _VERSION_HASH = keccak256(bytes("2.0")); // prettier-ignore bytes32 internal immutable _EIP_712_DOMAIN_TYPEHASH = keccak256( abi.encodePacked( "EIP712Domain(", "string name,", "string version,", "uint256 chainId,", "address verifyingContract", ")" ) ); // prettier-ignore bytes32 internal immutable _SIGNED_ORDER_TYPEHASH = keccak256( abi.encodePacked( "SignedOrder(", "address fulfiller,", "uint64 expiration,", "bytes32 orderHash,", "bytes context", ")" ) ); uint256 internal immutable _CHAIN_ID = block.chainid; bytes32 internal immutable _DOMAIN_SEPARATOR; address private immutable SEAPORT = 0x0000000000000068F116a894984e2DB1123eB395; /** * @notice Constructor to deploy the contract. * * @param zoneName The name for the zone used in the domain separator * derivation. */ constructor(string memory zoneName) { // Set the deployer as the controller. _controller = msg.sender; // Set the name hash. _NAME_HASH = keccak256(bytes(zoneName)); // Derive and set the domain separator. _DOMAIN_SEPARATOR = _deriveDomainSeparator(); // Emit an event to signal a SIP-5 contract has been deployed. emit SeaportCompatibleContractDeployed(); } /** * @notice The fallback function is used as a dispatcher for the * `updateSigner`, `isActiveSigner`, `getActiveSigners` and * `supportsInterface` functions. */ // prettier-ignore fallback(bytes calldata) external returns (bytes memory output) { // Get the function selector. bytes4 selector = msg.sig; if (selector == UPDATE_SIGNER_SELECTOR) { // abi.encodeWithSignature("updateSigner(address,bool)", signer, // active) // Get the signer, and active status. address signer = abi.decode(msg.data[4:], (address)); bool active = abi.decode(msg.data[36:], (bool)); // Call to update the signer. _updateSigner(signer, active); } else if (selector == GET_ACTIVE_SIGNERS_SELECTOR) { // abi.encodeWithSignature("getActiveSigners()") // Call the internal function to get the active signers. return abi.encode(_getActiveSigners()); } else if (selector == IS_ACTIVE_SIGNER_SELECTOR) { // abi.encodeWithSignature("isActiveSigner(address)", signer) // Get the signer. address signer = abi.decode(msg.data[4:], (address)); // Call the internal function to determine if the signer is active. return abi.encode(_isActiveSigner(signer)); } else { // Revert if the function selector is not supported. assembly { // Store left-padded selector with push4 (reduces bytecode), // mem[28:32] = selector mstore(0, UnsupportedFunctionSelector_error_selector) // revert(abi.encodeWithSignature( // "UnsupportedFunctionSelector()" // )) revert(0x1c, UnsupportedFunctionSelector_error_length) } } } /** * @notice Check if a given order including extraData is currently valid. * * @dev This function is called by Seaport whenever any extraData is * provided by the caller. * * @return authorizedOrderMagicValue A magic value indicating if the order * is currently valid. */ function authorizeOrder( ZoneParameters calldata zoneParameters ) external override returns (bytes4 authorizedOrderMagicValue) { if (msg.sender != SEAPORT) { // Revert if the caller is not Seaport. revert CallerNotSeaport(); } // Check Zone Parameters validity. _assertValidZoneParameters(); // Put the extraData and orderHash on the stack for cheaper access. bytes calldata extraData = zoneParameters.extraData; bytes32 orderHash = zoneParameters.orderHash; // Declare a variable to hold the expiration. uint64 expiration; // Declare a variable to hold the substandard version byte. uint256 subStandardVersionByte; // Validate the extraData. assembly { // Get the length of the extraData. let extraDataPtr := add(0x24, calldataload(Zone_extraData_cdPtr)) let extraDataLength := calldataload(extraDataPtr) // Validate the extra data length. if lt(extraDataLength, InvalidExtraDataLength_expected_length_substandard_1) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidExtraDataLength_error_selector) mstore(InvalidExtraDataLength_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "InvalidExtraDataLength(bytes32)", orderHash) // ) revert(0x1c, InvalidExtraDataLength_error_length) } // extraData bytes 0-1: SIP-6 version byte (MUST be 0x00) let versionByte := shr(248, calldataload(add(extraDataPtr, 0x20))) // Validate the SIP6 Version byte. if iszero(eq(versionByte, 0x00)) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidSIP6Version_error_selector) mstore(InvalidSIP6Version_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "InvalidSIP6Version(bytes32)", orderHash) // ) revert(0x1c, InvalidSIP6Version_error_length) } // extraData bytes 93-94: Substandard #1 // (MUST be 0x00, 0x01, 0x07, 0x08, or 0x09) subStandardVersionByte := shr( 248, calldataload(add(extraDataPtr, ExtraData_substandard_version_byte_offset)) ) // Validate the substandard version byte. if or( gt(subStandardVersionByte, 0x09), and(gt(subStandardVersionByte, 0x01), lt(subStandardVersionByte, 0x07)) ) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidSubstandardVersion_error_selector) mstore(InvalidSubstandardVersion_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "InvalidSubstandardVersion(bytes32)", orderHash) // ) revert(0x1c, InvalidSubstandardVersion_error_length) } // extraData bytes 21-29: expiration timestamp (uint64) expiration := shr(192, calldataload(add(extraDataPtr, ExtraData_expiration_offset))) // Revert if expired. if lt(expiration, timestamp()) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, SignatureExpired_error_selector) mstore(SignatureExpired_error_expiration_ptr, expiration) mstore(SignatureExpired_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "SignatureExpired(uint256,bytes32)", expiration, orderHash) // ) revert(0x1c, SignatureExpired_error_length) } // Get the length of the consideration array. let considerationLength := calldataload( add(0x24, calldataload(Zone_consideration_head_cdPtr)) ) // Revert if the order does not have any consideration items due to // the Substandard #1 requirement. if iszero(considerationLength) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidSubstandardSupport_error_selector) mstore(InvalidSubstandardSupport_error_reason_offset_ptr, 0x60) mstore(InvalidSubstandardSupport_error_substandard_version_ptr, 1) mstore(InvalidSubstandardSupport_error_orderHash_ptr, orderHash) mstore(InvalidSubstandardSupport_error_reason_length_ptr, 0x2a) mstore(InvalidSubstandardSupport_error_reason_ptr, "Consideration must have at least") mstore(InvalidSubstandardSupport_error_reason_2_ptr, " one item.") // revert(abi.encodeWithSignature( // "InvalidSubstandardSupport(string,uint256,bytes32)", // reason, // substandardVersion, // orderHash // )) revert(0x1c, InvalidSubstandardSupport_error_length) } } // Check the validity of the Substandard #1 extraData and get the // expected fulfiller address. address expectedFulfiller = (_assertValidSubstandardAndGetExpectedFulfiller(orderHash)); // extraData bytes 29-93: signature // (strictly requires 64 byte compact sig, EIP-2098) bytes calldata signature = extraData[29:93]; // extraData bytes 93-126: context (fixed length, 32 bytes + 1 byte) bytes calldata context; if (subStandardVersionByte < 2) { context = extraData[93:126]; } else if (subStandardVersionByte == 7) { if (extraData.length < 166) { assembly { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidExtraDataLength_error_selector) mstore(InvalidExtraDataLength_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "InvalidExtraDataLength(bytes32)", orderHash) // ) revert(0x1c, InvalidExtraDataLength_error_length) } } context = extraData[93:166]; } else { if (extraData.length < 146) { assembly { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidExtraDataLength_error_selector) mstore(InvalidExtraDataLength_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "InvalidExtraDataLength(bytes32)", orderHash) // ) revert(0x1c, InvalidExtraDataLength_error_length) } } context = extraData[93:146]; } // Derive the signedOrder hash. bytes32 signedOrderHash = _deriveSignedOrderHash( expectedFulfiller, expiration, orderHash, context ); // Derive the EIP-712 digest using the domain separator and signedOrder // hash. bytes32 digest = _deriveEIP712Digest(_domainSeparator(), signedOrderHash); // Recover the signer address from the digest and signature. address recoveredSigner = _recoverSigner(digest, signature); // Revert if the signer is not active. if (!_signers[recoveredSigner]) { revert SignerNotActive(recoveredSigner, orderHash); } // Set the transfer status of the tokens to true. _setTransferStatus(zoneParameters, true); // Return the selector of authorizeOrder as the magic value. authorizedOrderMagicValue = ZoneInterfaceV16.authorizeOrder.selector; } /** * @notice Check if a given order including extraData is currently valid. * * @dev This function is called by Seaport whenever any extraData is * provided by the caller. * * @return validOrderMagicValue A magic value indicating if the order is * currently valid. */ function validateOrder( ZoneParameters calldata zoneParameters ) external override returns (bytes4 validOrderMagicValue) { if (msg.sender != SEAPORT) { // Revert if the caller is not Seaport. revert CallerNotSeaport(); } // Set the transfer status of the tokens to false. _setTransferStatus(zoneParameters, false); // Return the selector of validateOrder as the magic value. validOrderMagicValue = ZoneInterfaceV16.validateOrder.selector; } /** * @dev Returns Seaport metadata for this contract, returning the * contract name and supported schemas. * * @return name The contract name * @return schemas The supported SIPs */ function getSeaportMetadata() external view override(SIP5Interface, ZoneInterfaceV16) returns (string memory name, Schema[] memory schemas) { // Return the supported SIPs. schemas = new Schema[](1); schemas[0].id = 7; // Get the SIP-7 information. ( bytes32 domainSeparator, string memory zoneName, string memory apiEndpoint, uint256[] memory substandards, string memory documentationURI ) = _sip7Information(); // Return the zone name. name = zoneName; // Encode the SIP-7 information. schemas[0].metadata = abi.encode(domainSeparator, apiEndpoint, substandards, documentationURI); } /** * @dev Sets the transfer status of the token based on the consideration * items or offer items. * * @param zoneParameters The zone parameters. * @param active The transfer status of the token. */ function _setTransferStatus(ZoneParameters calldata zoneParameters, bool active) internal { uint8 subStandardVersionByte = uint8(bytes1(zoneParameters.extraData[93])); if (subStandardVersionByte < 2) { return; } address registry = address(bytes20(zoneParameters.extraData[126:146])); address token; uint256 identifier; uint256 amount; if (uint256(zoneParameters.consideration[0].itemType) > 1) { // Call on first consideration token = zoneParameters.consideration[0].token; identifier = zoneParameters.consideration[0].identifier; amount = zoneParameters.consideration[0].amount; } else { // Call on first offer token = zoneParameters.offer[0].token; identifier = zoneParameters.offer[0].identifier; amount = zoneParameters.offer[0].amount; } if (subStandardVersionByte == 7) { address operator = address(bytes20(zoneParameters.extraData[146:166])); if (active) { IAuthorizedTransferSecurityRegistry(registry).beforeAuthorizedTransfer(operator, token); } else { IAuthorizedTransferSecurityRegistry(registry).afterAuthorizedTransfer(token); } } else if (subStandardVersionByte == 8) { if (active) { IAuthorizedTransferSecurityRegistry(registry).beforeAuthorizedTransfer(token, identifier); } else { IAuthorizedTransferSecurityRegistry(registry).afterAuthorizedTransfer(token, identifier); } } /* subStandardVersionByte == 9 */ else { if (active) { IAuthorizedTransferSecurityRegistry(registry).beforeAuthorizedTransferWithAmount( token, identifier, amount ); } else { IAuthorizedTransferSecurityRegistry(registry).afterAuthorizedTransferWithAmount( token, identifier ); } } } /** * @notice Add or remove a signer to the zone. * Only the controller can call this function. * * @param signer The signer address to add or remove. */ function _updateSigner(address signer, bool active) internal { // Only the controller can call this function. _assertCallerIsController(); // Add or remove the signer. active ? _addSigner(signer) : _removeSigner(signer); } /** * @notice Add a new signer to the zone. * Only the controller or an active signer can call this function. * * @param signer The new signer address to add. */ function _addSigner(address signer) internal { // Set the signer's active status to true. _signers[signer] = true; // Emit an event that the signer was added. emit SignerAdded(signer); } /** * @notice Remove an active signer from the zone. * Only the controller or an active signer can call this function. * * @param signer The signer address to remove. */ function _removeSigner(address signer) internal { // Set the signer's active status to false. _signers[signer] = false; // Emit an event that the signer was removed. emit SignerRemoved(signer); } /** * @notice Returns the active signers for the zone. Note that the array of * active signers could grow to a size that this function could not * return, the array of active signers is expected to be small, * and is managed by the controller. * * @return signers The active signers. */ function _getActiveSigners() internal view returns (address[] memory signers) { // Return the active signers for the zone by calling the controller. signers = SignedZoneControllerInterface(_controller).getActiveSigners(address(this)); } /** * @notice Returns if the given address is an active signer for the zone. * * @param signer The address to check if it is an active signer. * * @return The address is an active signer, false otherwise. */ function _isActiveSigner(address signer) internal view returns (bool) { // Return the active status of the caller. return _signers[signer]; } /** * @notice Returns whether the interface is supported. * * @param interfaceId The interface id to check against. */ function _supportsInterface(bytes4 interfaceId) internal pure returns (bool) { // Determine if the interface is supported. return (interfaceId == type(SIP5Interface).interfaceId || // SIP-5 interfaceId == type(ZoneInterfaceV16).interfaceId || // ZoneInterface interfaceId == 0x01ffc9a7); // ERC-165 } /** * @notice Internal call to return the signing information, substandards, * and documentation about the zone. * * @return domainSeparator The domain separator used for signing. * @return zoneName The zone name. * @return apiEndpoint The API endpoint for the zone. * @return substandards The substandards supported by the zone. * @return documentationURI The documentation URI for the zone. */ function _sip7Information() internal view returns ( bytes32 domainSeparator, string memory zoneName, string memory apiEndpoint, uint256[] memory substandards, string memory documentationURI ) { // Return the SIP-7 information. domainSeparator = _domainSeparator(); // Get the SIP-7 information from the controller. (, zoneName, apiEndpoint, substandards, documentationURI) = SignedZoneControllerInterface( _controller ).getAdditionalZoneInformation(address(this)); } /** * @dev Derive the signedOrder hash from the orderHash and expiration. * * @param fulfiller The expected fulfiller address. * @param expiration The signature expiration timestamp. * @param orderHash The order hash. * @param context The optional variable-length context. * * @return signedOrderHash The signedOrder hash. * */ function _deriveSignedOrderHash( address fulfiller, uint64 expiration, bytes32 orderHash, bytes calldata context ) internal view returns (bytes32 signedOrderHash) { // Derive the signed order hash. signedOrderHash = keccak256( abi.encode(_SIGNED_ORDER_TYPEHASH, fulfiller, expiration, orderHash, keccak256(context)) ); } /** * @dev Internal view function to return the signer of a signature. * * @param digest The digest to verify the signature against. * @param signature A signature from the signer indicating that the order * has been approved. * * @return recoveredSigner The recovered signer. */ function _recoverSigner( bytes32 digest, bytes memory signature ) internal view returns (address recoveredSigner) { // Utilize assembly to perform optimized signature verification check. assembly { // Ensure that first word of scratch space is empty. mstore(0, 0) // Declare value for v signature parameter. let v // Get the length of the signature. let signatureLength := mload(signature) // Get the pointer to the value preceding the signature length. // This will be used for temporary memory overrides - either the // signature head for isValidSignature or the digest for ecrecover. let wordBeforeSignaturePtr := sub(signature, OneWord) // Cache the current value behind the signature to restore it later. let cachedWordBeforeSignature := mload(wordBeforeSignaturePtr) // Declare lenDiff + recoveredSigner scope to manage stack pressure. { // Take the difference between the max ECDSA signature length // and the actual signature length. Overflow desired for any // values > 65. If the diff is not 0 or 1, it is not a valid // ECDSA signature - move on to EIP1271 check. let lenDiff := sub(ECDSA_MaxLength, signatureLength) // If diff is 0 or 1, it may be an ECDSA signature. // Try to recover signer. if iszero(gt(lenDiff, 1)) { // Read the signature `s` value. let originalSignatureS := mload(add(signature, ECDSA_signature_s_offset)) // Read the first byte of the word after `s`. If the // signature is 65 bytes, this will be the real `v` value. // If not, it will need to be modified - doing it this way // saves an extra condition. v := byte(0, mload(add(signature, ECDSA_signature_v_offset))) // If lenDiff is 1, parse 64-byte signature as ECDSA. if lenDiff { // Extract yParity from highest bit of vs and add 27 to // get v. v := add(shr(MaxUint8, originalSignatureS), Signature_lower_v) // Extract canonical s from vs, all but the highest bit. // Temporarily overwrite the original `s` value in the // signature. mstore( add(signature, ECDSA_signature_s_offset), and(originalSignatureS, EIP2098_allButHighestBitMask) ) } // Temporarily overwrite the signature length with `v` to // conform to the expected input for ecrecover. mstore(signature, v) // Temporarily overwrite the word before the length with // `digest` to conform to the expected input for ecrecover. mstore(wordBeforeSignaturePtr, digest) // Attempt to recover the signer for the given signature. Do // not check the call status as ecrecover will return a null // address if the signature is invalid. pop( staticcall( gas(), Ecrecover_precompile, // Call ecrecover precompile. wordBeforeSignaturePtr, // Use data memory location. Ecrecover_args_size, // Size of digest, v, r, and s. 0, // Write result to scratch space. OneWord // Provide size of returned result. ) ) // Restore cached word before signature. mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature) // Restore cached signature length. mstore(signature, signatureLength) // Restore cached signature `s` value. mstore(add(signature, ECDSA_signature_s_offset), originalSignatureS) // Read the recovered signer from the buffer given as return // space for ecrecover. recoveredSigner := mload(0) } } // Restore the cached values overwritten by selector, digest and // signature head. mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature) } } /** * @dev Internal view function to get the EIP-712 domain separator. If the * chainId matches the chainId set on deployment, the cached domain * separator will be returned; otherwise, it will be derived from * scratch. * * @return The domain separator. */ function _domainSeparator() internal view returns (bytes32) { // prettier-ignore return block.chainid == _CHAIN_ID ? _DOMAIN_SEPARATOR : _deriveDomainSeparator(); } /** * @dev Internal view function to derive the EIP-712 domain separator. * * @return domainSeparator The derived domain separator. */ function _deriveDomainSeparator() internal view returns (bytes32 domainSeparator) { bytes32 typehash = _EIP_712_DOMAIN_TYPEHASH; bytes32 nameHash = _NAME_HASH; bytes32 versionHash = _VERSION_HASH; // Leverage scratch space and other memory to perform an efficient hash. assembly { // Retrieve the free memory pointer; it will be replaced afterwards. let freeMemoryPointer := mload(FreeMemoryPointerSlot) // Retrieve value at 0x80; it will also be replaced afterwards. let slot0x80 := mload(Slot0x80) // Place typehash, name hash, and version hash at start of memory. mstore(0, typehash) mstore(OneWord, nameHash) mstore(TwoWords, versionHash) // Place chainId in the next memory location. mstore(ThreeWords, chainid()) // Place the address of this contract in the next memory location. mstore(FourWords, address()) // Hash relevant region of memory to derive the domain separator. domainSeparator := keccak256(0, FiveWords) // Restore the free memory pointer. mstore(FreeMemoryPointerSlot, freeMemoryPointer) // Restore the zero slot to zero. mstore(ZeroSlot, 0) // Restore the value at 0x80. mstore(Slot0x80, slot0x80) } } /** * @dev Internal pure function to efficiently derive an digest to sign for * an order in accordance with EIP-712. * * @param domainSeparator The domain separator. * @param signedOrderHash The signedOrder hash. * * @return digest The digest hash. */ function _deriveEIP712Digest( bytes32 domainSeparator, bytes32 signedOrderHash ) internal pure returns (bytes32 digest) { // Leverage scratch space to perform an efficient hash. assembly { // Place the EIP-712 prefix at the start of scratch space. mstore(0, EIP_712_PREFIX) // Place the domain separator in the next region of scratch space. mstore(EIP712_DomainSeparator_offset, domainSeparator) // Place the signed order hash in scratch space, spilling into the // first two bytes of the free memory pointer — this should never be // set as memory cannot be expanded to that size, and will be // zeroed out after the hash is performed. mstore(EIP712_SignedOrderHash_offset, signedOrderHash) // Hash the relevant region digest := keccak256(0, EIP712_DigestPayload_size) // Clear out the dirtied bits in the memory pointer. mstore(EIP712_SignedOrderHash_offset, 0) } } /** * @dev Internal view function to revert if the caller is not the * controller. */ function _assertCallerIsController() internal view { // Get the controller address to use in the assembly block. address controller = _controller; assembly { // Revert if the caller is not the controller. if iszero(eq(caller(), controller)) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidController_error_selector) // revert(abi.encodeWithSignature( // "InvalidController()") // ) revert(0x1c, InvalidController_error_length) } } } /** * @dev Internal pure function to validate calldata offsets for the * dyanamic type in ZoneParameters. This ensures that functions using * the calldata object normally will be using the same data as the * assembly functions and that values that are bound to a given range * are within that range. */ function _assertValidZoneParameters() internal pure { // Utilize assembly in order to read offset data directly from calldata. assembly { /* * Checks: * 1. Zone parameters struct offset == 0x20 */ // Zone parameters at calldata 0x04 must have offset of 0x20. if iszero(eq(calldataload(Zone_parameters_cdPtr), Zone_parameters_ptr)) { // Store left-padded selector with push4 (reduces bytecode), // mem[28:32] = selector mstore(0, InvalidZoneParameterEncoding_error_selector) // revert(abi.encodeWithSignature( // "InvalidZoneParameterEncoding()" // )) revert(0x1c, InvalidZoneParameterEncoding_error_length) } } } /** * @dev Internal pure function to ensure that the context argument for the * supplied extra data follows the substandard #1 format. Returns the * expected fulfiller of the order for deriving the signed order hash. * * @param orderHash The order hash. * * @return expectedFulfiller The expected fulfiller of the order. */ function _assertValidSubstandardAndGetExpectedFulfiller( bytes32 orderHash ) internal pure returns (address expectedFulfiller) { // Revert if the expected fulfiller is not the zero address and does // not match the actual fulfiller or if the expected received // identifier does not match the actual received identifier. assembly { // Get the actual fulfiller. let actualFulfiller := calldataload(Zone_parameters_fulfiller_cdPtr) let extraDataPtr := calldataload(Zone_extraData_cdPtr) let considerationPtr := calldataload(Zone_consideration_head_cdPtr) // Get the expected fulfiller. expectedFulfiller := shr(96, calldataload(add(expectedFulfiller_offset, extraDataPtr))) // Get the actual received identifier. let actualReceivedIdentifier := calldataload( add(actualReceivedIdentifier_offset, considerationPtr) ) // Get the expected received identifier. let expectedReceivedIdentifier := calldataload( add(expectedReceivedIdentifier_offset, extraDataPtr) ) // Revert if expected fulfiller is not the zero address and does // not match the actual fulfiller. if and(iszero(iszero(expectedFulfiller)), iszero(eq(expectedFulfiller, actualFulfiller))) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidFulfiller_error_selector) mstore(InvalidFulfiller_error_expectedFulfiller_ptr, expectedFulfiller) mstore(InvalidFulfiller_error_actualFulfiller_ptr, actualFulfiller) mstore(InvalidFulfiller_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "InvalidFulfiller(address,address,bytes32)", // expectedFulfiller, // actualFulfiller, // orderHash // )) revert(0x1c, InvalidFulfiller_error_length) } // Revert if expected received item does not match the actual // received item. if iszero(eq(expectedReceivedIdentifier, actualReceivedIdentifier)) { // Store left-padded selector with push4, mem[28:32] = selector mstore(0, InvalidReceivedItem_error_selector) mstore(InvalidReceivedItem_error_expectedReceivedItem_ptr, expectedReceivedIdentifier) mstore(InvalidReceivedItem_error_actualReceivedItem_ptr, actualReceivedIdentifier) mstore(InvalidReceivedItem_error_orderHash_ptr, orderHash) // revert(abi.encodeWithSignature( // "InvalidReceivedItem(uint256,uint256,bytes32)", // expectedReceivedIdentifier, // actualReceievedIdentifier, // orderHash // )) revert(0x1c, InvalidReceivedItem_error_length) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {ZoneParameters, Schema} from "../lib/ConsiderationStructs.sol"; interface ZoneInterfaceV16 { function authorizeOrder( ZoneParameters calldata zoneParameters ) external returns (bytes4 authorizeOrderMagicValue); function validateOrder( ZoneParameters calldata zoneParameters ) external returns (bytes4 validOrderMagicValue); function getSeaportMetadata() external view returns ( string memory name, Schema[] memory schemas // map to Seaport Improvement Proposal IDs ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; // prettier-ignore enum OrderType { // 0: no partial fills, anyone can execute FULL_OPEN, // 1: partial fills supported, anyone can execute PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute PARTIAL_RESTRICTED, // 4: contract order type CONTRACT } // prettier-ignore enum BasicOrderType { // 0: no partial fills, anyone can execute ETH_TO_ERC721_FULL_OPEN, // 1: partial fills supported, anyone can execute ETH_TO_ERC721_PARTIAL_OPEN, // 2: no partial fills, only offerer or zone can execute ETH_TO_ERC721_FULL_RESTRICTED, // 3: partial fills supported, only offerer or zone can execute ETH_TO_ERC721_PARTIAL_RESTRICTED, // 4: no partial fills, anyone can execute ETH_TO_ERC1155_FULL_OPEN, // 5: partial fills supported, anyone can execute ETH_TO_ERC1155_PARTIAL_OPEN, // 6: no partial fills, only offerer or zone can execute ETH_TO_ERC1155_FULL_RESTRICTED, // 7: partial fills supported, only offerer or zone can execute ETH_TO_ERC1155_PARTIAL_RESTRICTED, // 8: no partial fills, anyone can execute ERC20_TO_ERC721_FULL_OPEN, // 9: partial fills supported, anyone can execute ERC20_TO_ERC721_PARTIAL_OPEN, // 10: no partial fills, only offerer or zone can execute ERC20_TO_ERC721_FULL_RESTRICTED, // 11: partial fills supported, only offerer or zone can execute ERC20_TO_ERC721_PARTIAL_RESTRICTED, // 12: no partial fills, anyone can execute ERC20_TO_ERC1155_FULL_OPEN, // 13: partial fills supported, anyone can execute ERC20_TO_ERC1155_PARTIAL_OPEN, // 14: no partial fills, only offerer or zone can execute ERC20_TO_ERC1155_FULL_RESTRICTED, // 15: partial fills supported, only offerer or zone can execute ERC20_TO_ERC1155_PARTIAL_RESTRICTED, // 16: no partial fills, anyone can execute ERC721_TO_ERC20_FULL_OPEN, // 17: partial fills supported, anyone can execute ERC721_TO_ERC20_PARTIAL_OPEN, // 18: no partial fills, only offerer or zone can execute ERC721_TO_ERC20_FULL_RESTRICTED, // 19: partial fills supported, only offerer or zone can execute ERC721_TO_ERC20_PARTIAL_RESTRICTED, // 20: no partial fills, anyone can execute ERC1155_TO_ERC20_FULL_OPEN, // 21: partial fills supported, anyone can execute ERC1155_TO_ERC20_PARTIAL_OPEN, // 22: no partial fills, only offerer or zone can execute ERC1155_TO_ERC20_FULL_RESTRICTED, // 23: partial fills supported, only offerer or zone can execute ERC1155_TO_ERC20_PARTIAL_RESTRICTED } // prettier-ignore enum BasicOrderRouteType { // 0: provide Ether (or other native token) to receive offered ERC721 item. ETH_TO_ERC721, // 1: provide Ether (or other native token) to receive offered ERC1155 item. ETH_TO_ERC1155, // 2: provide ERC20 item to receive offered ERC721 item. ERC20_TO_ERC721, // 3: provide ERC20 item to receive offered ERC1155 item. ERC20_TO_ERC1155, // 4: provide ERC721 item to receive offered ERC20 item. ERC721_TO_ERC20, // 5: provide ERC1155 item to receive offered ERC20 item. ERC1155_TO_ERC20 } // prettier-ignore enum ItemType { // 0: ETH on mainnet, MATIC on polygon, etc. NATIVE, // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work) ERC20, // 2: ERC721 items ERC721, // 3: ERC1155 items ERC1155, // 4: ERC721 items where a number of tokenIds are supported ERC721_WITH_CRITERIA, // 5: ERC1155 items where a number of ids are supported ERC1155_WITH_CRITERIA } // prettier-ignore enum Side { // 0: Items that can be spent OFFER, // 1: Items that must be received CONSIDERATION }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { OrderType, BasicOrderType, ItemType, Side } from "./ConsiderationEnums.sol"; /** * @dev An order contains eleven components: an offerer, a zone (or account that * can cancel the order or restrict who can fulfill the order depending on * the type), the order type (specifying partial fill support as well as * restricted order status), the start and end time, a hash that will be * provided to the zone when validating restricted orders, a salt, a key * corresponding to a given conduit, a counter, and an arbitrary number of * offer items that can be spent along with consideration items that must * be received by their respective recipient. */ struct OrderComponents { address offerer; address zone; OfferItem[] offer; ConsiderationItem[] consideration; OrderType orderType; uint256 startTime; uint256 endTime; bytes32 zoneHash; uint256 salt; bytes32 conduitKey; uint256 counter; } /** * @dev An offer item has five components: an item type (ETH or other native * tokens, ERC20, ERC721, and ERC1155, as well as criteria-based ERC721 and * ERC1155), a token address, a dual-purpose "identifierOrCriteria" * component that will either represent a tokenId or a merkle root * depending on the item type, and a start and end amount that support * increasing or decreasing amounts over the duration of the respective * order. */ struct OfferItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; } /** * @dev A consideration item has the same five components as an offer item and * an additional sixth component designating the required recipient of the * item. */ struct ConsiderationItem { ItemType itemType; address token; uint256 identifierOrCriteria; uint256 startAmount; uint256 endAmount; address payable recipient; } /** * @dev A spent item is translated from a utilized offer item and has four * components: an item type (ETH or other native tokens, ERC20, ERC721, and * ERC1155), a token address, a tokenId, and an amount. */ struct SpentItem { ItemType itemType; address token; uint256 identifier; uint256 amount; } /** * @dev A received item is translated from a utilized consideration item and has * the same four components as a spent item, as well as an additional fifth * component designating the required recipient of the item. */ struct ReceivedItem { ItemType itemType; address token; uint256 identifier; uint256 amount; address payable recipient; } /** * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155 * matching, a group of six functions may be called that only requires a * subset of the usual order arguments. Note the use of a "basicOrderType" * enum; this represents both the usual order type as well as the "route" * of the basic order (a simple derivation function for the basic order * type is `basicOrderType = orderType + (4 * basicOrderRoute)`.) */ struct BasicOrderParameters { // calldata offset address considerationToken; // 0x24 uint256 considerationIdentifier; // 0x44 uint256 considerationAmount; // 0x64 address payable offerer; // 0x84 address zone; // 0xa4 address offerToken; // 0xc4 uint256 offerIdentifier; // 0xe4 uint256 offerAmount; // 0x104 BasicOrderType basicOrderType; // 0x124 uint256 startTime; // 0x144 uint256 endTime; // 0x164 bytes32 zoneHash; // 0x184 uint256 salt; // 0x1a4 bytes32 offererConduitKey; // 0x1c4 bytes32 fulfillerConduitKey; // 0x1e4 uint256 totalOriginalAdditionalRecipients; // 0x204 AdditionalRecipient[] additionalRecipients; // 0x224 bytes signature; // 0x244 // Total length, excluding dynamic array data: 0x264 (580) } /** * @dev Basic orders can supply any number of additional recipients, with the * implied assumption that they are supplied from the offered ETH (or other * native token) or ERC20 token for the order. */ struct AdditionalRecipient { uint256 amount; address payable recipient; } /** * @dev The full set of order components, with the exception of the counter, * must be supplied when fulfilling more sophisticated orders or groups of * orders. The total number of original consideration items must also be * supplied, as the caller may specify additional consideration items. */ struct OrderParameters { address offerer; // 0x00 address zone; // 0x20 OfferItem[] offer; // 0x40 ConsiderationItem[] consideration; // 0x60 OrderType orderType; // 0x80 uint256 startTime; // 0xa0 uint256 endTime; // 0xc0 bytes32 zoneHash; // 0xe0 uint256 salt; // 0x100 bytes32 conduitKey; // 0x120 uint256 totalOriginalConsiderationItems; // 0x140 // offer.length // 0x160 } /** * @dev Orders require a signature in addition to the other order parameters. */ struct Order { OrderParameters parameters; bytes signature; } /** * @dev Advanced orders include a numerator (i.e. a fraction to attempt to fill) * and a denominator (the total size of the order) in addition to the * signature and other order parameters. It also supports an optional field * for supplying extra data; this data will be provided to the zone if the * order type is restricted and the zone is not the caller, or will be * provided to the offerer as context for contract order types. */ struct AdvancedOrder { OrderParameters parameters; uint120 numerator; uint120 denominator; bytes signature; bytes extraData; } /** * @dev Orders can be validated (either explicitly via `validate`, or as a * consequence of a full or partial fill), specifically cancelled (they can * also be cancelled in bulk via incrementing a per-zone counter), and * partially or fully filled (with the fraction filled represented by a * numerator and denominator). */ struct OrderStatus { bool isValidated; bool isCancelled; uint120 numerator; uint120 denominator; } /** * @dev A criteria resolver specifies an order, side (offer vs. consideration), * and item index. It then provides a chosen identifier (i.e. tokenId) * alongside a merkle proof demonstrating the identifier meets the required * criteria. */ struct CriteriaResolver { uint256 orderIndex; Side side; uint256 index; uint256 identifier; bytes32[] criteriaProof; } /** * @dev A fulfillment is applied to a group of orders. It decrements a series of * offer and consideration items, then generates a single execution * element. A given fulfillment can be applied to as many offer and * consideration items as desired, but must contain at least one offer and * at least one consideration that match. The fulfillment must also remain * consistent on all key parameters across all offer items (same offerer, * token, type, tokenId, and conduit preference) as well as across all * consideration items (token, type, tokenId, and recipient). */ struct Fulfillment { FulfillmentComponent[] offerComponents; FulfillmentComponent[] considerationComponents; } /** * @dev Each fulfillment component contains one index referencing a specific * order and another referencing a specific offer or consideration item. */ struct FulfillmentComponent { uint256 orderIndex; uint256 itemIndex; } /** * @dev An execution is triggered once all consideration items have been zeroed * out. It sends the item in question from the offerer to the item's * recipient, optionally sourcing approvals from either this contract * directly or from the offerer's chosen conduit if one is specified. An * execution is not provided as an argument, but rather is derived via * orders, criteria resolvers, and fulfillments (where the total number of * executions will be less than or equal to the total number of indicated * fulfillments) and returned as part of `matchOrders`. */ struct Execution { ReceivedItem item; address offerer; bytes32 conduitKey; } /** * @dev Restricted orders are validated post-execution by calling validateOrder * on the zone. This struct provides context about the order fulfillment * and any supplied extraData, as well as all order hashes fulfilled in a * call to a match or fulfillAvailable method. */ struct ZoneParameters { bytes32 orderHash; address fulfiller; address offerer; SpentItem[] offer; ReceivedItem[] consideration; bytes extraData; bytes32[] orderHashes; uint256 startTime; uint256 endTime; bytes32 zoneHash; } /** * @dev Zones and contract offerers can communicate which schemas they implement * along with any associated metadata related to each schema. */ struct Schema { uint256 id; bytes metadata; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; enum ListTypes { AuthorizerList, OperatorList } /// @title IAuthorizedTransferSecurityRegistry /// @dev Interface for the Authorized Transfer Security Registry, a simplified version of the Transfer /// Security Registry that only supports authorizers and whitelisted operators, and assumes a /// security level of OperatorWhitelistEnableOTC + authorizers for all collections that use it. /// Note that a number of view functions on collections that add this validator will not work. interface IAuthorizedTransferSecurityRegistry { event CreatedList(uint256 indexed id, string name); event AppliedListToCollection(address indexed collection, uint120 indexed id); event ReassignedListOwnership(uint256 indexed id, address indexed newOwner); event AddedAccountToList(ListTypes indexed kind, uint256 indexed id, address indexed account); event RemovedAccountFromList(ListTypes indexed kind, uint256 indexed id, address indexed account); error AuthorizedTransferSecurityRegistry__ListDoesNotExist(); error AuthorizedTransferSecurityRegistry__CallerDoesNotOwnList(); error AuthorizedTransferSecurityRegistry__ArrayLengthCannotBeZero(); error AuthorizedTransferSecurityRegistry__CallerMustHaveElevatedPermissionsForSpecifiedNFT(); error AuthorizedTransferSecurityRegistry__ListOwnershipCannotBeTransferredToZeroAddress(); error AuthorizedTransferSecurityRegistry__ZeroAddressNotAllowed(); error AuthorizedTransferSecurityRegistry__UnauthorizedTransfer(); error AuthorizedTransferSecurityRegistry__CallerIsNotValidAuthorizer(); /// Manage lists of authorizers & operators that can be applied to collections function createList(string calldata name) external returns (uint120); function createListCopy(string calldata name, uint120 sourceListId) external returns (uint120); function reassignOwnershipOfList(uint120 id, address newOwner) external; function renounceOwnershipOfList(uint120 id) external; function applyListToCollection(address collection, uint120 id) external; function listOwners(uint120 id) external view returns (address); /// Manage and query for authorizers on lists function addAuthorizers(uint120 id, address[] calldata accounts) external; function removeAuthorizers(uint120 id, address[] calldata accounts) external; function getAuthorizers(uint120 id) external view returns (address[] memory); function isAuthorizer(uint120 id, address account) external view returns (bool); function getAuthorizersByCollection(address collection) external view returns (address[] memory); function isAuthorizerByCollection( address collection, address account ) external view returns (bool); /// Manage and query for operators on lists function addOperators(uint120 id, address[] calldata accounts) external; function removeOperators(uint120 id, address[] calldata accounts) external; function getOperators(uint120 id) external view returns (address[] memory); function isOperator(uint120 id, address account) external view returns (bool); function getOperatorsByCollection(address collection) external view returns (address[] memory); function isOperatorByCollection(address collection, address account) external view returns (bool); /// Ensure that a specific operator has been authorized to transfer tokens function validateTransfer(address caller, address from, address to) external view; /// Ensure that a transfer has been authorized for a specific tokenId function validateTransfer( address caller, address from, address to, uint256 tokenId ) external view; /// Ensure that a transfer has been authorized for a specific amount of a specific tokenId, and /// reduce the transferable amount remaining function validateTransfer( address caller, address from, address to, uint256 tokenId, uint256 amount ) external; /// Legacy alias for validateTransfer (address caller, address from, address to) function applyCollectionTransferPolicy(address caller, address from, address to) external view; /// Temporarily assign a specific allowed operator for a given collection function beforeAuthorizedTransfer(address operator, address token) external; /// Clear assignment of a specific allowed operator for a given collection function afterAuthorizedTransfer(address token) external; /// Temporarily allow a specific tokenId from a given collection to be transferred function beforeAuthorizedTransfer(address token, uint256 tokenId) external; /// Clear assignment of an specific tokenId's transfer allowance function afterAuthorizedTransfer(address token, uint256 tokenId) external; /// Temporarily allow a specific amount of a specific tokenId from a given collection to be transferred function beforeAuthorizedTransferWithAmount( address token, uint256 tokenId, uint256 amount ) external; /// Clear assignment of a tokenId's transfer allowance for a specific amount function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @title SignedZoneControllerInterface * @author BCLeFevre * @notice SignedZoneControllerInterface enables the deploying of SignedZones. * SignedZones are an implementation of SIP-7 that requires orders * to be signed by an approved signer. * https://github.com/ProjectOpenSea/SIPs/blob/main/SIPS/sip-7.md * */ interface SignedZoneControllerInterface { /** * @notice Deploy a SignedZone to a precomputed address. * * @param zoneName The name for the zone returned in * getSeaportMetadata(). * @param apiEndpoint The API endpoint where orders for this zone can be * signed. * @param documentationURI The URI to the documentation describing the * behavior of the contract. * Request and response payloads are defined in SIP-7. * @param salt The salt to be used to derive the zone address * @param initialOwner The initial owner to set for the new zone. * * @return derivedAddress The derived address for the zone. */ function createZone( string memory zoneName, string memory apiEndpoint, string memory documentationURI, address initialOwner, bytes32 salt ) external returns (address derivedAddress); /** * @notice Returns the active signers for the zone. * * @param signedZone The signed zone to get the active signers for. * * @return signers The active signers. */ function getActiveSigners(address signedZone) external view returns (address[] memory signers); /** * @notice Returns additional information about the zone. * * @param zone The zone to get the additional information for. * * @return domainSeparator The domain separator used for signing. * @return zoneName The name of the zone. * @return apiEndpoint The API endpoint for the zone. * @return substandards The substandards supported by the zone. * @return documentationURI The documentation URI for the zone. */ function getAdditionalZoneInformation(address zone) external view returns ( bytes32 domainSeparator, string memory zoneName, string memory apiEndpoint, uint256[] memory substandards, string memory documentationURI ); /** * @notice Update the API endpoint returned by the supplied zone. * Only the owner or an active signer can call this function. * * @param signedZone The signed zone to update the API endpoint for. * @param newApiEndpoint The new API endpoint. */ function updateAPIEndpoint( address signedZone, string calldata newApiEndpoint ) external; /** * @notice Update the signer for a given signed zone. * * @param signedZone The signed zone to update the signer for. * @param signer The signer to update. * @param active If the signer should be active or not. */ function updateSigner( address signedZone, address signer, bool active ) external; /** * @notice Initiate zone ownership transfer by assigning a new potential * owner for the given zone. Once set, the new potential owner * may call `acceptOwnership` to claim ownership of the zone. * Only the owner of the zone in question may call this function. * * @param zone The zone for which to initiate ownership transfer. * @param newPotentialOwner The new potential owner of the zone. */ function transferOwnership(address zone, address newPotentialOwner) external; /** * @notice Clear the currently set potential owner, if any, from a zone. * Only the owner of the zone in question may call this function. * * @param zone The zone for which to cancel ownership transfer. */ function cancelOwnershipTransfer(address zone) external; /** * @notice Accept ownership of a supplied zone. Only accounts that the * current owner has set as the new potential owner may call this * function. * * @param zone The zone for which to accept ownership. */ function acceptOwnership(address zone) external; /** * @notice Retrieve the current owner of a deployed zone. * * @param zone The zone for which to retrieve the associated owner. * * @return owner The owner of the supplied zone. */ function ownerOf(address zone) external view returns (address owner); /** * @notice Retrieve the potential owner, if any, for a given zone. The * current owner may set a new potential owner via * `transferOwnership` and that owner may then accept ownership of * the zone in question via `acceptOwnership`. * * @param zone The zone for which to retrieve the potential owner. * * @return potentialOwner The potential owner, if any, for the zone. */ function getPotentialOwner(address zone) external view returns (address potentialOwner); /** * @notice Derive the zone address associated with a salt. * * @param salt The salt to be used to derive the zone address * * @return derivedAddress The derived address of the signed zone. */ function getZone(bytes32 salt) external view returns (address derivedAddress); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @notice SignedZoneV16RoyaltyEventsAndErrors contains errors and events * related to zone interaction. */ interface SignedZoneV16RoyaltyEventsAndErrors { /** * @dev Emit an event when a new signer is added. */ event SignerAdded(address signer); /** * @dev Emit an event when a signer is removed. */ event SignerRemoved(address signer); /** * @dev Revert with an error when the signature has expired. */ error SignatureExpired(uint256 expiration, bytes32 orderHash); /** * @dev Revert with an error when the caller is not seaport. */ error CallerNotSeaport(); /** * @dev Revert with an error when attempting to update the signers of a * the zone from a caller that is not the zone's controller. */ error InvalidController(); /** * @dev Revert with an error if supplied order extraData is an invalid * length. */ error InvalidExtraDataLength(bytes32 orderHash); /** * @dev Revert with an error if the supplied order extraData does not * support the zone's SIP6 version. */ error InvalidSIP6Version(bytes32 orderHash); /** * @dev Revert with an error if the supplied order extraData does not * support the zone's substandard requirements. */ error InvalidSubstandardSupport(string reason, uint256 substandardVersion, bytes32 orderHash); /** * @dev Revert with an error if the supplied order extraData does not * support the zone's substandard version. */ error InvalidSubstandardVersion(bytes32 orderHash); /** * @dev Revert with an error if the fulfiller does not match. */ error InvalidFulfiller(address expectedFulfiller, address actualFulfiller, bytes32 orderHash); /** * @dev Revert with an error if the received item does not match. */ error InvalidReceivedItem( uint256 expectedReceivedIdentifier, uint256 actualReceievedIdentifier, bytes32 orderHash ); /** * @dev Revert with an error if the zone parameter encoding is invalid. */ error InvalidZoneParameterEncoding(); /** * @dev Revert with an error when an order is signed with a signer * that is not active. */ error SignerNotActive(address signer, bytes32 orderHash); /** * @dev Revert when an unsupported function selector is found. */ error UnsupportedFunctionSelector(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { Schema } from "../../lib/ConsiderationStructs.sol"; /** * @dev SIP-5: Contract Metadata Interface for Seaport Contracts * https://github.com/ProjectOpenSea/SIPs/blob/main/SIPS/sip-5.md */ interface SIP5Interface { /** * @dev An event that is emitted when a SIP-5 compatible contract is deployed. */ event SeaportCompatibleContractDeployed(); /** * @dev Returns Seaport metadata for this contract, returning the * contract name and supported schemas. * * @return name The contract name * @return schemas The supported SIPs */ function getSeaportMetadata() external view returns (string memory name, Schema[] memory schemas); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /// @dev ECDSA signature offsets. uint256 constant ECDSA_MaxLength = 65; uint256 constant ECDSA_signature_s_offset = 0x40; uint256 constant ECDSA_signature_v_offset = 0x60; /// @dev Helpers for memory offsets. uint256 constant OneWord = 0x20; uint256 constant TwoWords = 0x40; uint256 constant ThreeWords = 0x60; uint256 constant FourWords = 0x80; uint256 constant FiveWords = 0xa0; uint256 constant Signature_lower_v = 27; uint256 constant MaxUint8 = 0xff; bytes32 constant EIP2098_allButHighestBitMask = ( 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ); uint256 constant Ecrecover_precompile = 1; uint256 constant Ecrecover_args_size = 0x80; uint256 constant FreeMemoryPointerSlot = 0x40; uint256 constant ZeroSlot = 0x60; uint256 constant Slot0x80 = 0x80; /// @dev The EIP-712 digest offsets. uint256 constant EIP712_DomainSeparator_offset = 0x02; uint256 constant EIP712_SignedOrderHash_offset = 0x22; uint256 constant EIP712_DigestPayload_size = 0x42; uint256 constant EIP_712_PREFIX = ( 0x1901000000000000000000000000000000000000000000000000000000000000 ); // @dev Function selectors used in the fallback function.. bytes4 constant UPDATE_SIGNER_SELECTOR = 0xf460590b; bytes4 constant GET_ACTIVE_SIGNERS_SELECTOR = 0xa784b80c; bytes4 constant IS_ACTIVE_SIGNER_SELECTOR = 0x7dff5a79; bytes4 constant SUPPORTS_INTERFACE_SELECTOR = 0x01ffc9a7; /* * error InvalidController() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidController_error_selector = 0x6d5769be; uint256 constant InvalidController_error_length = 0x04; /* * error InvalidFulfiller(address expectedFulfiller, address actualFulfiller, bytes32 orderHash) * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: expectedFulfiller * - 0x40: actualFullfiller * - 0x60: orderHash * Revert buffer is memory[0x1c:0x80] */ uint256 constant InvalidFulfiller_error_selector = 0x1bcf9bb7; uint256 constant InvalidFulfiller_error_expectedFulfiller_ptr = 0x20; uint256 constant InvalidFulfiller_error_actualFulfiller_ptr = 0x40; uint256 constant InvalidFulfiller_error_orderHash_ptr = 0x60; uint256 constant InvalidFulfiller_error_length = 0x64; /* * error InvalidReceivedItem(uint256 expectedReceivedIdentifier, uint256 actualReceievedIdentifier, bytes32 orderHash) * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: expectedReceivedIdentifier * - 0x40: actualReceievedIdentifier * - 0x60: orderHash * Revert buffer is memory[0x1c:0x80] */ uint256 constant InvalidReceivedItem_error_selector = 0xb36c03e8; uint256 constant InvalidReceivedItem_error_expectedReceivedItem_ptr = 0x20; uint256 constant InvalidReceivedItem_error_actualReceivedItem_ptr = 0x40; uint256 constant InvalidReceivedItem_error_orderHash_ptr = 0x60; uint256 constant InvalidReceivedItem_error_length = 0x64; /* * error InvalidZoneParameterEncoding() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant InvalidZoneParameterEncoding_error_selector = 0x46d5d895; uint256 constant InvalidZoneParameterEncoding_error_length = 0x04; /* * error InvalidExtraDataLength() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidExtraDataLength_error_selector = 0xd232fd2c; uint256 constant InvalidExtraDataLength_error_orderHash_ptr = 0x20; uint256 constant InvalidExtraDataLength_error_length = 0x24; uint256 constant InvalidExtraDataLength_expected_length_substandard_1 = 0x7e; // 126 uint256 constant InvalidExtraDataLength_expected_length_substandard_7 = 0xa6; // 166 uint256 constant InvalidExtraDataLength_expected_length_substandard_8_or_9 = 0x92; // 146 uint256 constant ExtraData_expiration_offset = 0x35; uint256 constant ExtraData_substandard_version_byte_offset = 0x7d; /* * error InvalidSIP6Version() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidSIP6Version_error_selector = 0x64115774; uint256 constant InvalidSIP6Version_error_orderHash_ptr = 0x20; uint256 constant InvalidSIP6Version_error_length = 0x24; /* * error InvalidSubstandardVersion() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: orderHash * Revert buffer is memory[0x1c:0x40] */ uint256 constant InvalidSubstandardVersion_error_selector = 0x26787999; uint256 constant InvalidSubstandardVersion_error_orderHash_ptr = 0x20; uint256 constant InvalidSubstandardVersion_error_length = 0x24; /* * error InvalidSubstandardSupport() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: reason * - 0x40: substandardVersion * - 0x60: orderHash * Revert buffer is memory[0x1c:0xe0] */ uint256 constant InvalidSubstandardSupport_error_selector = 0x2be76224; uint256 constant InvalidSubstandardSupport_error_reason_offset_ptr = 0x20; uint256 constant InvalidSubstandardSupport_error_substandard_version_ptr = 0x40; uint256 constant InvalidSubstandardSupport_error_orderHash_ptr = 0x60; uint256 constant InvalidSubstandardSupport_error_reason_length_ptr = 0x80; uint256 constant InvalidSubstandardSupport_error_reason_ptr = 0xa0; uint256 constant InvalidSubstandardSupport_error_reason_2_ptr = 0xc0; uint256 constant InvalidSubstandardSupport_error_length = 0xc4; /* * error SignatureExpired() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * - 0x20: expiration * - 0x40: orderHash * Revert buffer is memory[0x1c:0x60] */ uint256 constant SignatureExpired_error_selector = 0x16546071; uint256 constant SignatureExpired_error_expiration_ptr = 0x20; uint256 constant SignatureExpired_error_orderHash_ptr = 0x40; uint256 constant SignatureExpired_error_length = 0x44; /* * error UnsupportedFunctionSelector() * - Defined in SignedZoneEventsAndErrors.sol * Memory layout: * - 0x00: Left-padded selector (data begins at 0x1c) * Revert buffer is memory[0x1c:0x20] */ uint256 constant UnsupportedFunctionSelector_error_selector = 0x54c91b87; uint256 constant UnsupportedFunctionSelector_error_length = 0x04; // Zone parameter calldata pointers uint256 constant Zone_parameters_cdPtr = 0x04; uint256 constant Zone_parameters_fulfiller_cdPtr = 0x44; uint256 constant Zone_consideration_head_cdPtr = 0xa4; uint256 constant Zone_extraData_cdPtr = 0xc4; // Zone parameter memory pointers uint256 constant Zone_parameters_ptr = 0x20; // Zone parameter offsets uint256 constant Zone_parameters_offset = 0x24; uint256 constant expectedFulfiller_offset = 0x45; uint256 constant actualReceivedIdentifier_offset = 0x84; uint256 constant expectedReceivedIdentifier_offset = 0xa2; // Spent Item Size uint256 constant SpentItem_size = 0x80; // Received Item Size uint256 constant ReceivedItem_size = 0xa0;
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"zoneName","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotSeaport","type":"error"},{"inputs":[],"name":"InvalidController","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidExtraDataLength","type":"error"},{"inputs":[{"internalType":"address","name":"expectedFulfiller","type":"address"},{"internalType":"address","name":"actualFulfiller","type":"address"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidFulfiller","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedReceivedIdentifier","type":"uint256"},{"internalType":"uint256","name":"actualReceievedIdentifier","type":"uint256"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidReceivedItem","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidSIP6Version","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"},{"internalType":"uint256","name":"substandardVersion","type":"uint256"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidSubstandardSupport","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"InvalidSubstandardVersion","type":"error"},{"inputs":[],"name":"InvalidZoneParameterEncoding","type":"error"},{"inputs":[{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"SignatureExpired","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"SignerNotActive","type":"error"},{"inputs":[],"name":"UnsupportedFunctionSelector","type":"error"},{"anonymous":false,"inputs":[],"name":"SeaportCompatibleContractDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"SignerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"SignerRemoved","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"components":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"address","name":"fulfiller","type":"address"},{"internalType":"address","name":"offerer","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct SpentItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem[]","name":"consideration","type":"tuple[]"},{"internalType":"bytes","name":"extraData","type":"bytes"},{"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"}],"internalType":"struct ZoneParameters","name":"zoneParameters","type":"tuple"}],"name":"authorizeOrder","outputs":[{"internalType":"bytes4","name":"authorizedOrderMagicValue","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getSeaportMetadata","outputs":[{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"internalType":"struct Schema[]","name":"schemas","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"address","name":"fulfiller","type":"address"},{"internalType":"address","name":"offerer","type":"address"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct SpentItem[]","name":"offer","type":"tuple[]"},{"components":[{"internalType":"enum ItemType","name":"itemType","type":"uint8"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"identifier","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"internalType":"struct ReceivedItem[]","name":"consideration","type":"tuple[]"},{"internalType":"bytes","name":"extraData","type":"bytes"},{"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"bytes32","name":"zoneHash","type":"bytes32"}],"internalType":"struct ZoneParameters","name":"zoneParameters","type":"tuple"}],"name":"validateOrder","outputs":[{"internalType":"bytes4","name":"validOrderMagicValue","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
610180604052346200008f576200001f620000196200010c565b620001ef565b6040516114889081620004318239608051818181610e4701528181610f3401526110e6015260a05181611371015260c05181611395015260e0518161134e015261010051816111fc015261012051816112fb01526101405181611322015261016051818181607701526103640152f35b600080fd5b50634e487b7160e01b600052604160045260246000fd5b601f909101601f19168101906001600160401b03821190821017620000cf57604052565b620000d962000094565b604052565b6020906001600160401b038111620000fc575b601f01601f19160190565b6200010662000094565b620000f1565b620018b9908138038060405193620001258286620000ab565b8439820160209283818303126200008f578051906001600160401b0382116200008f57019281601f850112156200008f5783516200016381620000de565b92620001736040519485620000ab565b8184528282870101116200008f5760005b8181106200019a57508260009394955001015290565b858101830151848201840152820162000184565b60408051919082016001600160401b03811183821017620001df575b60405260038252620322e360ec1b6020830152565b620001e962000094565b620001ca565b620001f9620001ae565b6020815191012060c0526040516020810181620002c3620002b66200028d62000271620002566200023e87600d906c08a92a06e626488dedac2d2dc5609b1b81520190565b6b1cdd1c9a5b99c81b985b594b60a21b8152600c0190565b6e1cdd1c9a5b99c81d995c9cda5bdb8b608a1b8152600f0190565b6f1d5a5b9d0c8d4d8818da185a5b92590b60821b815260100190565b7f6164647265737320766572696679696e67436f6e747261637400000000000000815260190190565b602960f81b815260010190565b0391620002d9601f1993848101835282620000ab565b51902060e0526040516200039e60208201928262000391620002b6620003786200035a6200033c6200031e8a600c906b0a6d2cedccac89ee4c8cae4560a31b81520190565b711859191c995cdcc8199d5b199a5b1b195c8b60721b815260120190565b711d5a5b9d0d8d08195e1c1a5c985d1a5bdb8b60721b815260120190565b71189e5d195ccccc881bdc99195c92185cda0b60721b815260120190565b6c189e5d195cc818dbdb9d195e1d609a1b8152600d0190565b03908101835282620000ab565b5190206101005246610120526c68f116a894984e2db1123eb39561016052336080526020815191012060a0526200040560e0519060a0519160c0516040519360805192600052602052604052466060523060805260a0600020926040526000606052608052565b610140527f98a7ac23945182ac62b68fbe5ba35cc0bf5c4c34b3a410ce94a4c2270282d6b5600080a156fe60806040526004361015610028575b346100235761001b6106e0565b602081519101f35b600080fd5b6000803560e01c90816301e4d72a146100675750806317b1f9421461005e57632e778efc0361000e57610059610499565b61000e565b50610059610353565b3461031d5761007536610320565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361030c576100ad6113d0565b6100ba60a08201826107d9565b929082359360c43591602491607e84840135106102fc57604484013560f81c6102ec5760a184013560f81c9360078510600186111660098611176102dc579060598892013560c01c924284106102c75760a435850135156102725761011e836113ea565b946101298383610549565b9890976002811015610209575050509361018e9695936101809361015361015c946101889861057c565b929092936111db565b6101646112f6565b61190160f01b6000526002526022526042600020906000602252565b923691610837565b90611270565b6101bb6101b76101b08360018060a01b03166000526000602052604060002090565b5460ff1690565b1590565b6101dd576101c882610a2b565b60405162f26b9560e11b8152602090f35b0390f35b6040516317c3008960e01b81526001600160a01b03919091166004820152602481019290925250604490fd5b60079192939495501460001461024d5760a6841061023e5750506101889361018e969593896101536101809561015c9561056b565b63d232fd2c8a9152602052601cfd5b6092841061023e5750506101889361018e969593896101536101809561015c9561055a565b82632be76224885260606020526001604052606052602a6080527f436f6e73696465726174696f6e206d7573742068617665206174206c6561737460a052691037b7329034ba32b69760b11b60c05260c4601cfd5b8284631654607189526020526040526044601cfd5b838863267879998852602052601cfd5b828763641157748752602052601cfd5b828763d232fd2c8752602052601cfd5b6304bcd3dd60e51b60805260046080fd5b80fd5b60031990602081830112610023576004359167ffffffffffffffff83116100235782610140920301126100235760040190565b50346100235761036236610320565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036103ad5761039b90610c88565b604051630bd8fca160e11b8152602090f35b6040516304bcd3dd60e51b8152600490fd5b600091031261002357565b60005b8381106103dd5750506000910152565b81810151838201526020016103cd565b90602091610406815180928185528580860191016103ca565b601f01601f1916010190565b610424604092838352838301906103ed565b906020908181840391015283519182815281810182808560051b8401019601946000925b858410610459575050505050505090565b909192939495968580610488600193601f1986820301885286838d5180518452015191818582015201906103ed565b990194019401929594939190610448565b50346100235760008060031936011261031d5760408051916104ba83610625565b60018352805b6020808210156104ed578351602092916104d982610625565b8482526060818301528287010152016104c0565b846105316101d9866007610500856108ac565b515261052361050d6110bf565b90869894939895929551958694602086016108c6565b03601f198101835282610662565b602061053c866108ac565b5101525192839283610412565b90605d1161002357601d0190604090565b9060921161002357605d0190603590565b9060a61161002357605d0190604990565b90607e1161002357605d0190602190565b91909182600411610023578211610023576004916003190190565b91909182602411610023578211610023576024916023190190565b9060921161002357607e0190601490565b9060a6116100235760920190601490565b6001600160a01b0381160361002357565b90816020910312610023573561060b816105e5565b90565b50634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff82111761064157604052565b61064961060e565b604052565b67ffffffffffffffff811161064157604052565b90601f8019910116810190811067ffffffffffffffff82111761064157604052565b6020908160408183019282815285518094520193019160005b8281106106ab575050505090565b83516001600160a01b03168552938101939281019260010161069d565b90816020910312610023573580151581036100235790565b6060906000356001600160e01b03191663f460590b60e01b8103610743575061074161072661071a610712363661058d565b8101906105f6565b6001600160a01b031690565b61073b61073336366105a8565b8101906106c8565b90610e44565b565b9091506329e12e0360e21b8103610772575061052361060b610763610f18565b60405192839160208301610684565b637dff5a7960e01b036107cb5761052361060b6107b661079861071a610712363661058d565b6001600160a01b031660009081526020819052604090205460ff1690565b60408051911515602083015290928391820190565b6354c91b876000526004601cfd5b903590601e1981360301821215610023570180359067ffffffffffffffff82116100235760200191813603831361002357565b60209067ffffffffffffffff811161082a575b601f01601f19160190565b61083261060e565b61081f565b9291926108438261080c565b916108516040519384610662565b829481845281830111610023578281602093846000960137010152565b60209067ffffffffffffffff8111610888575b60051b0190565b61089061060e565b610881565b50634e487b7160e01b600052603260045260246000fd5b6020908051156108ba570190565b6108c2610895565b0190565b909493919481526108e360209560808784015260808301906103ed565b818103604083015285808551928381520194019060005b8181106109175750505061060b93945060608184039101526103ed565b8251865294870194918701916001016108fa565b605d918210156108ba570190565b6bffffffffffffffffffffffff19903581811693926014811061095b57505050565b60140360031b82901b16169150565b903590601e1981360301821215610023570180359067ffffffffffffffff8211610023576020019160a082023603831361002357565b90156109a95790565b61060b610895565b600611156109bb57565b634e487b7160e01b600052602160045260246000fd5b3560068110156100235790565b903590601e1981360301821215610023570180359067ffffffffffffffff821161002357602001918160071b3603831361002357565b3561060b816105e5565b506040513d6000823e3d90fd5b60a081019060ff610a5f610a59610a4b610a4586866107d9565b9061092b565b356001600160f81b03191690565b60f81c90565b169160028310610c8357610a8e610a88610a82610a7c84866107d9565b906105c3565b90610939565b60601c90565b91608081016001610ab0610aab610aa5848661096a565b906109a0565b6109d1565b610ab9816109b1565b1115610c4357610ad76020610ad1610aa5848661096a565b01610a14565b946060610af8610aa56040610aef610aa5878961096a565b0135948661096a565b0135905b60078103610b9757505050610a82610b1a610b2093610a88936107d9565b906105d4565b6001600160a01b0390911691823b1561002357604051635079331560e01b81526001600160a01b03928316600482015291166024820152906000908290818381604481015b03925af18015610b8a575b610b775750565b80610b846107419261064e565b806103bf565b610b92610a1e565b610b70565b91959493509150600803610beb57506001600160a01b031691823b15610023576040516301d0718b60e51b81526001600160a01b039092166004830152602482015290600090829081838160448101610b65565b906001600160a01b0316803b15610023576040516328cc113160e01b81526001600160a01b0393909316600484015260248301939093526044820152906000908290606490829084905af18015610b8a57610b775750565b5060608101610c5a6020610ad1610aa584866109de565b946060610c7b610aa56040610c72610aa587896109de565b013594866109de565b013590610afc565b505050565b60a081019060ff610ca2610a59610a4b610a4586866107d9565b169160028310610c8357610cbf610a88610a82610a7c84866107d9565b91608081016001610cd6610aab610aa5848661096a565b610cdf816109b1565b1115610e0857610cf76020610ad1610aa5848661096a565b94610d16610aa56040610d0d610aa5868861096a565b0135938561096a565b505b60078103610d6f575050610d2f91610b1a916107d9565b50506001600160a01b0316803b1561002357604051630ad3889960e01b81526001600160a01b039092166004830152600090829081838160248101610b65565b9094939250600814159050610dc3576001600160a01b031691823b156100235760405163b89c4b0d60e01b81526001600160a01b039092166004830152602482015290600090829081838160448101610b65565b6001600160a01b031691823b156100235760405163b6e39ba160e01b81526001600160a01b039092166004830152602482015290600090829081838160448101610b65565b5060608101610e1f6020610ad1610aa584866109de565b94610e3e610aa56040610e35610aa586886109de565b013593856109de565b50610d18565b907f00000000000000000000000000000000000000000000000000000000000000003303610f0a5715610ebf576001600160a01b031660008181526020818152604091829020805460ff1916600117905590519182527f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f2491a1565b6001600160a01b031660008181526020818152604091829020805460ff1916905590519182527f3525e22824a8a7df2c9a6029941c824cf95b6447f1e13d5128fd3826d35afe8b91a1565b636d5769be6000526004601cfd5b6040516366a2489f60e01b8152306004820152600080826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa918215611012575b8192610f7157505090565b9091503d8083833e610f838183610662565b8101602091828183031261100a5780519067ffffffffffffffff821161100e570181601f8201121561100a57805190610fbb8261086e565b94610fc96040519687610662565b828652848087019360051b83010193841161031d57508301905b828210610ff1575050505090565b8380918351610fff816105e5565b815201910190610fe3565b8380fd5b8480fd5b61101a610a1e565b610f66565b81601f820112156100235780516110358161080c565b926110436040519485610662565b818452602082840101116100235761060b91602080850191016103ca565b81601f82011215610023578051916110788361086e565b926110866040519485610662565b808452602092838086019260051b820101928311610023578301905b8282106110b0575050505090565b815181529083019083016110a2565b6110c76112f6565b604051628f139360e31b815230600482015290919060009081816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9182156111ce575b8092819282809261112c575b505090919293565b9350935050503d8082843e6111418184610662565b820160a0838203126111ca5760208301519067ffffffffffffffff9182811161100a578161117091860161101f565b91604085015181811161100e578261118991870161101f565b9460608101518281116111c657836111a2918301611061565b94608082015192831161031d57506111bb92910161101f565b909291903880611124565b8580fd5b5080fd5b6111d6610a1e565b611118565b93926111ea9192933691610837565b602081519101206040519260208401947f0000000000000000000000000000000000000000000000000000000000000000865260018060a01b0316604085015267ffffffffffffffff8093166060850152608084015260a083015260a0825260c082019082821090821117611263575b60405251902090565b61126b61060e565b61125a565b9190916000926000918280528151601f1983019283518260410394600186111561129e575b50505050505050565b90919293949596975060408301948551966060850151891a906112dc575b8452815260208760808360015afa50525252519038808080808080611295565b506001600160ff1b038716865260ff87901c601b016112bc565b6000467f00000000000000000000000000000000000000000000000000000000000000000361134457507f000000000000000000000000000000000000000000000000000000000000000090565b60405190608051907f000000000000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006020527f0000000000000000000000000000000000000000000000000000000000000000604052466060523060805260a081209260405260605260805290565b6020600435036113dc57565b6346d5d8956000526004601cfd5b906044359160c435806045013560601c9360a435608401359160a20135908086141586151516611438575081810361142157505050565b63b36c03e86000526020526040526060526064601cfd5b839086631bcf9bb76000526020526040526060526064601cfdfea26469706673582212203fc511b7c1ba46250e07db13f3f1c82c4236ab39a74023885f681960425a7e3d64736f6c6343000811003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000012526f79616c7479456e666f7263656d656e740000000000000000000000000000
Deployed Bytecode
0x60806040526004361015610028575b346100235761001b6106e0565b602081519101f35b600080fd5b6000803560e01c90816301e4d72a146100675750806317b1f9421461005e57632e778efc0361000e57610059610499565b61000e565b50610059610353565b3461031d5761007536610320565b7f0000000000000000000000000000000000000068f116a894984e2db1123eb3956001600160a01b0316330361030c576100ad6113d0565b6100ba60a08201826107d9565b929082359360c43591602491607e84840135106102fc57604484013560f81c6102ec5760a184013560f81c9360078510600186111660098611176102dc579060598892013560c01c924284106102c75760a435850135156102725761011e836113ea565b946101298383610549565b9890976002811015610209575050509361018e9695936101809361015361015c946101889861057c565b929092936111db565b6101646112f6565b61190160f01b6000526002526022526042600020906000602252565b923691610837565b90611270565b6101bb6101b76101b08360018060a01b03166000526000602052604060002090565b5460ff1690565b1590565b6101dd576101c882610a2b565b60405162f26b9560e11b8152602090f35b0390f35b6040516317c3008960e01b81526001600160a01b03919091166004820152602481019290925250604490fd5b60079192939495501460001461024d5760a6841061023e5750506101889361018e969593896101536101809561015c9561056b565b63d232fd2c8a9152602052601cfd5b6092841061023e5750506101889361018e969593896101536101809561015c9561055a565b82632be76224885260606020526001604052606052602a6080527f436f6e73696465726174696f6e206d7573742068617665206174206c6561737460a052691037b7329034ba32b69760b11b60c05260c4601cfd5b8284631654607189526020526040526044601cfd5b838863267879998852602052601cfd5b828763641157748752602052601cfd5b828763d232fd2c8752602052601cfd5b6304bcd3dd60e51b60805260046080fd5b80fd5b60031990602081830112610023576004359167ffffffffffffffff83116100235782610140920301126100235760040190565b50346100235761036236610320565b7f0000000000000000000000000000000000000068f116a894984e2db1123eb3956001600160a01b031633036103ad5761039b90610c88565b604051630bd8fca160e11b8152602090f35b6040516304bcd3dd60e51b8152600490fd5b600091031261002357565b60005b8381106103dd5750506000910152565b81810151838201526020016103cd565b90602091610406815180928185528580860191016103ca565b601f01601f1916010190565b610424604092838352838301906103ed565b906020908181840391015283519182815281810182808560051b8401019601946000925b858410610459575050505050505090565b909192939495968580610488600193601f1986820301885286838d5180518452015191818582015201906103ed565b990194019401929594939190610448565b50346100235760008060031936011261031d5760408051916104ba83610625565b60018352805b6020808210156104ed578351602092916104d982610625565b8482526060818301528287010152016104c0565b846105316101d9866007610500856108ac565b515261052361050d6110bf565b90869894939895929551958694602086016108c6565b03601f198101835282610662565b602061053c866108ac565b5101525192839283610412565b90605d1161002357601d0190604090565b9060921161002357605d0190603590565b9060a61161002357605d0190604990565b90607e1161002357605d0190602190565b91909182600411610023578211610023576004916003190190565b91909182602411610023578211610023576024916023190190565b9060921161002357607e0190601490565b9060a6116100235760920190601490565b6001600160a01b0381160361002357565b90816020910312610023573561060b816105e5565b90565b50634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff82111761064157604052565b61064961060e565b604052565b67ffffffffffffffff811161064157604052565b90601f8019910116810190811067ffffffffffffffff82111761064157604052565b6020908160408183019282815285518094520193019160005b8281106106ab575050505090565b83516001600160a01b03168552938101939281019260010161069d565b90816020910312610023573580151581036100235790565b6060906000356001600160e01b03191663f460590b60e01b8103610743575061074161072661071a610712363661058d565b8101906105f6565b6001600160a01b031690565b61073b61073336366105a8565b8101906106c8565b90610e44565b565b9091506329e12e0360e21b8103610772575061052361060b610763610f18565b60405192839160208301610684565b637dff5a7960e01b036107cb5761052361060b6107b661079861071a610712363661058d565b6001600160a01b031660009081526020819052604090205460ff1690565b60408051911515602083015290928391820190565b6354c91b876000526004601cfd5b903590601e1981360301821215610023570180359067ffffffffffffffff82116100235760200191813603831361002357565b60209067ffffffffffffffff811161082a575b601f01601f19160190565b61083261060e565b61081f565b9291926108438261080c565b916108516040519384610662565b829481845281830111610023578281602093846000960137010152565b60209067ffffffffffffffff8111610888575b60051b0190565b61089061060e565b610881565b50634e487b7160e01b600052603260045260246000fd5b6020908051156108ba570190565b6108c2610895565b0190565b909493919481526108e360209560808784015260808301906103ed565b818103604083015285808551928381520194019060005b8181106109175750505061060b93945060608184039101526103ed565b8251865294870194918701916001016108fa565b605d918210156108ba570190565b6bffffffffffffffffffffffff19903581811693926014811061095b57505050565b60140360031b82901b16169150565b903590601e1981360301821215610023570180359067ffffffffffffffff8211610023576020019160a082023603831361002357565b90156109a95790565b61060b610895565b600611156109bb57565b634e487b7160e01b600052602160045260246000fd5b3560068110156100235790565b903590601e1981360301821215610023570180359067ffffffffffffffff821161002357602001918160071b3603831361002357565b3561060b816105e5565b506040513d6000823e3d90fd5b60a081019060ff610a5f610a59610a4b610a4586866107d9565b9061092b565b356001600160f81b03191690565b60f81c90565b169160028310610c8357610a8e610a88610a82610a7c84866107d9565b906105c3565b90610939565b60601c90565b91608081016001610ab0610aab610aa5848661096a565b906109a0565b6109d1565b610ab9816109b1565b1115610c4357610ad76020610ad1610aa5848661096a565b01610a14565b946060610af8610aa56040610aef610aa5878961096a565b0135948661096a565b0135905b60078103610b9757505050610a82610b1a610b2093610a88936107d9565b906105d4565b6001600160a01b0390911691823b1561002357604051635079331560e01b81526001600160a01b03928316600482015291166024820152906000908290818381604481015b03925af18015610b8a575b610b775750565b80610b846107419261064e565b806103bf565b610b92610a1e565b610b70565b91959493509150600803610beb57506001600160a01b031691823b15610023576040516301d0718b60e51b81526001600160a01b039092166004830152602482015290600090829081838160448101610b65565b906001600160a01b0316803b15610023576040516328cc113160e01b81526001600160a01b0393909316600484015260248301939093526044820152906000908290606490829084905af18015610b8a57610b775750565b5060608101610c5a6020610ad1610aa584866109de565b946060610c7b610aa56040610c72610aa587896109de565b013594866109de565b013590610afc565b505050565b60a081019060ff610ca2610a59610a4b610a4586866107d9565b169160028310610c8357610cbf610a88610a82610a7c84866107d9565b91608081016001610cd6610aab610aa5848661096a565b610cdf816109b1565b1115610e0857610cf76020610ad1610aa5848661096a565b94610d16610aa56040610d0d610aa5868861096a565b0135938561096a565b505b60078103610d6f575050610d2f91610b1a916107d9565b50506001600160a01b0316803b1561002357604051630ad3889960e01b81526001600160a01b039092166004830152600090829081838160248101610b65565b9094939250600814159050610dc3576001600160a01b031691823b156100235760405163b89c4b0d60e01b81526001600160a01b039092166004830152602482015290600090829081838160448101610b65565b6001600160a01b031691823b156100235760405163b6e39ba160e01b81526001600160a01b039092166004830152602482015290600090829081838160448101610b65565b5060608101610e1f6020610ad1610aa584866109de565b94610e3e610aa56040610e35610aa586886109de565b013593856109de565b50610d18565b907f0000000000000000000000008001507b20bfa9408c0902b75a103129ed6703203303610f0a5715610ebf576001600160a01b031660008181526020818152604091829020805460ff1916600117905590519182527f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f2491a1565b6001600160a01b031660008181526020818152604091829020805460ff1916905590519182527f3525e22824a8a7df2c9a6029941c824cf95b6447f1e13d5128fd3826d35afe8b91a1565b636d5769be6000526004601cfd5b6040516366a2489f60e01b8152306004820152600080826024817f0000000000000000000000008001507b20bfa9408c0902b75a103129ed6703206001600160a01b03165afa918215611012575b8192610f7157505090565b9091503d8083833e610f838183610662565b8101602091828183031261100a5780519067ffffffffffffffff821161100e570181601f8201121561100a57805190610fbb8261086e565b94610fc96040519687610662565b828652848087019360051b83010193841161031d57508301905b828210610ff1575050505090565b8380918351610fff816105e5565b815201910190610fe3565b8380fd5b8480fd5b61101a610a1e565b610f66565b81601f820112156100235780516110358161080c565b926110436040519485610662565b818452602082840101116100235761060b91602080850191016103ca565b81601f82011215610023578051916110788361086e565b926110866040519485610662565b808452602092838086019260051b820101928311610023578301905b8282106110b0575050505090565b815181529083019083016110a2565b6110c76112f6565b604051628f139360e31b815230600482015290919060009081816024817f0000000000000000000000008001507b20bfa9408c0902b75a103129ed6703206001600160a01b03165afa9182156111ce575b8092819282809261112c575b505090919293565b9350935050503d8082843e6111418184610662565b820160a0838203126111ca5760208301519067ffffffffffffffff9182811161100a578161117091860161101f565b91604085015181811161100e578261118991870161101f565b9460608101518281116111c657836111a2918301611061565b94608082015192831161031d57506111bb92910161101f565b909291903880611124565b8580fd5b5080fd5b6111d6610a1e565b611118565b93926111ea9192933691610837565b602081519101206040519260208401947f58d1345cbd7d0ceb38b86441d42a4086bc412b7f1ed7d947a569ed7d68b1b790865260018060a01b0316604085015267ffffffffffffffff8093166060850152608084015260a083015260a0825260c082019082821090821117611263575b60405251902090565b61126b61060e565b61125a565b9190916000926000918280528151601f1983019283518260410394600186111561129e575b50505050505050565b90919293949596975060408301948551966060850151891a906112dc575b8452815260208760808360015afa50525252519038808080808080611295565b506001600160ff1b038716865260ff87901c601b016112bc565b6000467f00000000000000000000000000000000000000000000000000000000000081730361134457507f9f01268e78945b80c2fd71b7b27f9801018fb4f934a157fa947922a172a7f36190565b60405190608051907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527f970c5baece800861db26e88cd0a8a8ae7669d63d9b73f2dfafea8cb3551451b16020527f88f72b566ae0c96f6fffac4bc8ac74909f61512ac0c06a8124d5ed420d306f90604052466060523060805260a081209260405260605260805290565b6020600435036113dc57565b6346d5d8956000526004601cfd5b906044359160c435806045013560601c9360a435608401359160a20135908086141586151516611438575081810361142157505050565b63b36c03e86000526020526040526060526064601cfd5b839086631bcf9bb76000526020526040526060526064601cfdfea26469706673582212203fc511b7c1ba46250e07db13f3f1c82c4236ab39a74023885f681960425a7e3d64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000012526f79616c7479456e666f7263656d656e740000000000000000000000000000
-----Decoded View---------------
Arg [0] : zoneName (string): RoyaltyEnforcement
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [2] : 526f79616c7479456e666f7263656d656e740000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.