diff --git a/signed-zone/SignedZone.sol b/signed-zone/SignedZone.sol deleted file mode 100644 index 0d5beb4..0000000 --- a/signed-zone/SignedZone.sol +++ /dev/null @@ -1,743 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {ZoneParameters, Schema} from "seaport-types/lib/ConsiderationStructs.sol"; - -import {ZoneInterface} from "seaport-types/interfaces/ZoneInterface.sol"; - -import {SignedZoneEventsAndErrors} from "./interfaces/SignedZoneEventsAndErrors.sol"; - -import {ISIP5} from "shipyard-core/interfaces/sips/ISIP5.sol"; -import {IERC165} from "forge-std/interfaces/IERC165.sol"; - -import {SignedZoneControllerInterface} from "./interfaces/SignedZoneControllerInterface.sol"; - -import "./lib/SignedZoneConstants.sol"; - -/** - * @title SignedZone - * @author ryanio, BCLeFevre - * @notice SignedZone 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 SignedZone is SignedZoneEventsAndErrors, ZoneInterface, ISIP5 { - /// @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("1.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; - - /** - * @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 payable 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 == SUPPORTS_INTERFACE_SELECTOR) { - // abi.encodeWithSignature("supportsInterface(bytes4)", interfaceId) - - // Get the interface ID. - bytes4 interfaceId = abi.decode(msg.data[4:], (bytes4)); - - // Call the internal function to determine if the interface is - // supported. - return abi.encode(_supportsInterface(interfaceId)); - } 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 validOrderMagicValue A magic value indicating if the order is - * currently valid. - */ - function validateOrder(ZoneParameters calldata zoneParameters) - external - view - override - returns (bytes4 validOrderMagicValue) - { - // 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; - - // 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 iszero(eq(extraDataLength, InvalidExtraDataLength_epected_length)) { - // 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) - let subStandardVersionByte := - shr(248, calldataload(add(extraDataPtr, ExtraData_substandard_version_byte_offset))) - - // Validate the substandard version byte. - if iszero(eq(subStandardVersionByte, 0x00)) { - // 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) - } - } - - // extraData bytes 29-93: signature - // (strictly requires 64 byte compact sig, EIP-2098) - bytes calldata signature = extraData[29:93]; - - // extraData bytes 93-end: context (optional, variable length) - bytes calldata context = extraData[93:]; - - // Check the validity of the Substandard #1 extraData and get the - // expected fulfiller address. - address expectedFulfiller = (_assertValidSubstandardAndGetExpectedFulfiller(orderHash)); - - // 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); - } - // Return the selector of validateOrder as the magic value. - validOrderMagicValue = ZoneInterface.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(ISIP5, ZoneInterface) - 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); - } - - /** - * @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]; - } - - function supportsInterface(bytes4 interfaceId) external view override(IERC165, ZoneInterface) returns (bool) { - // Return whether the interface is supported. - return _supportsInterface(interfaceId); - } - - /** - * @notice Returns whether the interface is supported. - * - * @param interfaceId The interface id to check against. - */ - function _supportsInterface(bytes4 interfaceId) internal pure returns (bool _supports) { - // Determine if the interface is supported. - _supports = interfaceId == type(ISIP5).interfaceId // SIP-5 - || interfaceId == type(ZoneInterface).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) - } - } - } -} diff --git a/signed-zone/SignedZoneCaptain.sol b/signed-zone/SignedZoneCaptain.sol deleted file mode 100644 index c187055..0000000 --- a/signed-zone/SignedZoneCaptain.sol +++ /dev/null @@ -1,377 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {SignedZoneCaptainInterface} from "./interfaces/SignedZoneCaptainInterface.sol"; - -import {SignedZoneControllerInterface} from "./interfaces/SignedZoneControllerInterface.sol"; - -import {SignedZoneCaptainEventsAndErrors} from "./interfaces/SignedZoneCaptainEventsAndErrors.sol"; - -import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; - -/** - * @title SignedZoneCaptain - * @author BCLeFevre - * @notice SignedZoneCaptain is a contract that owns signed zones and manages - * their active signers via two roles. The rotator role can update - * the active signers of a zone. The sanitizer role can remove all - * active signers of a zone controlled by the captain and clear the - * rotator role on the captain. - */ -abstract contract SignedZoneCaptain is Ownable, SignedZoneCaptainInterface, SignedZoneCaptainEventsAndErrors { - // The address of the signed zone controller. The signed zone controller - // manages signed zones. - SignedZoneControllerInterface private immutable _SIGNED_ZONE_CONTROLLER; - - // The address of the rotator. The rotator can manage the active signers of - // a zone controlled by this contract. - address private _rotator; - - // The address of the sanitizer. The sanitizer can remove all active - // signers of a zone controlled by the captain and clear the rotator role - // on the captain. - address private _sanitizer; - - /** - * @dev Initialize contract by setting the signed zone controller. - * - * @param signedZoneController The address of the signed zone controller. - */ - constructor(address signedZoneController) { - // Ensure that the contract is being deployed by an approved deployer. - _assertValidDeployer(); - - // Ensure that a contract is deployed to the given signed zone controller. - if (signedZoneController.code.length == 0) { - revert InvalidSignedZoneController(signedZoneController); - } - - // Set the signed zone controller. - _SIGNED_ZONE_CONTROLLER = SignedZoneControllerInterface(signedZoneController); - } - - /** - * @notice External initialization called by the deployer to set the owner, - * rotator and sanitizer, and create a signed zone with the given - * name, API endpoint, documentation URI. This function can only be - * called once, as there is a check to ensure that the current - * owner is address(0) before the initialization is performed, the - * owner must then be set to a non address(0) address during - * initialization and finally the owner cannot be set to address(0) - * after initialization. - * - * @param initialOwner The address to be set as the owner. - * @param initialRotator The address to be set as the rotator. - * @param initialSanitizer The address to be set as the sanitizer. - * @param zoneName The name of the zone being created. - * @param apiEndpoint The API endpoint of the zone being created. - * @param documentationURI The documentation URI of the zone being created. - * @param zoneSalt The salt to use when creating the zone. - */ - function initialize( - address initialOwner, - address initialRotator, - address initialSanitizer, - string memory zoneName, - string memory apiEndpoint, - string memory documentationURI, - bytes32 zoneSalt - ) external override { - // Ensure the origin is an approved deployer. - _assertValidDeployer(); - - // Call initialize. - _initialize(initialOwner, initialRotator, initialSanitizer, zoneName, apiEndpoint, documentationURI, zoneSalt); - } - - /** - * @notice Internal initialization function to set the owner, rotator, and - * sanitizer and create a new zone with the given name, API - * endpoint, documentation URI and the captain as the zone owner. - * - * @param initialOwner The address to be set as the owner. - * @param initialRotator The address to be set as the rotator. - * @param initialSanitizer The address to be set as the sanitizer. - * @param zoneName The name of the zone being created. - * @param apiEndpoint The API endpoint of the zone being created. - * @param documentationURI The documentation URI of the zone being created. - * @param zoneSalt The salt to use when creating the zone. - */ - function _initialize( - address initialOwner, - address initialRotator, - address initialSanitizer, - string memory zoneName, - string memory apiEndpoint, - string memory documentationURI, - bytes32 zoneSalt - ) internal { - // Set the owner of the captain. - _transferOwnership(initialOwner); - - // Set the rotator. - _setRotator(initialRotator); - - // Set the sanitizer. - _setSanitizer(initialSanitizer); - - // Create a new zone, with the captain as the zone owner, the given - // zone name, API endpoint, and documentation URI. - SignedZoneControllerInterface(_SIGNED_ZONE_CONTROLLER).createZone( - zoneName, apiEndpoint, documentationURI, address(this), zoneSalt - ); - } - - /** - * @notice Update the API endpoint returned by the supplied zone. - * Only the owner can call this function. - * - * @param zone The signed zone to update the API endpoint for. - * @param newApiEndpoint The new API endpoint. - */ - function updateZoneAPIEndpoint(address zone, string calldata newApiEndpoint) external override { - // Ensure caller is the owner. - _assertCallerIsOwner(); - - // Call to the signed zone controller to update the zone API endpoint. - _SIGNED_ZONE_CONTROLLER.updateAPIEndpoint(zone, newApiEndpoint); - } - - /** - * @notice Update the documentationURI returned by a zone. Only the owner - * of the supplied zone can call this function. - * - * @param zone The signed zone to update the API endpoint - * for. - * @param newDocumentationURI The new documentation URI. - */ - function updateZoneDocumentationURI(address zone, string calldata newDocumentationURI) external override { - // Ensure caller is the owner. - _assertCallerIsOwner(); - - // Call to the signed zone controller to update the zone documentation - // URI. - _SIGNED_ZONE_CONTROLLER.updateDocumentationURI(zone, newDocumentationURI); - } - - /** - * @notice Update the signer for a given signed zone. - * - * @param zone 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 updateZoneSigner(address zone, address signer, bool active) external override { - // Ensure caller is the owner. - _assertCallerIsOwner(); - - // Call to the signed zone controller to update the zone signer. - _SIGNED_ZONE_CONTROLLER.updateSigner(zone, signer, active); - } - - /** - * @notice Update the rotator role on the captain. - * - * @param newRotator The new rotator of the captain. - */ - function updateRotator(address newRotator) external override { - // Ensure caller is owner. - _assertCallerIsOwner(); - - // Set the new rotator. - _setRotator(newRotator); - } - - /** - * @notice Update the sanitizer role on the captain. - * - * @param newSanitizer The new sanitizer of the captain. - */ - function updateSanitizer(address newSanitizer) external override { - // Ensure caller is owner. - _assertCallerIsOwner(); - - // Set the new sanitizer. - _setSanitizer(newSanitizer); - } - - /** - * @notice Initiate zone ownership transfer by assigning a new potential - * owner for the given zone. Only callable by the owner. - * - * @param zone The zone for which to initiate ownership - * transfer. - * @param newPotentialOwner The new potential owner to set. - */ - function transferZoneOwnership(address zone, address newPotentialOwner) external override { - // Ensure caller is the owner. - _assertCallerIsOwner(); - - // Call to the signed zone controller to transfer the zone ownership. - _SIGNED_ZONE_CONTROLLER.transferOwnership(zone, newPotentialOwner); - } - - /** - * @notice Clear the currently set potential owner, if any, from a zone. - * Only callable by the owner. - * - * @param zone The zone for which to cancel ownership transfer. - */ - function cancelZoneOwnershipTransfer(address zone) external override { - // Ensure caller is the owner. - _assertCallerIsOwner(); - - // Call to the signed zone controller to cancel the zone ownership - // transfer. - _SIGNED_ZONE_CONTROLLER.cancelOwnershipTransfer(zone); - } - - /** - * @notice Accept ownership of a given zone once the address has been set - * as the current potential owner. Only callable by the owner. - * - * @param zone The zone for which to accept ownership transfer. - */ - function acceptZoneOwnership(address zone) external override { - // Call to the signed zone controller to accept the zone ownership. - _SIGNED_ZONE_CONTROLLER.acceptOwnership(zone); - } - - /** - * @notice Rotate the signers for a given zone. Only callable by the owner - * or the rotator of the zone. - * - * @param zone The zone to rotate the signers for. - * @param signerToRemove The signer to remove. - * @param signerToAdd The signer to add. - */ - function rotateSigners(address zone, address signerToRemove, address signerToAdd) external override { - // Ensure caller is the owner or the rotator. - _assertCallerIsOwnerOrRotator(); - - // Call to the signed zone controller to remove the signer. - _SIGNED_ZONE_CONTROLLER.updateSigner(zone, signerToRemove, false); - - // Call to the signed zone controller to add the signer. - _SIGNED_ZONE_CONTROLLER.updateSigner(zone, signerToAdd, true); - } - - /** - * @notice This will remove all active signers of the given zone and clear - * the rotator address on the captain. Only callable by the owner - * or the sanitizer of the zone. - * - * @param zone The zone to revoke. - */ - function sanitizeSignedZone(address zone) external override { - // Ensure caller is the owner or the sanitizer. - _assertCallerIsOwnerOrSanitizer(); - - // Call to the signed zone controller to sanitize the signed zone. - address[] memory signers = _SIGNED_ZONE_CONTROLLER.getActiveSigners(zone); - - // Loop through the signers and deactivate them. - for (uint256 i = 0; i < signers.length; i++) { - _SIGNED_ZONE_CONTROLLER.updateSigner(zone, signers[i], false); - } - - // Clear the rotator role. - delete _rotator; - - // Emit the sanitized event. - emit ZoneSanitized(zone); - } - - /** - * @notice Get the rotator address. - * - * @return The rotator address. - */ - function getRotator() external view override returns (address) { - return _rotator; - } - - /** - * @notice Get the sanitizer address. - * - * @return The sanitizer address. - */ - function getSanitizer() external view override returns (address) { - return _sanitizer; - } - - /** - * @notice Internal function to set the rotator role on the contract, - * checking to make sure the provided address is not the null - * address - * - * @param newRotator The new rotator address. - */ - function _setRotator(address newRotator) internal { - // Ensure new rotator is not null. - if (newRotator == address(0)) { - revert RotatorCannotBeNullAddress(); - } - - _rotator = newRotator; - - emit RotatorUpdated(newRotator); - } - - /** - * @notice Internal function to set the sanitizer role on the contract, - * checking to make sure the provided address is not the null - * address - * - * @param newSanitizer The new sanitizer address. - */ - function _setSanitizer(address newSanitizer) internal { - // Ensure new sanitizer is not null. - if (newSanitizer == address(0)) { - revert SanitizerCannotBeNullAddress(); - } - - _sanitizer = newSanitizer; - - emit SanitizerUpdated(newSanitizer); - } - - function _assertCallerIsOwner() internal view virtual { - // Ensure caller is the owner. - if (msg.sender != owner()) { - revert CallerIsNotOwner(); - } - } - - /** - * @notice Internal function to assert that the caller is a valid deployer. - * This must be overwritten by the contract that inherits from this - * contract. This is to ensure that the caller or tx.orign is - * permitted to deploy this contract. - */ - function _assertValidDeployer() internal view virtual { - revert("Not implemented assertValidDeployer"); - } - - /** - * @dev Internal view function to revert if the caller is not the owner or - * the sanitizer. - */ - function _assertCallerIsOwnerOrSanitizer() internal view { - // Ensure caller is the owner or the sanitizer. - if (msg.sender != owner() && msg.sender != _sanitizer) { - revert CallerIsNotOwnerOrSanitizer(); - } - } - - /** - * @dev Internal view function to revert if the caller is not the owner or - * the rotator. - */ - function _assertCallerIsOwnerOrRotator() internal view { - // Ensure caller is the owner or the rotator. - if (msg.sender != owner() && msg.sender != _rotator) { - revert CallerIsNotOwnerOrRotator(); - } - } -} diff --git a/signed-zone/SignedZoneController.sol b/signed-zone/SignedZoneController.sol deleted file mode 100644 index cb54b9c..0000000 --- a/signed-zone/SignedZoneController.sol +++ /dev/null @@ -1,595 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {SignedZone} from "./SignedZone.sol"; - -import {SignedZoneInterface} from "./interfaces/SignedZoneInterface.sol"; - -import {SignedZoneControllerInterface} from "./interfaces/SignedZoneControllerInterface.sol"; - -import {SignedZoneControllerEventsAndErrors} from "./interfaces/SignedZoneControllerEventsAndErrors.sol"; - -import "./lib/SignedZoneConstants.sol"; - -/** - * @title SignedZoneController - * @author BCLeFevre - * @notice SignedZoneController enables the deploying of SignedZones and - * managing new SignedZone. - * 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 - */ -contract SignedZoneController is SignedZoneControllerInterface, SignedZoneControllerEventsAndErrors { - /** - * @dev The struct for storing signer info. - */ - struct SignerInfo { - /// @dev If the signer is currently active. - bool active; - /// @dev If the signer has been active before. - bool previouslyActive; - } - - // Properties used by the signed zone, stored on the controller. - struct SignedZoneProperties { - /// @dev Owner of the signed zone (used for permissioned functions) - address owner; - /// @dev Potential owner of the signed zone - address potentialOwner; - /// @dev The name for this zone returned in getSeaportMetadata(). - string zoneName; - /// @dev The API endpoint where orders for this zone can be signed. - /// Request and response payloads are defined in SIP-7. - string apiEndpoint; - /// @dev The URI to the documentation describing the behavior of the - /// contract. - string documentationURI; - /// @dev The substandards supported by this zone. - /// Substandards are defined in SIP-7. - uint256[] substandards; - /// @dev Mapping of signer information keyed by signer Address - mapping(address => SignerInfo) signers; - /// @dev List of active signers - address[] activeSignerList; - } - - /// @dev Mapping of signed zone properties keyed by the Signed Zone - /// address. - mapping(address => SignedZoneProperties) internal _signedZones; - - /// @dev The EIP-712 digest parameters for the SignedZone. - bytes32 internal immutable _VERSION_HASH = keccak256(bytes("1.0")); - // prettier-ignore - bytes32 internal immutable _EIP_712_DOMAIN_TYPEHASH = keccak256( - abi.encodePacked( - "EIP712Domain(", "string name,", "string version,", "uint256 chainId,", "address verifyingContract", ")" - ) - ); - uint256 internal immutable _CHAIN_ID = block.chainid; - - /** - * @dev Initialize contract - */ - constructor() {} - - /** - * @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 signedZone The derived address for the zone. - */ - function createZone( - string memory zoneName, - string memory apiEndpoint, - string memory documentationURI, - address initialOwner, - bytes32 salt - ) external override returns (address signedZone) { - // Ensure that an initial owner has been supplied. - if (initialOwner == address(0)) { - revert InvalidInitialOwner(); - } - - // Ensure the first 20 bytes of the salt are the same as the msg.sender. - if ((address(uint160(bytes20(salt))) != msg.sender)) { - // Revert with an error indicating that the creator is invalid. - revert InvalidCreator(); - } - - // Get the creation code for the signed zone. - bytes memory _SIGNED_ZONE_CREATION_CODE = abi.encodePacked(type(SignedZone).creationCode, abi.encode(zoneName)); - - // Using assembly try to deploy the zone. - assembly { - signedZone := create2(0, add(0x20, _SIGNED_ZONE_CREATION_CODE), mload(_SIGNED_ZONE_CREATION_CODE), salt) - - if iszero(extcodesize(signedZone)) { revert(0, 0) } - } - - // Initialize storage variable referencing signed zone properties. - SignedZoneProperties storage signedZoneProperties = _signedZones[signedZone]; - - // Set the supplied intial owner as the owner of the zone. - signedZoneProperties.owner = initialOwner; - // Set the zone name. - signedZoneProperties.zoneName = zoneName; - // Set the API endpoint. - signedZoneProperties.apiEndpoint = apiEndpoint; - // Set the documentation URI. - signedZoneProperties.documentationURI = documentationURI; - // Set the substandard. - signedZoneProperties.substandards = [1]; - - // Emit an event signifying that the zone was created. - emit ZoneCreated(signedZone, zoneName, apiEndpoint, documentationURI, salt); - - // Emit an event indicating that zone ownership has been assigned. - emit OwnershipTransferred(signedZone, address(0), initialOwner); - } - - /** - * @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 override { - // Ensure the caller is the current owner of the zone in question. - _assertCallerIsZoneOwner(zone); - - // Ensure the new potential owner is not an invalid address. - if (newPotentialOwner == address(0)) { - revert NewPotentialOwnerIsNullAddress(zone); - } - - // Ensure the new potential owner is not already set. - if (newPotentialOwner == _signedZones[zone].potentialOwner) { - revert NewPotentialOwnerAlreadySet(zone, newPotentialOwner); - } - - // Emit an event indicating that the potential owner has been updated. - emit PotentialOwnerUpdated(newPotentialOwner); - - // Set the new potential owner as the potential owner of the zone. - _signedZones[zone].potentialOwner = newPotentialOwner; - } - - /** - * @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 override { - // Ensure the caller is the current owner of the zone in question. - _assertCallerIsZoneOwner(zone); - - // Ensure that ownership transfer is currently possible. - if (_signedZones[zone].potentialOwner == address(0)) { - revert NoPotentialOwnerCurrentlySet(zone); - } - - // Emit an event indicating that the potential owner has been cleared. - emit PotentialOwnerUpdated(address(0)); - - // Clear the current new potential owner from the zone. - _signedZones[zone].potentialOwner = address(0); - } - - /** - * @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 override { - // Ensure that the zone in question exists. - _assertZoneExists(zone); - - // If caller does not match current potential owner of the zone... - if (msg.sender != _signedZones[zone].potentialOwner) { - // Revert, indicating that caller is not current potential owner. - revert CallerIsNotNewPotentialOwner(zone); - } - - // Emit an event indicating that the potential owner has been cleared. - emit PotentialOwnerUpdated(address(0)); - - // Clear the current new potential owner from the zone. - _signedZones[zone].potentialOwner = address(0); - - // Emit an event indicating zone ownership has been transferred. - emit OwnershipTransferred(zone, _signedZones[zone].owner, msg.sender); - - // Set the caller as the owner of the zone. - _signedZones[zone].owner = msg.sender; - } - - /** - * @notice Update the API endpoint returned by a zone. - * Only the owner or an active signer of the supplied zone can call - * this function. - * - * @param zone The signed zone to update the API endpoint for. - * @param newApiEndpoint The new API endpoint. - */ - function updateAPIEndpoint(address zone, string calldata newApiEndpoint) external override { - // Ensure the caller is the owner of the signed zone. - _assertCallerIsZoneOwner(zone); - - // Retrieve storage region where the singers for the signedZone are - // stored. - SignedZoneProperties storage signedZoneProperties = _signedZones[zone]; - - // Update the API endpoint on the signed zone. - signedZoneProperties.apiEndpoint = newApiEndpoint; - } - - /** - * @notice Update the documentationURI returned by a zone. - * Only the owner or an active signer of the supplied zone can call - * this function. - * - * @param zone The signed zone to update the documentationURI - * for. - * @param documentationURI The new documentation URI. - */ - function updateDocumentationURI(address zone, string calldata documentationURI) external override { - // Ensure the caller is the owner of the signed zone. - _assertCallerIsZoneOwner(zone); - - // Retrieve storage region where the singers for the signedZone are - // stored. - SignedZoneProperties storage signedZoneProperties = _signedZones[zone]; - - // Update the documentationURI on the signed zone. - signedZoneProperties.documentationURI = documentationURI; - } - - /** - * @notice Add or remove a signer from the supplied zone. - * Only the owner or an active signer of the supplied zone can call - * this function. - * - * @param zone The signed zone to update the signer permissions for. - * @param signer The signer to update the permissions for. - * @param active Whether the signer should be active or not. - */ - function updateSigner(address zone, address signer, bool active) external override { - // Ensure the caller is the owner of the signed zone. - _assertCallerIsZoneOwner(zone); - - // Retrieve storage region where the singers for the signedZone are - // stored. - SignedZoneProperties storage signedZoneProperties = _signedZones[zone]; - - // Validate signer permissions. - _assertSignerPermissions(signedZoneProperties, signer, active); - - // Update the signer on the signed zone. - SignedZoneInterface(zone).updateSigner(signer, active); - - // Update the signer information. - signedZoneProperties.signers[signer].active = active; - signedZoneProperties.signers[signer].previouslyActive = true; - // Add the signer to the list of signers if they are active. - if (active) { - signedZoneProperties.activeSignerList.push(signer); - } else { - // Remove the signer from the list of signers. - for (uint256 i = 0; i < signedZoneProperties.activeSignerList.length;) { - if (signedZoneProperties.activeSignerList[i] == signer) { - signedZoneProperties.activeSignerList[i] = - signedZoneProperties.activeSignerList[signedZoneProperties.activeSignerList.length - 1]; - signedZoneProperties.activeSignerList.pop(); - break; - } - - unchecked { - ++i; - } - } - } - - // Emit an event signifying that the signer was updated. - emit SignerUpdated(zone, signer, active); - } - - /** - * @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 override returns (address owner) { - // Ensure that the zone in question exists. - _assertZoneExists(zone); - - // Retrieve the current owner of the zone in question. - owner = _signedZones[zone].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 override returns (address potentialOwner) { - // Ensure that the zone in question exists. - _assertZoneExists(zone); - - // Retrieve the current potential owner of the zone in question. - potentialOwner = _signedZones[zone].potentialOwner; - } - - /** - * @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. - * - * @param zone The zone to return the active signers for. - * - * @return signers The active signers. - */ - function getActiveSigners(address zone) external view override returns (address[] memory signers) { - // Ensure that the zone in question exists. - _assertZoneExists(zone); - - // Retrieve storage region where the singers for the signedZone are - // stored. - SignedZoneProperties storage signedZoneProperties = _signedZones[zone]; - - // Return the active signers for the zone. - signers = signedZoneProperties.activeSignerList; - } - - /** - * @notice Returns if the given address is an active signer for the zone. - * - * @param zone The zone to return the active signers for. - * @param signer The address to check if it is an active signer. - * - * @return The address is an active signer, false otherwise. - */ - function isActiveSigner(address zone, address signer) external view override returns (bool) { - // Ensure that the zone in question exists. - _assertZoneExists(zone); - - // Retrieve storage region where the singers for the signedZone are - // stored. - SignedZoneProperties storage signedZoneProperties = _signedZones[zone]; - - // Return whether the signer is an active signer for the zone. - return signedZoneProperties.signers[signer].active; - } - - /** - * @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(string memory zoneName, bytes32 salt) external view override returns (address derivedAddress) { - // Get the zone creation code hash. - bytes32 _SIGNED_ZONE_CREATION_CODE_HASH = - keccak256(abi.encodePacked(type(SignedZone).creationCode, abi.encode(zoneName))); - // Derive the SignedZone address from deployer, salt and creation code - // hash. - derivedAddress = address( - uint160( - uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, _SIGNED_ZONE_CREATION_CODE_HASH))) - ) - ); - } - - /** - * @notice External call to return the signing information, substandards, - * and documentation about the zone. - * - * @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 - override - returns ( - bytes32 domainSeparator, - string memory zoneName, - string memory apiEndpoint, - uint256[] memory substandards, - string memory documentationURI - ) - { - // Ensure the zone exists. - _assertZoneExists(zone); - - // Return the zone's additional information. - return _additionalZoneInformation(zone); - } - - /** - * @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 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 _additionalZoneInformation(address zone) - internal - view - returns ( - bytes32 domainSeparator, - string memory zoneName, - string memory apiEndpoint, - uint256[] memory substandards, - string memory documentationURI - ) - { - // Get the zone properties. - SignedZoneProperties storage signedZoneProperties = _signedZones[zone]; - - // Return the SIP-7 information. - domainSeparator = _domainSeparator(zone); - zoneName = signedZoneProperties.zoneName; - apiEndpoint = signedZoneProperties.apiEndpoint; - substandards = signedZoneProperties.substandards; - documentationURI = signedZoneProperties.documentationURI; - } - - /** - * @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(address zone) internal view returns (bytes32) { - // prettier-ignore - return _deriveDomainSeparator(zone); - } - - /** - * @dev Internal view function to derive the EIP-712 domain separator. - * - * @return domainSeparator The derived domain separator. - */ - function _deriveDomainSeparator(address zone) internal view returns (bytes32 domainSeparator) { - bytes32 typehash = _EIP_712_DOMAIN_TYPEHASH; - // Get the name hash from the zone properties. - SignedZoneProperties storage signedZoneProperties = _signedZones[zone]; - bytes32 nameHash = keccak256(bytes(signedZoneProperties.zoneName)); - 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 the signed zone contract in the next memory location. - mstore(FourWords, zone) - - // 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 Private view function to revert if the caller is not the owner of a - * given zone. - * - * @param zone The zone for which to assert ownership. - */ - function _assertCallerIsZoneOwner(address zone) private view { - // Ensure that the zone in question exists. - _assertZoneExists(zone); - - // If the caller does not match the current owner of the zone... - if (msg.sender != _signedZones[zone].owner) { - // Revert, indicating that the caller is not the owner. - revert CallerIsNotOwner(zone); - } - } - - /** - * @dev Private view function to revert if a given zone does not exist. - * - * @param zone The zone for which to assert existence. - */ - function _assertZoneExists(address zone) private view { - // Attempt to retrieve a the owner for the zone in question. - if (_signedZones[zone].owner == address(0)) { - // Revert if no ownerwas located. - revert NoZone(); - } - } - - /** - * @dev Private view function to revert if a signer being added to a zone - * is the null address or the signer already exists, or the signer was - * previously authorized. If the signer is being removed, the - * function will revert if the signer is not active. - * - * @param signedZoneProperties The signed zone properties for the zone. - * @param signer The signer to add or remove. - * @param active Whether the signer is being added or - * removed. - */ - function _assertSignerPermissions(SignedZoneProperties storage signedZoneProperties, address signer, bool active) - private - view - { - // Do not allow the null address to be added as a signer. - if (signer == address(0)) { - revert SignerCannotBeNullAddress(); - } - - // If the signer is being added... - if (active) { - // Revert if the signer is already added. - if (signedZoneProperties.signers[signer].active) { - revert SignerAlreadyAdded(signer); - } - - // Revert if the signer was previously authorized. - if (signedZoneProperties.signers[signer].previouslyActive) { - revert SignerCannotBeReauthorized(signer); - } - } else { - // Revert if the signer is not active. - if (!signedZoneProperties.signers[signer].active) { - revert SignerNotPresent(signer); - } - } - } -} diff --git a/signed-zone/examples/ExampleSignedZoneCaptain.sol b/signed-zone/examples/ExampleSignedZoneCaptain.sol deleted file mode 100644 index c9eccfd..0000000 --- a/signed-zone/examples/ExampleSignedZoneCaptain.sol +++ /dev/null @@ -1,37 +0,0 @@ -//SPDX-License Identifier:MIT -pragma solidity ^0.8.13; - -import {SignedZoneCaptain} from "../SignedZoneCaptain.sol"; - -/** - * @title ExampleSignedZoneCaptain - * @author OpenSea Protocol Team - * @notice ExampleSignedZoneCaptain is a test contract that owns signed zones - * and manages their active signers via two roles. The rotator role can - * update the active signers of a zone. The sanitizer role can remove - * all active signers of a zone controlled by the captain and clear - * the rotator role on the captain. - * In order to ensure the captain is deployed by an approved deployer, - * the _assertValidDeployer function is overridden to check that the - * deployer is the address is valid. - */ -contract ExampleSignedZoneCaptain is SignedZoneCaptain { - constructor(address signedZoneController) SignedZoneCaptain(signedZoneController) {} - - /** - * @notice Internal function to assert that the caller is a valid deployer. - */ - function _assertValidDeployer() internal view override { - // Ensure that the contract is being deployed by an approved - // deployer. - // tx.origin is used here, because we use the SignedZoneDeployer - // contract to deploy this contract, and initailize the owner, - // rotator, and sanitizer roles. - - /// @dev 0x1010101010101010101010101010101010101010 should be overridden - /// with the address of your approved deployer. - if (tx.origin != address(0x1010101010101010101010101010101010101010)) { - revert InvalidDeployer(); - } - } -} diff --git a/signed-zone/interfaces/SignedZoneCaptainEventsAndErrors.sol b/signed-zone/interfaces/SignedZoneCaptainEventsAndErrors.sol deleted file mode 100644 index 49367fb..0000000 --- a/signed-zone/interfaces/SignedZoneCaptainEventsAndErrors.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @notice SignedZoneCaptainEventsAndErrors contains errors and events - * related to owning signed zones. - */ -interface SignedZoneCaptainEventsAndErrors { - /** - * @dev Emit an event when the contract owner updates the rotator. - * - * @param newRotator The new rotator of the contract. - */ - event RotatorUpdated(address newRotator); - - /** - * @dev Emit an event when the contract owner updates the sanitizer. - * - * @param newSanitizer The new sanitizer of the contract. - */ - event SanitizerUpdated(address newSanitizer); - - /** - * @dev Emit an event when the sanitizer sanitizes a zone. - * - * @param zone The zone address being sanitized. - */ - event ZoneSanitized(address zone); - - /** - * @dev Revert with an error when attempting to deploy the contract with an - * invalid deployer. - */ - error InvalidDeployer(); - - /** - * @dev Revert with an error when attempting to set a zone controller - * that does not contain contract code. - * - * @param signedZoneController The invalid address. - */ - error InvalidSignedZoneController(address signedZoneController); - - /** - * @dev Revert with an error when attempting to set the rotator - * to the null address. - */ - error RotatorCannotBeNullAddress(); - - /** - * @dev Revert with an error when attempting to set the sanitizer - * to the null address. - */ - error SanitizerCannotBeNullAddress(); - - /** - * @dev Revert with an error when attempting to call a function that - * requires the caller to be the owner of the zone. - */ - error CallerIsNotOwner(); - - /** - * @dev Revert with an error when attempting to call a function that - * requires the caller to be the owner or sanitizer of the zone. - */ - error CallerIsNotOwnerOrSanitizer(); - - /** - * @dev Revert with an error when attempting to call a function that - * requires the caller to be the owner or rotator of the zone. - */ - error CallerIsNotOwnerOrRotator(); -} diff --git a/signed-zone/interfaces/SignedZoneCaptainInterface.sol b/signed-zone/interfaces/SignedZoneCaptainInterface.sol deleted file mode 100644 index 765457b..0000000 --- a/signed-zone/interfaces/SignedZoneCaptainInterface.sol +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @title SignedZoneCaptainInterface - * @author BCLeFevre - * @notice SignedZoneCaptainInterface contains function declarations for the - * SignedZoneCaptain contract. - */ -interface SignedZoneCaptainInterface { - /** - * @notice External initialization called by the deployer to set the owner, - * rotator and sanitizer, and create a signed zone with the given - * name, API endpoint, documentation URI. - * - * @param initialOwner The address to be set as the owner. - * @param initialRotator The address to be set as the rotator. - * @param initialSanitizer The address to be set as the sanitizer. - * @param zoneName The name of the zone being created. - * @param apiEndpoint The API endpoint of the zone being created. - * @param documentationURI The documentation URI of the zone being created. - * @param zoneSalt The salt to use when creating the zone. - */ - function initialize( - address initialOwner, - address initialRotator, - address initialSanitizer, - string calldata zoneName, - string calldata apiEndpoint, - string calldata documentationURI, - bytes32 zoneSalt - ) external; - - /** - * @notice Update the signer for a given signed zone. - * - * @param zone 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 updateZoneSigner(address zone, address signer, bool active) external; - - /** - * @notice Update the API endpoint returned by the supplied zone. - * Only the owner can call this function. - * - * @param zone The signed zone to update the API endpoint for. - * @param newApiEndpoint The new API endpoint. - */ - function updateZoneAPIEndpoint(address zone, string calldata newApiEndpoint) external; - - /** - * @notice Update the documentationURI returned by a zone. Only the owner - * of the supplied zone can call this function. - * - * @param zone The signed zone to update the API endpoint - * for. - * @param newDocumentationURI The new documentation URI. - */ - function updateZoneDocumentationURI(address zone, string calldata newDocumentationURI) external; - - /** - * @notice Initiate zone ownership transfer by assigning a new potential - * owner for the given zone. Only callable by the owner. - * - * @param zone The zone for which to initiate ownership - * transfer. - * @param newPotentialOwner The new potential owner to set. - */ - function transferZoneOwnership(address zone, address newPotentialOwner) external; - - /** - * @notice Clear the currently set potential owner, if any, from a zone. - * Only callable by the owner. - * - * @param zone The zone for which to cancel ownership transfer. - */ - function cancelZoneOwnershipTransfer(address zone) external; - - /** - * @notice Accept ownership of a given zone once the address has been set - * as the current potential owner. Only callable by the owner. - * - * @param zone The zone for which to accept ownership transfer. - */ - function acceptZoneOwnership(address zone) external; - - /** - * @notice Rotate the signers for a given zone. Only callable by the owner - * or the rotator of the zone. - * - * @param zone The zone to rotate the signers for. - * @param signerToRemove The signer to remove. - * @param signerToAdd The signer to add. - */ - function rotateSigners(address zone, address signerToRemove, address signerToAdd) external; - - /** - * @notice This will remove all active signers and clear the rotator - * address on the captain. Only callable by the owner or the - * sanitizer of the zone. - * - * @param zone The zone to sanitize. - */ - function sanitizeSignedZone(address zone) external; - - /** - * @notice Update the rotator role on the captain. - * - * @param newRotator The new rotator of the captain. - */ - function updateRotator(address newRotator) external; - - /** - * @notice Update the sanitizer role on the captain. - * - * @param newSanitizer The new sanitizer of the captain. - */ - function updateSanitizer(address newSanitizer) external; - - /** - * @notice Get the rotator address. - * - * @return The rotator address. - */ - function getRotator() external view returns (address); - - /** - * @notice Get the sanitizer address. - * - * @return The sanitizer address. - */ - function getSanitizer() external view returns (address); -} diff --git a/signed-zone/interfaces/SignedZoneControllerEventsAndErrors.sol b/signed-zone/interfaces/SignedZoneControllerEventsAndErrors.sol deleted file mode 100644 index 2e46adc..0000000 --- a/signed-zone/interfaces/SignedZoneControllerEventsAndErrors.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @notice SignedZoneControllerEventsAndErrors contains errors and events - * related to deploying and managing new signed zones. - */ -interface SignedZoneControllerEventsAndErrors { - /** - * @dev Emit an event whenever a new zone is created. - * - * @param zoneAddress The address of the zone. - * @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 used to deploy the zone. - */ - event ZoneCreated(address zoneAddress, string zoneName, string apiEndpoint, string documentationURI, bytes32 salt); - - /** - * @dev Emit an event whenever zone ownership is transferred. - * - * @param zone The zone for which ownership has been - * transferred. - * @param previousOwner The previous owner of the zone. - * @param newOwner The new owner of the zone. - */ - event OwnershipTransferred(address indexed zone, address indexed previousOwner, address indexed newOwner); - - /** - * @dev Emit an event whenever a zone owner registers a new potential - * owner for that zone. - * - * @param newPotentialOwner The new potential owner of the zone. - */ - event PotentialOwnerUpdated(address indexed newPotentialOwner); - - /** - * @dev Emit an event when a signer has been updated. - */ - event SignerUpdated(address signedZone, address signer, bool active); - - /** - * @dev Revert with an error when attempting to update zone information or - * transfer ownership of a zone when the caller is not the owner of - * the zone in question. - */ - error CallerIsNotOwner(address zone); - - /** - * @dev Revert with an error when attempting to claim ownership of a zone - * with a caller that is not the current potential owner for the - * zone in question. - */ - error CallerIsNotNewPotentialOwner(address zone); - - /** - * @dev Revert with an error when attempting to create a new signed zone - * using a salt where the first twenty bytes do not match the address - * of the caller or are not set to zero. - */ - error InvalidCreator(); - - /** - * @dev Revert with an error when attempting to create a new zone when no - * initial owner address is supplied. - */ - error InvalidInitialOwner(); - - /** - * @dev Revert with an error when attempting to set a new potential owner - * that is already set. - */ - error NewPotentialOwnerAlreadySet(address zone, address newPotentialOwner); - - /** - * @dev Revert with an error when attempting to cancel ownership transfer - * when no new potential owner is currently set. - */ - error NoPotentialOwnerCurrentlySet(address zone); - /** - * @dev Revert with an error when attempting to register a new potential - * owner and supplying the null address. - */ - error NewPotentialOwnerIsNullAddress(address zone); - - /** - * @dev Revert with an error when attempting to interact with a zone that - * does not yet exist. - */ - error NoZone(); - - /** - * @dev Revert with an error if trying to add a signer that is - * already active. - */ - error SignerAlreadyAdded(address signer); - - /** - * @dev Revert with an error if a new signer is the null address. - */ - error SignerCannotBeNullAddress(); - - /** - * @dev Revert with an error if a removed signer is trying to be - * reauthorized. - */ - error SignerCannotBeReauthorized(address signer); - - /** - * @dev Revert with an error if trying to remove a signer that is - * not present. - */ - error SignerNotPresent(address signer); - - /** - * @dev Revert with an error when attempting to deploy a zone that is - * currently deployed. - */ - error ZoneAlreadyExists(address zone); -} diff --git a/signed-zone/interfaces/SignedZoneControllerInterface.sol b/signed-zone/interfaces/SignedZoneControllerInterface.sol deleted file mode 100644 index 9a17e05..0000000 --- a/signed-zone/interfaces/SignedZoneControllerInterface.sol +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @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 signedZone The derived address for the zone. - */ - function createZone( - string memory zoneName, - string memory apiEndpoint, - string memory documentationURI, - address initialOwner, - bytes32 salt - ) external returns (address signedZone); - - /** - * @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 documentationURI returned by a zone. - * Only the owner or an active signer of the supplied zone can call - * this function. - * - * @param zone The signed zone to update the API endpoint for. - * @param documentationURI The new documentation URI. - */ - function updateDocumentationURI(address zone, string calldata documentationURI) 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 zoneName The name of the zone. - * @param salt The salt to be used to derive the zone address. - * - * @return derivedAddress The derived address of the signed zone. - */ - function getZone(string memory zoneName, bytes32 salt) external view returns (address derivedAddress); - - /** - * @notice Returns whether or not the supplied address is an active signer - * for the supplied zone. - * - * @param zone The zone to check if the supplied address is an active - * signer for. - * @param signer The address to check if it is an active signer for - * - * @return active If the supplied address is an active signer for the - * supplied zone. - */ - function isActiveSigner(address zone, address signer) external view returns (bool); -} diff --git a/signed-zone/interfaces/SignedZoneEventsAndErrors.sol b/signed-zone/interfaces/SignedZoneEventsAndErrors.sol deleted file mode 100644 index 9783764..0000000 --- a/signed-zone/interfaces/SignedZoneEventsAndErrors.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @notice SignedZoneEventsAndErrors contains errors and events - * related to zone interaction. - */ -interface SignedZoneEventsAndErrors { - /** - * @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 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(); -} diff --git a/signed-zone/interfaces/SignedZoneInterface.sol b/signed-zone/interfaces/SignedZoneInterface.sol deleted file mode 100644 index 1767f6c..0000000 --- a/signed-zone/interfaces/SignedZoneInterface.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @title SignedZone - * @author ryanio, BCLeFevre - * @notice SignedZone 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 - * - */ -interface SignedZoneInterface { - /** - * @notice Update the active status of a signer. - * - * @param signer The signer address to update. - * @param active The new active status of the signer. - */ - function updateSigner(address signer, bool active) external; - - /** - * @notice Returns the active signers for the zone. - * - * @return signers The active signers. - */ - function getActiveSigners() external view returns (address[] memory signers); -} diff --git a/signed-zone/lib/SignedZoneConstants.sol b/signed-zone/lib/SignedZoneConstants.sol deleted file mode 100644 index 2a74bf9..0000000 --- a/signed-zone/lib/SignedZoneConstants.sol +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/// @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_epected_length = 0x7e; - -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;