diff --git a/constants/addresses.ts b/constants/addresses.ts index 65dfa640..a75f6664 100644 --- a/constants/addresses.ts +++ b/constants/addresses.ts @@ -6,8 +6,17 @@ export const CONDUIT_CONTROLLER_ADDRESS: { [chainId: number]: string } = { [ChainId.GÖRLI]: "0x00000000F9490004C11Cef243f5400493c00Ad63", }; -export const SEAPORT_ADDRESS: { [chainId: number]: string } = { +export const SEAPORT_ADDRESS_1_1: { [chainId: number]: string } = { [ChainId.ETHEREUM]: "0x00000000006c3852cbef3e08e8df289169ede581", [ChainId.RINKEBY]: "0x00000000006c3852cbef3e08e8df289169ede581", [ChainId.GÖRLI]: "0x00000000006c3852cbEf3e08E8dF289169EdE581", }; + +// TODO +export const SEAPORT_ADDRESS_1_2: { [chainId: number]: string } = { + [ChainId.ETHEREUM]: "", + [ChainId.RINKEBY]: "", + [ChainId.GÖRLI]: "", +}; + +export const SEAPORT_ADDRESS = SEAPORT_ADDRESS_1_1; diff --git a/contracts/seaport/Conduit.sol b/contracts/seaport/Conduit.sol index ece0dac7..3ec6fe43 100644 --- a/contracts/seaport/Conduit.sol +++ b/contracts/seaport/Conduit.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.13; +pragma solidity ^0.8.13; import "seaport/contracts/conduit/Conduit.sol"; \ No newline at end of file diff --git a/contracts/seaport/ConduitController.sol b/contracts/seaport/ConduitController.sol index b637fffb..bb6d3cf8 100644 --- a/contracts/seaport/ConduitController.sol +++ b/contracts/seaport/ConduitController.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.13; +pragma solidity ^0.8.13; import "seaport/contracts/conduit/ConduitController.sol"; \ No newline at end of file diff --git a/contracts/seaport/ImmutableCreate2FactoryInterface.sol b/contracts/seaport/ImmutableCreate2FactoryInterface.sol index 1e8a3185..ea82efd4 100644 --- a/contracts/seaport/ImmutableCreate2FactoryInterface.sol +++ b/contracts/seaport/ImmutableCreate2FactoryInterface.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.13; +pragma solidity ^0.8.13; import "seaport/contracts/interfaces/ImmutableCreate2FactoryInterface.sol"; \ No newline at end of file diff --git a/contracts/seaport/Seaport.sol b/contracts/seaport/Seaport.sol index 53aa2408..49f7f161 100644 --- a/contracts/seaport/Seaport.sol +++ b/contracts/seaport/Seaport.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.13; +pragma solidity ^0.8.17; import "seaport/contracts/Seaport.sol"; \ No newline at end of file diff --git a/contracts/seaport/Zones/PausableZone.sol b/contracts/seaport/Zones/PausableZone.sol index ff327a89..1240692b 100644 --- a/contracts/seaport/Zones/PausableZone.sol +++ b/contracts/seaport/Zones/PausableZone.sol @@ -1,273 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.7; +pragma solidity ^0.8.13; -import { ZoneInterface } from "seaport/contracts/interfaces/ZoneInterface.sol"; -import { ZoneInteractionErrors } from "seaport/contracts/interfaces/ZoneInteractionErrors.sol"; - -// prettier-ignore -import { - PausableZoneEventsAndErrors -} from "./PausableZoneEventsAndErrors.sol"; - -import { SeaportInterface } from "seaport/contracts/interfaces/SeaportInterface.sol"; - -// prettier-ignore -import { - AdvancedOrder, - CriteriaResolver, - Order, - OrderComponents, - Fulfillment, - Execution -} from "seaport/contracts/lib/ConsiderationStructs.sol"; - -import { PausableZoneInterface } from "./PausableZoneInterface.sol"; - -/** - * @title PausableZone - * @author cupOJoseph, BCLeFevre, ryanio - * @notice PausableZone is a simple zone implementation that approves every - * order. It can be self-destructed by its controller to pause - * restricted orders that have it set as their zone. - */ -contract PausableZone is - PausableZoneEventsAndErrors, - ZoneInterface, - PausableZoneInterface -{ - // Set an immutable controller that can pause the zone & update an operator. - address internal immutable _controller; - - // Set an operator that can instruct the zone to cancel or execute orders. - address public operator; - - /** - * @dev Ensure that the caller is either the operator or controller. - */ - modifier isOperator() { - // Ensure that the caller is either the operator or the controller. - if (msg.sender != operator && msg.sender != _controller) { - revert InvalidOperator(); - } - - // Continue with function execution. - _; - } - - /** - * @dev Ensure that the caller is the controller. - */ - modifier isController() { - // Ensure that the caller is the controller. - if (msg.sender != _controller) { - revert InvalidController(); - } - - // Continue with function execution. - _; - } - - /** - * @notice Set the deployer as the controller of the zone. - */ - constructor() { - // Set the controller to the deployer. - _controller = msg.sender; - - // Emit an event signifying that the zone is unpaused. - emit Unpaused(); - } - - /** - * @notice Cancel an arbitrary number of orders that have agreed to use the - * contract as their zone. - * - * @param seaport The Seaport address. - * @param orders The orders to cancel. - * - * @return cancelled A boolean indicating whether the supplied orders have - * been successfully cancelled. - */ - function cancelOrders( - SeaportInterface seaport, - OrderComponents[] calldata orders - ) external override isOperator returns (bool cancelled) { - // Call cancel on Seaport and return its boolean value. - cancelled = seaport.cancel(orders); - } - - /** - * @notice Pause this contract, safely stopping orders from using - * the contract as a zone. Restricted orders with this address as a - * zone will not be fulfillable unless the zone is redeployed to the - * same address. - */ - function pause(address payee) external override isController { - // Emit an event signifying that the zone is paused. - emit Paused(); - - // Destroy the zone, sending any ether to the transaction submitter. - selfdestruct(payable(payee)); - } - - /** - * @notice Assign the given address with the ability to operate the zone. - * - * @param operatorToAssign The address to assign as the operator. - */ - function assignOperator(address operatorToAssign) - external - override - isController - { - // Ensure the operator being assigned is not the null address. - if (operatorToAssign == address(0)) { - revert PauserCanNotBeSetAsZero(); - } - - // Set the given address as the new operator. - operator = operatorToAssign; - - // Emit an event indicating the operator has been updated. - emit OperatorUpdated(operator); - } - - /** - * @notice Execute an arbitrary number of matched orders, each with - * an arbitrary number of items for offer and consideration - * along with a set of fulfillments allocating offer components - * to consideration components. - * - * @param seaport The Seaport address. - * @param orders The orders to match. - * @param fulfillments An array of elements allocating offer components - * to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchOrders( - SeaportInterface seaport, - Order[] calldata orders, - Fulfillment[] calldata fulfillments - ) - external - payable - override - isOperator - returns (Execution[] memory executions) - { - // Call matchOrders on Seaport and return the sequence of transfers - // performed as part of matching the given orders. - executions = seaport.matchOrders{ value: msg.value }( - orders, - fulfillments - ); - } - - /** - * @notice Execute an arbitrary number of matched advanced orders, - * each with an arbitrary number of items for offer and - * consideration along with a set of fulfillments allocating - * offer components to consideration components. - * - * @param seaport The Seaport address. - * @param orders The orders to match. - * @param criteriaResolvers An array where each element contains a reference - * to a specific order as well as that order's - * offer or consideration, a token identifier, and - * a proof that the supplied token identifier is - * contained in the order's merkle root. - * @param fulfillments An array of elements allocating offer components - * to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchAdvancedOrders( - SeaportInterface seaport, - AdvancedOrder[] calldata orders, - CriteriaResolver[] calldata criteriaResolvers, - Fulfillment[] calldata fulfillments - ) - external - payable - override - isOperator - returns (Execution[] memory executions) - { - // Call matchAdvancedOrders on Seaport and return the sequence of - // transfers performed as part of matching the given orders. - executions = seaport.matchAdvancedOrders{ value: msg.value }( - orders, - criteriaResolvers, - fulfillments - ); - } - - /** - * @notice Check if a given order is currently valid. - * - * @dev This function is called by Seaport whenever extraData is not - * provided by the caller. - * - * @param orderHash The hash of the order. - * @param caller The caller in question. - * @param offerer The offerer in question. - * @param zoneHash The hash to provide upon calling the zone. - * - * @return validOrderMagicValue A magic value indicating if the order is - * currently valid. - */ - function isValidOrder( - bytes32 orderHash, - address caller, - address offerer, - bytes32 zoneHash - ) external pure override returns (bytes4 validOrderMagicValue) { - orderHash; - caller; - offerer; - zoneHash; - - // Return the selector of isValidOrder as the magic value. - validOrderMagicValue = ZoneInterface.isValidOrder.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. - * - * @param orderHash The hash of the order. - * @param caller The caller in question. - * @param order The order in question. - * @param priorOrderHashes The order hashes of each order supplied prior to - * the current order as part of a "match" variety - * of order fulfillment. - * @param criteriaResolvers The criteria resolvers corresponding to - * the order. - * - * @return validOrderMagicValue A magic value indicating if the order is - * currently valid. - */ - function isValidOrderIncludingExtraData( - bytes32 orderHash, - address caller, - AdvancedOrder calldata order, - bytes32[] calldata priorOrderHashes, - CriteriaResolver[] calldata criteriaResolvers - ) external pure override returns (bytes4 validOrderMagicValue) { - orderHash; - caller; - order; - priorOrderHashes; - criteriaResolvers; - - // Return the selector of isValidOrder as the magic value. - validOrderMagicValue = ZoneInterface.isValidOrder.selector; - } -} +import "seaport/contracts/zones/PausableZone.sol"; diff --git a/contracts/seaport/Zones/PausableZoneController.sol b/contracts/seaport/Zones/PausableZoneController.sol index 005b2269..9d6fef32 100644 --- a/contracts/seaport/Zones/PausableZoneController.sol +++ b/contracts/seaport/Zones/PausableZoneController.sol @@ -1,387 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.7; +pragma solidity ^0.8.13; -import { PausableZone } from "./PausableZone.sol"; - -// prettier-ignore -import { - PausableZoneControllerInterface -} from "./PausableZoneControllerInterface.sol"; - -// prettier-ignore -import { - PausableZoneEventsAndErrors -} from "./PausableZoneEventsAndErrors.sol"; - -// prettier-ignore -import { - Order, - Fulfillment, - OrderComponents, - AdvancedOrder, - CriteriaResolver, - Execution -} from "seaport/contracts/lib/ConsiderationStructs.sol"; - -import { SeaportInterface } from "seaport/contracts/interfaces/SeaportInterface.sol"; - -/** - * @title PausableZoneController - * @author cupOJoseph, BCLeFevre, stuckinaboot, stephankmin - * @notice PausableZoneController enables deploying, pausing and executing - * orders on PausableZones. This deployer is designed to be owned - * by a gnosis safe, DAO, or trusted party. - */ -contract PausableZoneController is - PausableZoneControllerInterface, - PausableZoneEventsAndErrors -{ - // Set the owner that can deploy, pause and execute orders on PausableZones. - address internal _owner; - - // Set the address of the new potential owner of the zone. - address private _potentialOwner; - - // Set the address with the ability to pause the zone. - address internal _pauser; - - // Set the immutable zone creation code hash. - bytes32 public immutable zoneCreationCode; - - /** - * @dev Throws if called by any account other than the owner or pauser. - */ - modifier isPauser() { - if (msg.sender != _pauser && msg.sender != _owner) { - revert InvalidPauser(); - } - _; - } - - /** - * @notice Set the owner of the controller and store - * the zone creation code. - * - * @param ownerAddress The deployer to be set as the owner. - */ - constructor(address ownerAddress) { - // Set the owner address as the owner. - _owner = ownerAddress; - - // Hash and store the zone creation code. - zoneCreationCode = keccak256(type(PausableZone).creationCode); - } - - /** - * @notice Deploy a PausableZone to a precomputed address. - * - * @param salt The salt to be used to derive the zone address - * - * @return derivedAddress The derived address for the zone. - */ - function createZone(bytes32 salt) - external - override - returns (address derivedAddress) - { - // Ensure the caller is the owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - - // Derive the PausableZone address. - // This expression demonstrates address computation but is not required. - derivedAddress = address( - uint160( - uint256( - keccak256( - abi.encodePacked( - bytes1(0xff), - address(this), - salt, - zoneCreationCode - ) - ) - ) - ) - ); - - // Revert if a zone is currently deployed to the derived address. - if (derivedAddress.code.length != 0) { - revert ZoneAlreadyExists(derivedAddress); - } - - // Deploy the zone using the supplied salt. - new PausableZone{ salt: salt }(); - - // Emit an event signifying that the zone was created. - emit ZoneCreated(derivedAddress, salt); - } - - /** - * @notice Pause orders on a given zone. - * - * @param zone The address of the zone to be paused. - * - * @return success A boolean indicating the zone has been paused. - */ - function pause(address zone) - external - override - isPauser - returns (bool success) - { - // Call pause on the given zone. - PausableZone(zone).pause(msg.sender); - - // Return a boolean indicating the pause was successful. - success = true; - } - - /** - * @notice Cancel Seaport orders on a given zone. - * - * @param pausableZoneAddress The zone that manages the - * orders to be cancelled. - * @param seaportAddress The Seaport address. - * @param orders The orders to cancel. - */ - function cancelOrders( - address pausableZoneAddress, - SeaportInterface seaportAddress, - OrderComponents[] calldata orders - ) external override { - // Ensure the caller is the owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - - // Create a zone object from the zone address. - PausableZone zone = PausableZone(pausableZoneAddress); - - // Call cancelOrders on the given zone. - zone.cancelOrders(seaportAddress, orders); - } - - /** - * @notice Execute an arbitrary number of matched orders on a given zone. - * - * @param pausableZoneAddress The zone that manages the orders - * to be cancelled. - * @param seaportAddress The Seaport address. - * @param orders The orders to match. - * @param fulfillments An array of elements allocating offer - * components to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchOrders( - address pausableZoneAddress, - SeaportInterface seaportAddress, - Order[] calldata orders, - Fulfillment[] calldata fulfillments - ) external payable override returns (Execution[] memory executions) { - // Ensure the caller is the owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - - // Create a zone object from the zone address. - PausableZone zone = PausableZone(pausableZoneAddress); - - // Call executeMatchOrders on the given zone and return the sequence - // of transfers performed as part of matching the given orders. - executions = zone.executeMatchOrders{ value: msg.value }( - seaportAddress, - orders, - fulfillments - ); - } - - /** - * @notice Execute an arbitrary number of matched advanced orders on a given - * zone. - * - * @param pausableZoneAddress The zone that manages the orders to be - * cancelled. - * @param seaportAddress The Seaport address. - * @param orders The orders to match. - * @param criteriaResolvers An array where each element contains a - * reference to a specific order as well as that - * order's offer or consideration, a token - * identifier, and a proof that the supplied - * token identifier is contained in the - * order's merkle root. - * @param fulfillments An array of elements allocating offer - * components to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchAdvancedOrders( - address pausableZoneAddress, - SeaportInterface seaportAddress, - AdvancedOrder[] calldata orders, - CriteriaResolver[] calldata criteriaResolvers, - Fulfillment[] calldata fulfillments - ) external payable override returns (Execution[] memory executions) { - // Ensure the caller is the owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - - // Create a zone object from the zone address. - PausableZone zone = PausableZone(pausableZoneAddress); - - // Call executeMatchOrders on the given zone and return the sequence - // of transfers performed as part of matching the given orders. - executions = zone.executeMatchAdvancedOrders{ value: msg.value }( - seaportAddress, - orders, - criteriaResolvers, - fulfillments - ); - } - - /** - * @notice Initiate Zone ownership transfer by assigning a new potential - * owner this contract. Once set, the new potential owner - * may call `acceptOwnership` to claim ownership. - * Only the owner in question may call this function. - * - * @param newPotentialOwner The address for which to initiate ownership - * transfer to. - */ - function transferOwnership(address newPotentialOwner) external override { - // Ensure the caller is the owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - // Ensure the new potential owner is not an invalid address. - if (newPotentialOwner == address(0)) { - revert OwnerCanNotBeSetAsZero(); - } - - // Emit an event indicating that the potential owner has been updated. - emit PotentialOwnerUpdated(newPotentialOwner); - - // Set the new potential owner as the potential owner. - _potentialOwner = newPotentialOwner; - } - - /** - * @notice Clear the currently set potential owner, if any. - * Only the owner of this contract may call this function. - */ - function cancelOwnershipTransfer() external override { - // Ensure the caller is the current owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - - // Emit an event indicating that the potential owner has been cleared. - emit PotentialOwnerUpdated(address(0)); - - // Clear the current new potential owner. - delete _potentialOwner; - } - - /** - * @notice Accept ownership of this contract. Only the account that the - * current owner has set as the new potential owner may call this - * function. - */ - function acceptOwnership() external override { - // Ensure the caller is the potential owner. - if (msg.sender != _potentialOwner) { - revert CallerIsNotPotentialOwner(); - } - - // Emit an event indicating that the potential owner has been cleared. - emit PotentialOwnerUpdated(address(0)); - - // Clear the current new potential owner - delete _potentialOwner; - - // Emit an event indicating ownership has been transferred. - emit OwnershipTransferred(_owner, msg.sender); - - // Set the caller as the owner of this contract. - _owner = msg.sender; - } - - /** - * @notice Assign the given address with the ability to pause the zone. - * - * @param pauserToAssign The address to assign the pauser role. - */ - function assignPauser(address pauserToAssign) external override { - // Ensure the caller is the owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - // Ensure the pauser to assign is not an invalid address. - if (pauserToAssign == address(0)) { - revert PauserCanNotBeSetAsZero(); - } - - // Set the given account as the pauser. - _pauser = pauserToAssign; - - // Emit an event indicating the pauser has been assigned. - emit PauserUpdated(_pauser); - } - - /** - * @notice Assign the given address with the ability to operate the - * given zone. - * - * @param pausableZoneAddress The zone address to assign operator role. - * @param operatorToAssign The address to assign as operator. - */ - function assignOperator( - address pausableZoneAddress, - address operatorToAssign - ) external override { - // Ensure the caller is the owner. - if (msg.sender != _owner) { - revert CallerIsNotOwner(); - } - // Create a zone object from the zone address. - PausableZone zone = PausableZone(pausableZoneAddress); - - // Call assignOperator on the zone by passing in the given - // operator address. - zone.assignOperator(operatorToAssign); - } - - /** - * @notice An external view function that returns the owner. - * - * @return The address of the owner. - */ - function owner() external view override returns (address) { - return _owner; - } - - /** - * @notice An external view function that return the potential owner. - * - * @return The address of the potential owner. - */ - function potentialOwner() external view override returns (address) { - return _potentialOwner; - } - - /** - * @notice An external view function that returns the pauser. - * - * @return The address of the pauser. - */ - function pauser() external view override returns (address) { - return _pauser; - } -} +import "seaport/contracts/zones/PausableZoneController.sol"; diff --git a/contracts/seaport/Zones/PausableZoneControllerInterface.sol b/contracts/seaport/Zones/PausableZoneControllerInterface.sol deleted file mode 100644 index 0a58c9c7..00000000 --- a/contracts/seaport/Zones/PausableZoneControllerInterface.sol +++ /dev/null @@ -1,176 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.7; - -import { PausableZone } from "./PausableZone.sol"; - -// prettier-ignore -import { - PausableZoneEventsAndErrors -} from "./PausableZoneEventsAndErrors.sol"; - -// prettier-ignore -import { - Order, - Fulfillment, - OrderComponents, - AdvancedOrder, - CriteriaResolver, - Execution -} from "seaport/contracts/lib/ConsiderationStructs.sol"; - -import { SeaportInterface } from "seaport/contracts/interfaces/SeaportInterface.sol"; - -/** - * @title PausableZoneController - * @author cupOJoseph, BCLeFevre, stuckinaboot - * @notice PausableZoneController enables deploying, pausing and executing - * orders on PausableZones. This deployer is designed to be owned - * by a gnosis safe, DAO, or trusted party. - */ -interface PausableZoneControllerInterface { - /** - * @notice Deploy a PausableZone to a precomputed address. - * - * @param salt The salt to be used to derive the zone address - * - * @return derivedAddress The derived address for the zone. - */ - function createZone(bytes32 salt) external returns (address derivedAddress); - - /** - * @notice Pause orders on a given zone. - * - * @param zone The address of the zone to be paused. - * - * @return success A boolean indicating the zone has been paused. - */ - function pause(address zone) external returns (bool success); - - /** - * @notice Cancel Seaport offers on a given zone. - * - * @param pausableZoneAddress The zone that manages the orders to be - * cancelled. - * @param seaportAddress The Seaport address. - * @param orders The orders to cancel. - */ - function cancelOrders( - address pausableZoneAddress, - SeaportInterface seaportAddress, - OrderComponents[] calldata orders - ) external; - - /** - * @notice Execute an arbitrary number of matched orders on a given zone. - * - * @param pausableZoneAddress The zone that manages the orders to be - * cancelled. - * @param seaportAddress The Seaport address. - * @param orders The orders to match. - * @param fulfillments An array of elements allocating offer - * components to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchOrders( - address pausableZoneAddress, - SeaportInterface seaportAddress, - Order[] calldata orders, - Fulfillment[] calldata fulfillments - ) external payable returns (Execution[] memory executions); - - /** - * @notice Execute an arbitrary number of matched advanced orders on a - * given zone. - * - * @param pausableZoneAddress The zone that manages the orders to be - * cancelled. - * @param seaportAddress The Seaport address. - * @param orders The orders to match. - * @param criteriaResolvers An array where each element contains a - * reference to a specific order as well as - * that order's offer or consideration, - * a token identifier, and a proof that - * the supplied token identifier is - * contained in the order's merkle root. - * @param fulfillments An array of elements allocating offer - * components to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchAdvancedOrders( - address pausableZoneAddress, - SeaportInterface seaportAddress, - AdvancedOrder[] calldata orders, - CriteriaResolver[] calldata criteriaResolvers, - Fulfillment[] calldata fulfillments - ) external payable returns (Execution[] memory executions); - - /** - * @notice Initiate Zone ownership transfer by assigning a new potential - * owner this contract. Once set, the new potential owner - * may call `acceptOwnership` to claim ownership. - * Only the owner in question may call this function. - * - * @param newPotentialOwner The address for which to initiate ownership - * transfer to. - */ - function transferOwnership(address newPotentialOwner) external; - - /** - * @notice Clear the currently set potential owner, if any. - * Only the owner of this contract may call this function. - */ - function cancelOwnershipTransfer() external; - - /** - * @notice Accept ownership of this contract. Only the account that the - * current owner has set as the new potential owner may call this - * function. - */ - function acceptOwnership() external; - - /** - * @notice Assign the given address with the ability to pause the zone. - * - * @param pauserToAssign The address to assign the pauser role. - */ - function assignPauser(address pauserToAssign) external; - - /** - * @notice Assign the given address with the ability to operate the - * given zone. - * - * @param pausableZoneAddress The zone address to assign operator role. - * @param operatorToAssign The address to assign as operator. - */ - function assignOperator( - address pausableZoneAddress, - address operatorToAssign - ) external; - - /** - * @notice An external view function that returns the owner. - * - * @return The address of the owner. - */ - function owner() external view returns (address); - - /** - * @notice An external view function that return the potential owner. - * - * @return The address of the potential owner. - */ - function potentialOwner() external view returns (address); - - /** - * @notice An external view function that returns the pauser. - * - * @return The address of the pauser. - */ - function pauser() external view returns (address); -} diff --git a/contracts/seaport/Zones/PausableZoneEventsAndErrors.sol b/contracts/seaport/Zones/PausableZoneEventsAndErrors.sol deleted file mode 100644 index ffe14f7a..00000000 --- a/contracts/seaport/Zones/PausableZoneEventsAndErrors.sol +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.7; - -/** - * @notice PausableZoneEventsAndErrors contains errors and events - * related to zone interaction. - */ -interface PausableZoneEventsAndErrors { - /** - * @dev Emit an event whenever a zone is successfully paused. - */ - event Paused(); - - /** - * @dev Emit an event whenever a zone is successfully unpaused (created). - */ - event Unpaused(); - - /** - * @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 newPotentialOwner); - - /** - * @dev Emit an event whenever zone ownership is transferred. - * - * @param previousOwner The previous owner of the zone. - * @param newOwner The new owner of the zone. - */ - event OwnershipTransferred(address previousOwner, address newOwner); - - /** - * @dev Emit an event whenever a new zone is created. - * - * @param zone The address of the zone. - * @param salt The salt used to deploy the zone. - */ - event ZoneCreated(address zone, bytes32 salt); - - /** - * @dev Emit an event whenever a zone owner assigns a new pauser - * - * @param newPauser The new pausear of the zone. - */ - event PauserUpdated(address newPauser); - - /** - * @dev Emit an event whenever a zone owner assigns a new operator - * - * @param newOperator The new operator of the zone. - */ - event OperatorUpdated(address newOperator); - - /** - * @dev Revert with an error when attempting to pause the zone - * while the caller is not the owner or pauser of the zone. - */ - error InvalidPauser(); - - /** - * @dev Revert with an error when attempting to call an operation - * while the caller is not the controller or operator of the zone. - */ - error InvalidOperator(); - - /** - * @dev Revert with an error when attempting to pause the zone or update the - * operator while the caller is not the controller of the zone. - */ - error InvalidController(); - /** - * @dev Revert with an error when attempting to deploy a zone that is - * currently deployed. - */ - error ZoneAlreadyExists(address zone); - - /** - * @dev Revert with an error when the caller does not have the _owner role - * - */ - error CallerIsNotOwner(); - - /** - * @dev Revert with an error when the caller does not have the operator role - * - */ - error CallerIsNotOperator(); - - /** - * @dev Revert with an error when attempting to set the new potential owner - * as the 0 address. - * - */ - error OwnerCanNotBeSetAsZero(); - - /** - * @dev Revert with an error when attempting to set the new potential pauser - * as the 0 address. - * - */ - error PauserCanNotBeSetAsZero(); - - /** - * @dev Revert with an error when the caller does not have - * the potentialOwner role. - */ - error CallerIsNotPotentialOwner(); -} diff --git a/contracts/seaport/Zones/PausableZoneInterface.sol b/contracts/seaport/Zones/PausableZoneInterface.sol deleted file mode 100644 index 029359c5..00000000 --- a/contracts/seaport/Zones/PausableZoneInterface.sol +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.7; - -import { SeaportInterface } from "seaport/contracts/interfaces/SeaportInterface.sol"; - -// prettier-ignore -import { - AdvancedOrder, - CriteriaResolver, - Order, - OrderComponents, - Fulfillment, - Execution -} from "seaport/contracts/lib/ConsiderationStructs.sol"; - -/** - * @title PausableZone - * @author cupOJoseph, BCLeFevre, ryanio - * @notice PausableZone is a simple zone implementation that approves every - * order. It can be self-destructed by its controller to pause - * restricted orders that have it set as their zone. - */ -interface PausableZoneInterface { - /** - * @notice Cancel an arbitrary number of orders that have agreed to use the - * contract as their zone. - * - * @param seaport The Seaport address. - * @param orders The orders to cancel. - * - * @return cancelled A boolean indicating whether the supplied orders have - * been successfully cancelled. - */ - function cancelOrders( - SeaportInterface seaport, - OrderComponents[] calldata orders - ) external returns (bool cancelled); - - /** - * @notice Execute an arbitrary number of matched orders, each with - * an arbitrary number of items for offer and consideration - * along with a set of fulfillments allocating offer components - * to consideration components. - * - * @param seaport The Seaport address. - * @param orders The orders to match. - * @param fulfillments An array of elements allocating offer components - * to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchOrders( - SeaportInterface seaport, - Order[] calldata orders, - Fulfillment[] calldata fulfillments - ) external payable returns (Execution[] memory executions); - - /** - * @notice Execute an arbitrary number of matched advanced orders, - * each with an arbitrary number of items for offer and - * consideration along with a set of fulfillments allocating - * offer components to consideration components. - * - * @param seaport The Seaport address. - * @param orders The orders to match. - * @param criteriaResolvers An array where each element contains a reference - * to a specific order as well as that order's - * offer or consideration, a token identifier, and - * a proof that the supplied token identifier is - * contained in the order's merkle root. - * @param fulfillments An array of elements allocating offer components - * to consideration components. - * - * @return executions An array of elements indicating the sequence of - * transfers performed as part of matching the given - * orders. - */ - function executeMatchAdvancedOrders( - SeaportInterface seaport, - AdvancedOrder[] calldata orders, - CriteriaResolver[] calldata criteriaResolvers, - Fulfillment[] calldata fulfillments - ) external payable returns (Execution[] memory executions); - - /** - * @notice Pause this contract, safely stopping orders from using - * the contract as a zone. Restricted orders with this address as a - * zone will not be fulfillable unless the zone is redeployed to the - * same address. - */ - function pause(address payee) external; - - /** - * @notice Assign the given address with the ability to operate the zone. - * - * @param operatorToAssign The address to assign as the operator. - */ - function assignOperator(address operatorToAssign) external; -} diff --git a/contracts/test/TestZone.sol b/contracts/test/TestZone.sol index 780ae68a..0ad80910 100644 --- a/contracts/test/TestZone.sol +++ b/contracts/test/TestZone.sol @@ -6,56 +6,16 @@ import { ZoneInterface } from "seaport/contracts/interfaces/ZoneInterface.sol"; // prettier-ignore import { AdvancedOrder, - CriteriaResolver + CriteriaResolver, + ZoneParameters } from "seaport/contracts/lib/ConsiderationStructs.sol"; contract TestZone is ZoneInterface { - function isValidOrder( - bytes32 orderHash, - address caller, - address offerer, - bytes32 zoneHash - ) external pure override returns (bytes4 validOrderMagicValue) { - orderHash; - caller; - offerer; - - if (zoneHash == bytes32(uint256(1))) { - revert("Revert on zone hash 1"); - } else if (zoneHash == bytes32(uint256(2))) { - assembly { - revert(0, 0) - } - } - - validOrderMagicValue = zoneHash != bytes32(uint256(3)) - ? ZoneInterface.isValidOrder.selector - : bytes4(0xffffffff); - } - - function isValidOrderIncludingExtraData( - bytes32 orderHash, - address caller, - AdvancedOrder calldata order, - bytes32[] calldata priorOrderHashes, - CriteriaResolver[] calldata criteriaResolvers - ) external pure override returns (bytes4 validOrderMagicValue) { - orderHash; - caller; - order; - priorOrderHashes; - criteriaResolvers; - - if (order.extraData.length == 4) { - revert("Revert on extraData length 4"); - } else if (order.extraData.length == 5) { - assembly { - revert(0, 0) - } - } - - validOrderMagicValue = order.parameters.zoneHash != bytes32(uint256(3)) - ? ZoneInterface.isValidOrder.selector - : bytes4(0xffffffff); + // Called by Consideration whenever any extraData is provided by the caller. + function validateOrder( + ZoneParameters calldata zoneParameters + ) external returns (bytes4 validOrderMagicValue) { + // revert(hex"696969696969"); + return ZoneInterface.validateOrder.selector; } } diff --git a/deployments/goerli/solcInputs/6d132c08ea5855a8db9ad1d8958352e3.json b/deployments/goerli/solcInputs/6d132c08ea5855a8db9ad1d8958352e3.json deleted file mode 100644 index 1d66e827..00000000 --- a/deployments/goerli/solcInputs/6d132c08ea5855a8db9ad1d8958352e3.json +++ /dev/null @@ -1,309 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "contracts/seaport/Conduit.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport \"seaport/contracts/conduit/Conduit.sol\";" - }, - "seaport/contracts/conduit/Conduit.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport { ConduitInterface } from \"../interfaces/ConduitInterface.sol\";\n\nimport { ConduitItemType } from \"./lib/ConduitEnums.sol\";\n\nimport { TokenTransferrer } from \"../lib/TokenTransferrer.sol\";\n\n// prettier-ignore\nimport {\n ConduitTransfer,\n ConduitBatch1155Transfer\n} from \"./lib/ConduitStructs.sol\";\n\nimport \"./lib/ConduitConstants.sol\";\n\n/**\n * @title Conduit\n * @author 0age\n * @notice This contract serves as an originator for \"proxied\" transfers. Each\n * conduit is deployed and controlled by a \"conduit controller\" that can\n * add and remove \"channels\" or contracts that can instruct the conduit\n * to transfer approved ERC20/721/1155 tokens. *IMPORTANT NOTE: each\n * conduit has an owner that can arbitrarily add or remove channels, and\n * a malicious or negligent owner can add a channel that allows for any\n * approved ERC20/721/1155 tokens to be taken immediately — be extremely\n * cautious with what conduits you give token approvals to!*\n */\ncontract Conduit is ConduitInterface, TokenTransferrer {\n // Set deployer as an immutable controller that can update channel statuses.\n address private immutable _controller;\n\n // Track the status of each channel.\n mapping(address => bool) private _channels;\n\n /**\n * @notice Ensure that the caller is currently registered as an open channel\n * on the conduit.\n */\n modifier onlyOpenChannel() {\n // Utilize assembly to access channel storage mapping directly.\n assembly {\n // Write the caller to scratch space.\n mstore(ChannelKey_channel_ptr, caller())\n\n // Write the storage slot for _channels to scratch space.\n mstore(ChannelKey_slot_ptr, _channels.slot)\n\n // Derive the position in storage of _channels[msg.sender]\n // and check if the stored value is zero.\n if iszero(\n sload(keccak256(ChannelKey_channel_ptr, ChannelKey_length))\n ) {\n // The caller is not an open channel; revert with\n // ChannelClosed(caller). First, set error signature in memory.\n mstore(ChannelClosed_error_ptr, ChannelClosed_error_signature)\n\n // Next, set the caller as the argument.\n mstore(ChannelClosed_channel_ptr, caller())\n\n // Finally, revert, returning full custom error with argument.\n revert(ChannelClosed_error_ptr, ChannelClosed_error_length)\n }\n }\n\n // Continue with function execution.\n _;\n }\n\n /**\n * @notice In the constructor, set the deployer as the controller.\n */\n constructor() {\n // Set the deployer as the controller.\n _controller = msg.sender;\n }\n\n /**\n * @notice Execute a sequence of ERC20/721/1155 transfers. Only a caller\n * with an open channel can call this function. Note that channels\n * are expected to implement reentrancy protection if desired, and\n * that cross-channel reentrancy may be possible if the conduit has\n * multiple open channels at once. Also note that channels are\n * expected to implement checks against transferring any zero-amount\n * items if that constraint is desired.\n *\n * @param transfers The ERC20/721/1155 transfers to perform.\n *\n * @return magicValue A magic value indicating that the transfers were\n * performed successfully.\n */\n function execute(ConduitTransfer[] calldata transfers)\n external\n override\n onlyOpenChannel\n returns (bytes4 magicValue)\n {\n // Retrieve the total number of transfers and place on the stack.\n uint256 totalStandardTransfers = transfers.length;\n\n // Iterate over each transfer.\n for (uint256 i = 0; i < totalStandardTransfers; ) {\n // Retrieve the transfer in question and perform the transfer.\n _transfer(transfers[i]);\n\n // Skip overflow check as for loop is indexed starting at zero.\n unchecked {\n ++i;\n }\n }\n\n // Return a magic value indicating that the transfers were performed.\n magicValue = this.execute.selector;\n }\n\n /**\n * @notice Execute a sequence of batch 1155 item transfers. Only a caller\n * with an open channel can call this function. Note that channels\n * are expected to implement reentrancy protection if desired, and\n * that cross-channel reentrancy may be possible if the conduit has\n * multiple open channels at once. Also note that channels are\n * expected to implement checks against transferring any zero-amount\n * items if that constraint is desired.\n *\n * @param batchTransfers The 1155 batch item transfers to perform.\n *\n * @return magicValue A magic value indicating that the item transfers were\n * performed successfully.\n */\n function executeBatch1155(\n ConduitBatch1155Transfer[] calldata batchTransfers\n ) external override onlyOpenChannel returns (bytes4 magicValue) {\n // Perform 1155 batch transfers. Note that memory should be considered\n // entirely corrupted from this point forward.\n _performERC1155BatchTransfers(batchTransfers);\n\n // Return a magic value indicating that the transfers were performed.\n magicValue = this.executeBatch1155.selector;\n }\n\n /**\n * @notice Execute a sequence of transfers, both single ERC20/721/1155 item\n * transfers as well as batch 1155 item transfers. Only a caller\n * with an open channel can call this function. Note that channels\n * are expected to implement reentrancy protection if desired, and\n * that cross-channel reentrancy may be possible if the conduit has\n * multiple open channels at once. Also note that channels are\n * expected to implement checks against transferring any zero-amount\n * items if that constraint is desired.\n *\n * @param standardTransfers The ERC20/721/1155 item transfers to perform.\n * @param batchTransfers The 1155 batch item transfers to perform.\n *\n * @return magicValue A magic value indicating that the item transfers were\n * performed successfully.\n */\n function executeWithBatch1155(\n ConduitTransfer[] calldata standardTransfers,\n ConduitBatch1155Transfer[] calldata batchTransfers\n ) external override onlyOpenChannel returns (bytes4 magicValue) {\n // Retrieve the total number of transfers and place on the stack.\n uint256 totalStandardTransfers = standardTransfers.length;\n\n // Iterate over each standard transfer.\n for (uint256 i = 0; i < totalStandardTransfers; ) {\n // Retrieve the transfer in question and perform the transfer.\n _transfer(standardTransfers[i]);\n\n // Skip overflow check as for loop is indexed starting at zero.\n unchecked {\n ++i;\n }\n }\n\n // Perform 1155 batch transfers. Note that memory should be considered\n // entirely corrupted from this point forward aside from the free memory\n // pointer having the default value.\n _performERC1155BatchTransfers(batchTransfers);\n\n // Return a magic value indicating that the transfers were performed.\n magicValue = this.executeWithBatch1155.selector;\n }\n\n /**\n * @notice Open or close a given channel. Only callable by the controller.\n *\n * @param channel The channel to open or close.\n * @param isOpen The status of the channel (either open or closed).\n */\n function updateChannel(address channel, bool isOpen) external override {\n // Ensure that the caller is the controller of this contract.\n if (msg.sender != _controller) {\n revert InvalidController();\n }\n\n // Ensure that the channel does not already have the indicated status.\n if (_channels[channel] == isOpen) {\n revert ChannelStatusAlreadySet(channel, isOpen);\n }\n\n // Update the status of the channel.\n _channels[channel] = isOpen;\n\n // Emit a corresponding event.\n emit ChannelUpdated(channel, isOpen);\n }\n\n /**\n * @dev Internal function to transfer a given ERC20/721/1155 item. Note that\n * channels are expected to implement checks against transferring any\n * zero-amount items if that constraint is desired.\n *\n * @param item The ERC20/721/1155 item to transfer.\n */\n function _transfer(ConduitTransfer calldata item) internal {\n // Determine the transfer method based on the respective item type.\n if (item.itemType == ConduitItemType.ERC20) {\n // Transfer ERC20 token. Note that item.identifier is ignored and\n // therefore ERC20 transfer items are potentially malleable — this\n // check should be performed by the calling channel if a constraint\n // on item malleability is desired.\n _performERC20Transfer(item.token, item.from, item.to, item.amount);\n } else if (item.itemType == ConduitItemType.ERC721) {\n // Ensure that exactly one 721 item is being transferred.\n if (item.amount != 1) {\n revert InvalidERC721TransferAmount();\n }\n\n // Transfer ERC721 token.\n _performERC721Transfer(\n item.token,\n item.from,\n item.to,\n item.identifier\n );\n } else if (item.itemType == ConduitItemType.ERC1155) {\n // Transfer ERC1155 token.\n _performERC1155Transfer(\n item.token,\n item.from,\n item.to,\n item.identifier,\n item.amount\n );\n } else {\n // Throw with an error.\n revert InvalidItemType();\n }\n }\n}\n" - }, - "seaport/contracts/interfaces/ConduitInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// prettier-ignore\nimport {\n ConduitTransfer,\n ConduitBatch1155Transfer\n} from \"../conduit/lib/ConduitStructs.sol\";\n\n/**\n * @title ConduitInterface\n * @author 0age\n * @notice ConduitInterface contains all external function interfaces, events,\n * and errors for conduit contracts.\n */\ninterface ConduitInterface {\n /**\n * @dev Revert with an error when attempting to execute transfers using a\n * caller that does not have an open channel.\n */\n error ChannelClosed(address channel);\n\n /**\n * @dev Revert with an error when attempting to update a channel to the\n * current status of that channel.\n */\n error ChannelStatusAlreadySet(address channel, bool isOpen);\n\n /**\n * @dev Revert with an error when attempting to execute a transfer for an\n * item that does not have an ERC20/721/1155 item type.\n */\n error InvalidItemType();\n\n /**\n * @dev Revert with an error when attempting to update the status of a\n * channel from a caller that is not the conduit controller.\n */\n error InvalidController();\n\n /**\n * @dev Emit an event whenever a channel is opened or closed.\n *\n * @param channel The channel that has been updated.\n * @param open A boolean indicating whether the conduit is open or not.\n */\n event ChannelUpdated(address indexed channel, bool open);\n\n /**\n * @notice Execute a sequence of ERC20/721/1155 transfers. Only a caller\n * with an open channel can call this function.\n *\n * @param transfers The ERC20/721/1155 transfers to perform.\n *\n * @return magicValue A magic value indicating that the transfers were\n * performed successfully.\n */\n function execute(ConduitTransfer[] calldata transfers)\n external\n returns (bytes4 magicValue);\n\n /**\n * @notice Execute a sequence of batch 1155 transfers. Only a caller with an\n * open channel can call this function.\n *\n * @param batch1155Transfers The 1155 batch transfers to perform.\n *\n * @return magicValue A magic value indicating that the transfers were\n * performed successfully.\n */\n function executeBatch1155(\n ConduitBatch1155Transfer[] calldata batch1155Transfers\n ) external returns (bytes4 magicValue);\n\n /**\n * @notice Execute a sequence of transfers, both single and batch 1155. Only\n * a caller with an open channel can call this function.\n *\n * @param standardTransfers The ERC20/721/1155 transfers to perform.\n * @param batch1155Transfers The 1155 batch transfers to perform.\n *\n * @return magicValue A magic value indicating that the transfers were\n * performed successfully.\n */\n function executeWithBatch1155(\n ConduitTransfer[] calldata standardTransfers,\n ConduitBatch1155Transfer[] calldata batch1155Transfers\n ) external returns (bytes4 magicValue);\n\n /**\n * @notice Open or close a given channel. Only callable by the controller.\n *\n * @param channel The channel to open or close.\n * @param isOpen The status of the channel (either open or closed).\n */\n function updateChannel(address channel, bool isOpen) external;\n}\n" - }, - "seaport/contracts/conduit/lib/ConduitEnums.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nenum ConduitItemType {\n NATIVE, // unused\n ERC20,\n ERC721,\n ERC1155\n}\n" - }, - "seaport/contracts/lib/TokenTransferrer.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport \"./TokenTransferrerConstants.sol\";\n\n// prettier-ignore\nimport {\n TokenTransferrerErrors\n} from \"../interfaces/TokenTransferrerErrors.sol\";\n\nimport { ConduitBatch1155Transfer } from \"../conduit/lib/ConduitStructs.sol\";\n\n/**\n * @title TokenTransferrer\n * @author 0age\n * @custom:coauthor d1ll0n\n * @custom:coauthor transmissions11\n * @notice TokenTransferrer is a library for performing optimized ERC20, ERC721,\n * ERC1155, and batch ERC1155 transfers, used by both Seaport as well as\n * by conduits deployed by the ConduitController. Use great caution when\n * considering these functions for use in other codebases, as there are\n * significant side effects and edge cases that need to be thoroughly\n * understood and carefully addressed.\n */\ncontract TokenTransferrer is TokenTransferrerErrors {\n /**\n * @dev Internal function to transfer ERC20 tokens from a given originator\n * to a given recipient. Sufficient approvals must be set on the\n * contract performing the transfer.\n *\n * @param token The ERC20 token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param amount The amount to transfer.\n */\n function _performERC20Transfer(\n address token,\n address from,\n address to,\n uint256 amount\n ) internal {\n // Utilize assembly to perform an optimized ERC20 token transfer.\n assembly {\n // The free memory pointer memory slot will be used when populating\n // call data for the transfer; read the value and restore it later.\n let memPointer := mload(FreeMemoryPointerSlot)\n\n // Write call data into memory, starting with function selector.\n mstore(ERC20_transferFrom_sig_ptr, ERC20_transferFrom_signature)\n mstore(ERC20_transferFrom_from_ptr, from)\n mstore(ERC20_transferFrom_to_ptr, to)\n mstore(ERC20_transferFrom_amount_ptr, amount)\n\n // Make call & copy up to 32 bytes of return data to scratch space.\n // Scratch space does not need to be cleared ahead of time, as the\n // subsequent check will ensure that either at least a full word of\n // return data is received (in which case it will be overwritten) or\n // that no data is received (in which case scratch space will be\n // ignored) on a successful call to the given token.\n let callStatus := call(\n gas(),\n token,\n 0,\n ERC20_transferFrom_sig_ptr,\n ERC20_transferFrom_length,\n 0,\n OneWord\n )\n\n // Determine whether transfer was successful using status & result.\n let success := and(\n // Set success to whether the call reverted, if not check it\n // either returned exactly 1 (can't just be non-zero data), or\n // had no return data.\n or(\n and(eq(mload(0), 1), gt(returndatasize(), 31)),\n iszero(returndatasize())\n ),\n callStatus\n )\n\n // Handle cases where either the transfer failed or no data was\n // returned. Group these, as most transfers will succeed with data.\n // Equivalent to `or(iszero(success), iszero(returndatasize()))`\n // but after it's inverted for JUMPI this expression is cheaper.\n if iszero(and(success, iszero(iszero(returndatasize())))) {\n // If the token has no code or the transfer failed: Equivalent\n // to `or(iszero(success), iszero(extcodesize(token)))` but\n // after it's inverted for JUMPI this expression is cheaper.\n if iszero(and(iszero(iszero(extcodesize(token))), success)) {\n // If the transfer failed:\n if iszero(success) {\n // If it was due to a revert:\n if iszero(callStatus) {\n // If it returned a message, bubble it up as long as\n // sufficient gas remains to do so:\n if returndatasize() {\n // Ensure that sufficient gas is available to\n // copy returndata while expanding memory where\n // necessary. Start by computing the word size\n // of returndata and allocated memory. Round up\n // to the nearest full word.\n let returnDataWords := div(\n add(returndatasize(), AlmostOneWord),\n OneWord\n )\n\n // Note: use the free memory pointer in place of\n // msize() to work around a Yul warning that\n // prevents accessing msize directly when the IR\n // pipeline is activated.\n let msizeWords := div(memPointer, OneWord)\n\n // Next, compute the cost of the returndatacopy.\n let cost := mul(CostPerWord, returnDataWords)\n\n // Then, compute cost of new memory allocation.\n if gt(returnDataWords, msizeWords) {\n cost := add(\n cost,\n add(\n mul(\n sub(\n returnDataWords,\n msizeWords\n ),\n CostPerWord\n ),\n div(\n sub(\n mul(\n returnDataWords,\n returnDataWords\n ),\n mul(msizeWords, msizeWords)\n ),\n MemoryExpansionCoefficient\n )\n )\n )\n }\n\n // Finally, add a small constant and compare to\n // gas remaining; bubble up the revert data if\n // enough gas is still available.\n if lt(add(cost, ExtraGasBuffer), gas()) {\n // Copy returndata to memory; overwrite\n // existing memory.\n returndatacopy(0, 0, returndatasize())\n\n // Revert, specifying memory region with\n // copied returndata.\n revert(0, returndatasize())\n }\n }\n\n // Otherwise revert with a generic error message.\n mstore(\n TokenTransferGenericFailure_error_sig_ptr,\n TokenTransferGenericFailure_error_signature\n )\n mstore(\n TokenTransferGenericFailure_error_token_ptr,\n token\n )\n mstore(\n TokenTransferGenericFailure_error_from_ptr,\n from\n )\n mstore(TokenTransferGenericFailure_error_to_ptr, to)\n mstore(TokenTransferGenericFailure_error_id_ptr, 0)\n mstore(\n TokenTransferGenericFailure_error_amount_ptr,\n amount\n )\n revert(\n TokenTransferGenericFailure_error_sig_ptr,\n TokenTransferGenericFailure_error_length\n )\n }\n\n // Otherwise revert with a message about the token\n // returning false or non-compliant return values.\n mstore(\n BadReturnValueFromERC20OnTransfer_error_sig_ptr,\n BadReturnValueFromERC20OnTransfer_error_signature\n )\n mstore(\n BadReturnValueFromERC20OnTransfer_error_token_ptr,\n token\n )\n mstore(\n BadReturnValueFromERC20OnTransfer_error_from_ptr,\n from\n )\n mstore(\n BadReturnValueFromERC20OnTransfer_error_to_ptr,\n to\n )\n mstore(\n BadReturnValueFromERC20OnTransfer_error_amount_ptr,\n amount\n )\n revert(\n BadReturnValueFromERC20OnTransfer_error_sig_ptr,\n BadReturnValueFromERC20OnTransfer_error_length\n )\n }\n\n // Otherwise, revert with error about token not having code:\n mstore(NoContract_error_sig_ptr, NoContract_error_signature)\n mstore(NoContract_error_token_ptr, token)\n revert(NoContract_error_sig_ptr, NoContract_error_length)\n }\n\n // Otherwise, the token just returned no data despite the call\n // having succeeded; no need to optimize for this as it's not\n // technically ERC20 compliant.\n }\n\n // Restore the original free memory pointer.\n mstore(FreeMemoryPointerSlot, memPointer)\n\n // Restore the zero slot to zero.\n mstore(ZeroSlot, 0)\n }\n }\n\n /**\n * @dev Internal function to transfer an ERC721 token from a given\n * originator to a given recipient. Sufficient approvals must be set on\n * the contract performing the transfer. Note that this function does\n * not check whether the receiver can accept the ERC721 token (i.e. it\n * does not use `safeTransferFrom`).\n *\n * @param token The ERC721 token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param identifier The tokenId to transfer.\n */\n function _performERC721Transfer(\n address token,\n address from,\n address to,\n uint256 identifier\n ) internal {\n // Utilize assembly to perform an optimized ERC721 token transfer.\n assembly {\n // If the token has no code, revert.\n if iszero(extcodesize(token)) {\n mstore(NoContract_error_sig_ptr, NoContract_error_signature)\n mstore(NoContract_error_token_ptr, token)\n revert(NoContract_error_sig_ptr, NoContract_error_length)\n }\n\n // The free memory pointer memory slot will be used when populating\n // call data for the transfer; read the value and restore it later.\n let memPointer := mload(FreeMemoryPointerSlot)\n\n // Write call data to memory starting with function selector.\n mstore(ERC721_transferFrom_sig_ptr, ERC721_transferFrom_signature)\n mstore(ERC721_transferFrom_from_ptr, from)\n mstore(ERC721_transferFrom_to_ptr, to)\n mstore(ERC721_transferFrom_id_ptr, identifier)\n\n // Perform the call, ignoring return data.\n let success := call(\n gas(),\n token,\n 0,\n ERC721_transferFrom_sig_ptr,\n ERC721_transferFrom_length,\n 0,\n 0\n )\n\n // If the transfer reverted:\n if iszero(success) {\n // If it returned a message, bubble it up as long as sufficient\n // gas remains to do so:\n if returndatasize() {\n // Ensure that sufficient gas is available to copy\n // returndata while expanding memory where necessary. Start\n // by computing word size of returndata & allocated memory.\n // Round up to the nearest full word.\n let returnDataWords := div(\n add(returndatasize(), AlmostOneWord),\n OneWord\n )\n\n // Note: use the free memory pointer in place of msize() to\n // work around a Yul warning that prevents accessing msize\n // directly when the IR pipeline is activated.\n let msizeWords := div(memPointer, OneWord)\n\n // Next, compute the cost of the returndatacopy.\n let cost := mul(CostPerWord, returnDataWords)\n\n // Then, compute cost of new memory allocation.\n if gt(returnDataWords, msizeWords) {\n cost := add(\n cost,\n add(\n mul(\n sub(returnDataWords, msizeWords),\n CostPerWord\n ),\n div(\n sub(\n mul(returnDataWords, returnDataWords),\n mul(msizeWords, msizeWords)\n ),\n MemoryExpansionCoefficient\n )\n )\n )\n }\n\n // Finally, add a small constant and compare to gas\n // remaining; bubble up the revert data if enough gas is\n // still available.\n if lt(add(cost, ExtraGasBuffer), gas()) {\n // Copy returndata to memory; overwrite existing memory.\n returndatacopy(0, 0, returndatasize())\n\n // Revert, giving memory region with copied returndata.\n revert(0, returndatasize())\n }\n }\n\n // Otherwise revert with a generic error message.\n mstore(\n TokenTransferGenericFailure_error_sig_ptr,\n TokenTransferGenericFailure_error_signature\n )\n mstore(TokenTransferGenericFailure_error_token_ptr, token)\n mstore(TokenTransferGenericFailure_error_from_ptr, from)\n mstore(TokenTransferGenericFailure_error_to_ptr, to)\n mstore(TokenTransferGenericFailure_error_id_ptr, identifier)\n mstore(TokenTransferGenericFailure_error_amount_ptr, 1)\n revert(\n TokenTransferGenericFailure_error_sig_ptr,\n TokenTransferGenericFailure_error_length\n )\n }\n\n // Restore the original free memory pointer.\n mstore(FreeMemoryPointerSlot, memPointer)\n\n // Restore the zero slot to zero.\n mstore(ZeroSlot, 0)\n }\n }\n\n /**\n * @dev Internal function to transfer ERC1155 tokens from a given\n * originator to a given recipient. Sufficient approvals must be set on\n * the contract performing the transfer and contract recipients must\n * implement the ERC1155TokenReceiver interface to indicate that they\n * are willing to accept the transfer.\n *\n * @param token The ERC1155 token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param identifier The id to transfer.\n * @param amount The amount to transfer.\n */\n function _performERC1155Transfer(\n address token,\n address from,\n address to,\n uint256 identifier,\n uint256 amount\n ) internal {\n // Utilize assembly to perform an optimized ERC1155 token transfer.\n assembly {\n // If the token has no code, revert.\n if iszero(extcodesize(token)) {\n mstore(NoContract_error_sig_ptr, NoContract_error_signature)\n mstore(NoContract_error_token_ptr, token)\n revert(NoContract_error_sig_ptr, NoContract_error_length)\n }\n\n // The following memory slots will be used when populating call data\n // for the transfer; read the values and restore them later.\n let memPointer := mload(FreeMemoryPointerSlot)\n let slot0x80 := mload(Slot0x80)\n let slot0xA0 := mload(Slot0xA0)\n let slot0xC0 := mload(Slot0xC0)\n\n // Write call data into memory, beginning with function selector.\n mstore(\n ERC1155_safeTransferFrom_sig_ptr,\n ERC1155_safeTransferFrom_signature\n )\n mstore(ERC1155_safeTransferFrom_from_ptr, from)\n mstore(ERC1155_safeTransferFrom_to_ptr, to)\n mstore(ERC1155_safeTransferFrom_id_ptr, identifier)\n mstore(ERC1155_safeTransferFrom_amount_ptr, amount)\n mstore(\n ERC1155_safeTransferFrom_data_offset_ptr,\n ERC1155_safeTransferFrom_data_length_offset\n )\n mstore(ERC1155_safeTransferFrom_data_length_ptr, 0)\n\n // Perform the call, ignoring return data.\n let success := call(\n gas(),\n token,\n 0,\n ERC1155_safeTransferFrom_sig_ptr,\n ERC1155_safeTransferFrom_length,\n 0,\n 0\n )\n\n // If the transfer reverted:\n if iszero(success) {\n // If it returned a message, bubble it up as long as sufficient\n // gas remains to do so:\n if returndatasize() {\n // Ensure that sufficient gas is available to copy\n // returndata while expanding memory where necessary. Start\n // by computing word size of returndata & allocated memory.\n // Round up to the nearest full word.\n let returnDataWords := div(\n add(returndatasize(), AlmostOneWord),\n OneWord\n )\n\n // Note: use the free memory pointer in place of msize() to\n // work around a Yul warning that prevents accessing msize\n // directly when the IR pipeline is activated.\n let msizeWords := div(memPointer, OneWord)\n\n // Next, compute the cost of the returndatacopy.\n let cost := mul(CostPerWord, returnDataWords)\n\n // Then, compute cost of new memory allocation.\n if gt(returnDataWords, msizeWords) {\n cost := add(\n cost,\n add(\n mul(\n sub(returnDataWords, msizeWords),\n CostPerWord\n ),\n div(\n sub(\n mul(returnDataWords, returnDataWords),\n mul(msizeWords, msizeWords)\n ),\n MemoryExpansionCoefficient\n )\n )\n )\n }\n\n // Finally, add a small constant and compare to gas\n // remaining; bubble up the revert data if enough gas is\n // still available.\n if lt(add(cost, ExtraGasBuffer), gas()) {\n // Copy returndata to memory; overwrite existing memory.\n returndatacopy(0, 0, returndatasize())\n\n // Revert, giving memory region with copied returndata.\n revert(0, returndatasize())\n }\n }\n\n // Otherwise revert with a generic error message.\n mstore(\n TokenTransferGenericFailure_error_sig_ptr,\n TokenTransferGenericFailure_error_signature\n )\n mstore(TokenTransferGenericFailure_error_token_ptr, token)\n mstore(TokenTransferGenericFailure_error_from_ptr, from)\n mstore(TokenTransferGenericFailure_error_to_ptr, to)\n mstore(TokenTransferGenericFailure_error_id_ptr, identifier)\n mstore(TokenTransferGenericFailure_error_amount_ptr, amount)\n revert(\n TokenTransferGenericFailure_error_sig_ptr,\n TokenTransferGenericFailure_error_length\n )\n }\n\n mstore(Slot0x80, slot0x80) // Restore slot 0x80.\n mstore(Slot0xA0, slot0xA0) // Restore slot 0xA0.\n mstore(Slot0xC0, slot0xC0) // Restore slot 0xC0.\n\n // Restore the original free memory pointer.\n mstore(FreeMemoryPointerSlot, memPointer)\n\n // Restore the zero slot to zero.\n mstore(ZeroSlot, 0)\n }\n }\n\n /**\n * @dev Internal function to transfer ERC1155 tokens from a given\n * originator to a given recipient. Sufficient approvals must be set on\n * the contract performing the transfer and contract recipients must\n * implement the ERC1155TokenReceiver interface to indicate that they\n * are willing to accept the transfer. NOTE: this function is not\n * memory-safe; it will overwrite existing memory, restore the free\n * memory pointer to the default value, and overwrite the zero slot.\n * This function should only be called once memory is no longer\n * required and when uninitialized arrays are not utilized, and memory\n * should be considered fully corrupted (aside from the existence of a\n * default-value free memory pointer) after calling this function.\n *\n * @param batchTransfers The group of 1155 batch transfers to perform.\n */\n function _performERC1155BatchTransfers(\n ConduitBatch1155Transfer[] calldata batchTransfers\n ) internal {\n // Utilize assembly to perform optimized batch 1155 transfers.\n assembly {\n let len := batchTransfers.length\n // Pointer to first head in the array, which is offset to the struct\n // at each index. This gets incremented after each loop to avoid\n // multiplying by 32 to get the offset for each element.\n let nextElementHeadPtr := batchTransfers.offset\n\n // Pointer to beginning of the head of the array. This is the\n // reference position each offset references. It's held static to\n // let each loop calculate the data position for an element.\n let arrayHeadPtr := nextElementHeadPtr\n\n // Write the function selector, which will be reused for each call:\n // safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\n mstore(\n ConduitBatch1155Transfer_from_offset,\n ERC1155_safeBatchTransferFrom_signature\n )\n\n // Iterate over each batch transfer.\n for {\n let i := 0\n } lt(i, len) {\n i := add(i, 1)\n } {\n // Read the offset to the beginning of the element and add\n // it to pointer to the beginning of the array head to get\n // the absolute position of the element in calldata.\n let elementPtr := add(\n arrayHeadPtr,\n calldataload(nextElementHeadPtr)\n )\n\n // Retrieve the token from calldata.\n let token := calldataload(elementPtr)\n\n // If the token has no code, revert.\n if iszero(extcodesize(token)) {\n mstore(NoContract_error_sig_ptr, NoContract_error_signature)\n mstore(NoContract_error_token_ptr, token)\n revert(NoContract_error_sig_ptr, NoContract_error_length)\n }\n\n // Get the total number of supplied ids.\n let idsLength := calldataload(\n add(elementPtr, ConduitBatch1155Transfer_ids_length_offset)\n )\n\n // Determine the expected offset for the amounts array.\n let expectedAmountsOffset := add(\n ConduitBatch1155Transfer_amounts_length_baseOffset,\n mul(idsLength, OneWord)\n )\n\n // Validate struct encoding.\n let invalidEncoding := iszero(\n and(\n // ids.length == amounts.length\n eq(\n idsLength,\n calldataload(add(elementPtr, expectedAmountsOffset))\n ),\n and(\n // ids_offset == 0xa0\n eq(\n calldataload(\n add(\n elementPtr,\n ConduitBatch1155Transfer_ids_head_offset\n )\n ),\n ConduitBatch1155Transfer_ids_length_offset\n ),\n // amounts_offset == 0xc0 + ids.length*32\n eq(\n calldataload(\n add(\n elementPtr,\n ConduitBatchTransfer_amounts_head_offset\n )\n ),\n expectedAmountsOffset\n )\n )\n )\n )\n\n // Revert with an error if the encoding is not valid.\n if invalidEncoding {\n mstore(\n Invalid1155BatchTransferEncoding_ptr,\n Invalid1155BatchTransferEncoding_selector\n )\n revert(\n Invalid1155BatchTransferEncoding_ptr,\n Invalid1155BatchTransferEncoding_length\n )\n }\n\n // Update the offset position for the next loop\n nextElementHeadPtr := add(nextElementHeadPtr, OneWord)\n\n // Copy the first section of calldata (before dynamic values).\n calldatacopy(\n BatchTransfer1155Params_ptr,\n add(elementPtr, ConduitBatch1155Transfer_from_offset),\n ConduitBatch1155Transfer_usable_head_size\n )\n\n // Determine size of calldata required for ids and amounts. Note\n // that the size includes both lengths as well as the data.\n let idsAndAmountsSize := add(TwoWords, mul(idsLength, TwoWords))\n\n // Update the offset for the data array in memory.\n mstore(\n BatchTransfer1155Params_data_head_ptr,\n add(\n BatchTransfer1155Params_ids_length_offset,\n idsAndAmountsSize\n )\n )\n\n // Set the length of the data array in memory to zero.\n mstore(\n add(\n BatchTransfer1155Params_data_length_basePtr,\n idsAndAmountsSize\n ),\n 0\n )\n\n // Determine the total calldata size for the call to transfer.\n let transferDataSize := add(\n BatchTransfer1155Params_calldata_baseSize,\n idsAndAmountsSize\n )\n\n // Copy second section of calldata (including dynamic values).\n calldatacopy(\n BatchTransfer1155Params_ids_length_ptr,\n add(elementPtr, ConduitBatch1155Transfer_ids_length_offset),\n idsAndAmountsSize\n )\n\n // Perform the call to transfer 1155 tokens.\n let success := call(\n gas(),\n token,\n 0,\n ConduitBatch1155Transfer_from_offset, // Data portion start.\n transferDataSize, // Location of the length of callData.\n 0,\n 0\n )\n\n // If the transfer reverted:\n if iszero(success) {\n // If it returned a message, bubble it up as long as\n // sufficient gas remains to do so:\n if returndatasize() {\n // Ensure that sufficient gas is available to copy\n // returndata while expanding memory where necessary.\n // Start by computing word size of returndata and\n // allocated memory. Round up to the nearest full word.\n let returnDataWords := div(\n add(returndatasize(), AlmostOneWord),\n OneWord\n )\n\n // Note: use transferDataSize in place of msize() to\n // work around a Yul warning that prevents accessing\n // msize directly when the IR pipeline is activated.\n // The free memory pointer is not used here because\n // this function does almost all memory management\n // manually and does not update it, and transferDataSize\n // should be the largest memory value used (unless a\n // previous batch was larger).\n let msizeWords := div(transferDataSize, OneWord)\n\n // Next, compute the cost of the returndatacopy.\n let cost := mul(CostPerWord, returnDataWords)\n\n // Then, compute cost of new memory allocation.\n if gt(returnDataWords, msizeWords) {\n cost := add(\n cost,\n add(\n mul(\n sub(returnDataWords, msizeWords),\n CostPerWord\n ),\n div(\n sub(\n mul(\n returnDataWords,\n returnDataWords\n ),\n mul(msizeWords, msizeWords)\n ),\n MemoryExpansionCoefficient\n )\n )\n )\n }\n\n // Finally, add a small constant and compare to gas\n // remaining; bubble up the revert data if enough gas is\n // still available.\n if lt(add(cost, ExtraGasBuffer), gas()) {\n // Copy returndata to memory; overwrite existing.\n returndatacopy(0, 0, returndatasize())\n\n // Revert with memory region containing returndata.\n revert(0, returndatasize())\n }\n }\n\n // Set the error signature.\n mstore(\n 0,\n ERC1155BatchTransferGenericFailure_error_signature\n )\n\n // Write the token.\n mstore(ERC1155BatchTransferGenericFailure_token_ptr, token)\n\n // Increase the offset to ids by 32.\n mstore(\n BatchTransfer1155Params_ids_head_ptr,\n ERC1155BatchTransferGenericFailure_ids_offset\n )\n\n // Increase the offset to amounts by 32.\n mstore(\n BatchTransfer1155Params_amounts_head_ptr,\n add(\n OneWord,\n mload(BatchTransfer1155Params_amounts_head_ptr)\n )\n )\n\n // Return modified region. The total size stays the same as\n // `token` uses the same number of bytes as `data.length`.\n revert(0, transferDataSize)\n }\n }\n\n // Reset the free memory pointer to the default value; memory must\n // be assumed to be dirtied and not reused from this point forward.\n // Also note that the zero slot is not reset to zero, meaning empty\n // arrays cannot be safely created or utilized until it is restored.\n mstore(FreeMemoryPointerSlot, DefaultFreeMemoryPointer)\n }\n }\n}\n" - }, - "seaport/contracts/conduit/lib/ConduitStructs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport { ConduitItemType } from \"./ConduitEnums.sol\";\n\nstruct ConduitTransfer {\n ConduitItemType itemType;\n address token;\n address from;\n address to;\n uint256 identifier;\n uint256 amount;\n}\n\nstruct ConduitBatch1155Transfer {\n address token;\n address from;\n address to;\n uint256[] ids;\n uint256[] amounts;\n}\n" - }, - "seaport/contracts/conduit/lib/ConduitConstants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// error ChannelClosed(address channel)\nuint256 constant ChannelClosed_error_signature = (\n 0x93daadf200000000000000000000000000000000000000000000000000000000\n);\nuint256 constant ChannelClosed_error_ptr = 0x00;\nuint256 constant ChannelClosed_channel_ptr = 0x4;\nuint256 constant ChannelClosed_error_length = 0x24;\n\n// For the mapping:\n// mapping(address => bool) channels\n// The position in storage for a particular account is:\n// keccak256(abi.encode(account, channels.slot))\nuint256 constant ChannelKey_channel_ptr = 0x00;\nuint256 constant ChannelKey_slot_ptr = 0x20;\nuint256 constant ChannelKey_length = 0x40;\n" - }, - "seaport/contracts/lib/TokenTransferrerConstants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/*\n * -------------------------- Disambiguation & Other Notes ---------------------\n * - The term \"head\" is used as it is in the documentation for ABI encoding,\n * but only in reference to dynamic types, i.e. it always refers to the\n * offset or pointer to the body of a dynamic type. In calldata, the head\n * is always an offset (relative to the parent object), while in memory,\n * the head is always the pointer to the body. More information found here:\n * https://docs.soliditylang.org/en/v0.8.14/abi-spec.html#argument-encoding\n * - Note that the length of an array is separate from and precedes the\n * head of the array.\n *\n * - The term \"body\" is used in place of the term \"head\" used in the ABI\n * documentation. It refers to the start of the data for a dynamic type,\n * e.g. the first word of a struct or the first word of the first element\n * in an array.\n *\n * - The term \"pointer\" is used to describe the absolute position of a value\n * and never an offset relative to another value.\n * - The suffix \"_ptr\" refers to a memory pointer.\n * - The suffix \"_cdPtr\" refers to a calldata pointer.\n *\n * - The term \"offset\" is used to describe the position of a value relative\n * to some parent value. For example, OrderParameters_conduit_offset is the\n * offset to the \"conduit\" value in the OrderParameters struct relative to\n * the start of the body.\n * - Note: Offsets are used to derive pointers.\n *\n * - Some structs have pointers defined for all of their fields in this file.\n * Lines which are commented out are fields that are not used in the\n * codebase but have been left in for readability.\n */\n\nuint256 constant AlmostOneWord = 0x1f;\nuint256 constant OneWord = 0x20;\nuint256 constant TwoWords = 0x40;\nuint256 constant ThreeWords = 0x60;\n\nuint256 constant FreeMemoryPointerSlot = 0x40;\nuint256 constant ZeroSlot = 0x60;\nuint256 constant DefaultFreeMemoryPointer = 0x80;\n\nuint256 constant Slot0x80 = 0x80;\nuint256 constant Slot0xA0 = 0xa0;\nuint256 constant Slot0xC0 = 0xc0;\n\n// abi.encodeWithSignature(\"transferFrom(address,address,uint256)\")\nuint256 constant ERC20_transferFrom_signature = (\n 0x23b872dd00000000000000000000000000000000000000000000000000000000\n);\nuint256 constant ERC20_transferFrom_sig_ptr = 0x0;\nuint256 constant ERC20_transferFrom_from_ptr = 0x04;\nuint256 constant ERC20_transferFrom_to_ptr = 0x24;\nuint256 constant ERC20_transferFrom_amount_ptr = 0x44;\nuint256 constant ERC20_transferFrom_length = 0x64; // 4 + 32 * 3 == 100\n\n// abi.encodeWithSignature(\n// \"safeTransferFrom(address,address,uint256,uint256,bytes)\"\n// )\nuint256 constant ERC1155_safeTransferFrom_signature = (\n 0xf242432a00000000000000000000000000000000000000000000000000000000\n);\nuint256 constant ERC1155_safeTransferFrom_sig_ptr = 0x0;\nuint256 constant ERC1155_safeTransferFrom_from_ptr = 0x04;\nuint256 constant ERC1155_safeTransferFrom_to_ptr = 0x24;\nuint256 constant ERC1155_safeTransferFrom_id_ptr = 0x44;\nuint256 constant ERC1155_safeTransferFrom_amount_ptr = 0x64;\nuint256 constant ERC1155_safeTransferFrom_data_offset_ptr = 0x84;\nuint256 constant ERC1155_safeTransferFrom_data_length_ptr = 0xa4;\nuint256 constant ERC1155_safeTransferFrom_length = 0xc4; // 4 + 32 * 6 == 196\nuint256 constant ERC1155_safeTransferFrom_data_length_offset = 0xa0;\n\n// abi.encodeWithSignature(\n// \"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\"\n// )\nuint256 constant ERC1155_safeBatchTransferFrom_signature = (\n 0x2eb2c2d600000000000000000000000000000000000000000000000000000000\n);\n\nbytes4 constant ERC1155_safeBatchTransferFrom_selector = bytes4(\n bytes32(ERC1155_safeBatchTransferFrom_signature)\n);\n\nuint256 constant ERC721_transferFrom_signature = ERC20_transferFrom_signature;\nuint256 constant ERC721_transferFrom_sig_ptr = 0x0;\nuint256 constant ERC721_transferFrom_from_ptr = 0x04;\nuint256 constant ERC721_transferFrom_to_ptr = 0x24;\nuint256 constant ERC721_transferFrom_id_ptr = 0x44;\nuint256 constant ERC721_transferFrom_length = 0x64; // 4 + 32 * 3 == 100\n\n// abi.encodeWithSignature(\"NoContract(address)\")\nuint256 constant NoContract_error_signature = (\n 0x5f15d67200000000000000000000000000000000000000000000000000000000\n);\nuint256 constant NoContract_error_sig_ptr = 0x0;\nuint256 constant NoContract_error_token_ptr = 0x4;\nuint256 constant NoContract_error_length = 0x24; // 4 + 32 == 36\n\n// abi.encodeWithSignature(\n// \"TokenTransferGenericFailure(address,address,address,uint256,uint256)\"\n// )\nuint256 constant TokenTransferGenericFailure_error_signature = (\n 0xf486bc8700000000000000000000000000000000000000000000000000000000\n);\nuint256 constant TokenTransferGenericFailure_error_sig_ptr = 0x0;\nuint256 constant TokenTransferGenericFailure_error_token_ptr = 0x4;\nuint256 constant TokenTransferGenericFailure_error_from_ptr = 0x24;\nuint256 constant TokenTransferGenericFailure_error_to_ptr = 0x44;\nuint256 constant TokenTransferGenericFailure_error_id_ptr = 0x64;\nuint256 constant TokenTransferGenericFailure_error_amount_ptr = 0x84;\n\n// 4 + 32 * 5 == 164\nuint256 constant TokenTransferGenericFailure_error_length = 0xa4;\n\n// abi.encodeWithSignature(\n// \"BadReturnValueFromERC20OnTransfer(address,address,address,uint256)\"\n// )\nuint256 constant BadReturnValueFromERC20OnTransfer_error_signature = (\n 0x9889192300000000000000000000000000000000000000000000000000000000\n);\nuint256 constant BadReturnValueFromERC20OnTransfer_error_sig_ptr = 0x0;\nuint256 constant BadReturnValueFromERC20OnTransfer_error_token_ptr = 0x4;\nuint256 constant BadReturnValueFromERC20OnTransfer_error_from_ptr = 0x24;\nuint256 constant BadReturnValueFromERC20OnTransfer_error_to_ptr = 0x44;\nuint256 constant BadReturnValueFromERC20OnTransfer_error_amount_ptr = 0x64;\n\n// 4 + 32 * 4 == 132\nuint256 constant BadReturnValueFromERC20OnTransfer_error_length = 0x84;\n\nuint256 constant ExtraGasBuffer = 0x20;\nuint256 constant CostPerWord = 3;\nuint256 constant MemoryExpansionCoefficient = 0x200;\n\n// Values are offset by 32 bytes in order to write the token to the beginning\n// in the event of a revert\nuint256 constant BatchTransfer1155Params_ptr = 0x24;\nuint256 constant BatchTransfer1155Params_ids_head_ptr = 0x64;\nuint256 constant BatchTransfer1155Params_amounts_head_ptr = 0x84;\nuint256 constant BatchTransfer1155Params_data_head_ptr = 0xa4;\nuint256 constant BatchTransfer1155Params_data_length_basePtr = 0xc4;\nuint256 constant BatchTransfer1155Params_calldata_baseSize = 0xc4;\n\nuint256 constant BatchTransfer1155Params_ids_length_ptr = 0xc4;\n\nuint256 constant BatchTransfer1155Params_ids_length_offset = 0xa0;\nuint256 constant BatchTransfer1155Params_amounts_length_baseOffset = 0xc0;\nuint256 constant BatchTransfer1155Params_data_length_baseOffset = 0xe0;\n\nuint256 constant ConduitBatch1155Transfer_usable_head_size = 0x80;\n\nuint256 constant ConduitBatch1155Transfer_from_offset = 0x20;\nuint256 constant ConduitBatch1155Transfer_ids_head_offset = 0x60;\nuint256 constant ConduitBatch1155Transfer_amounts_head_offset = 0x80;\nuint256 constant ConduitBatch1155Transfer_ids_length_offset = 0xa0;\nuint256 constant ConduitBatch1155Transfer_amounts_length_baseOffset = 0xc0;\nuint256 constant ConduitBatch1155Transfer_calldata_baseSize = 0xc0;\n\n// Note: abbreviated version of above constant to adhere to line length limit.\nuint256 constant ConduitBatchTransfer_amounts_head_offset = 0x80;\n\nuint256 constant Invalid1155BatchTransferEncoding_ptr = 0x00;\nuint256 constant Invalid1155BatchTransferEncoding_length = 0x04;\nuint256 constant Invalid1155BatchTransferEncoding_selector = (\n 0xeba2084c00000000000000000000000000000000000000000000000000000000\n);\n\nuint256 constant ERC1155BatchTransferGenericFailure_error_signature = (\n 0xafc445e200000000000000000000000000000000000000000000000000000000\n);\nuint256 constant ERC1155BatchTransferGenericFailure_token_ptr = 0x04;\nuint256 constant ERC1155BatchTransferGenericFailure_ids_offset = 0xc0;\n" - }, - "seaport/contracts/interfaces/TokenTransferrerErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/**\n * @title TokenTransferrerErrors\n */\ninterface TokenTransferrerErrors {\n /**\n * @dev Revert with an error when an ERC721 transfer with amount other than\n * one is attempted.\n */\n error InvalidERC721TransferAmount();\n\n /**\n * @dev Revert with an error when attempting to fulfill an order where an\n * item has an amount of zero.\n */\n error MissingItemAmount();\n\n /**\n * @dev Revert with an error when attempting to fulfill an order where an\n * item has unused parameters. This includes both the token and the\n * identifier parameters for native transfers as well as the identifier\n * parameter for ERC20 transfers. Note that the conduit does not\n * perform this check, leaving it up to the calling channel to enforce\n * when desired.\n */\n error UnusedItemParameters();\n\n /**\n * @dev Revert with an error when an ERC20, ERC721, or ERC1155 token\n * transfer reverts.\n *\n * @param token The token for which the transfer was attempted.\n * @param from The source of the attempted transfer.\n * @param to The recipient of the attempted transfer.\n * @param identifier The identifier for the attempted transfer.\n * @param amount The amount for the attempted transfer.\n */\n error TokenTransferGenericFailure(\n address token,\n address from,\n address to,\n uint256 identifier,\n uint256 amount\n );\n\n /**\n * @dev Revert with an error when a batch ERC1155 token transfer reverts.\n *\n * @param token The token for which the transfer was attempted.\n * @param from The source of the attempted transfer.\n * @param to The recipient of the attempted transfer.\n * @param identifiers The identifiers for the attempted transfer.\n * @param amounts The amounts for the attempted transfer.\n */\n error ERC1155BatchTransferGenericFailure(\n address token,\n address from,\n address to,\n uint256[] identifiers,\n uint256[] amounts\n );\n\n /**\n * @dev Revert with an error when an ERC20 token transfer returns a falsey\n * value.\n *\n * @param token The token for which the ERC20 transfer was attempted.\n * @param from The source of the attempted ERC20 transfer.\n * @param to The recipient of the attempted ERC20 transfer.\n * @param amount The amount for the attempted ERC20 transfer.\n */\n error BadReturnValueFromERC20OnTransfer(\n address token,\n address from,\n address to,\n uint256 amount\n );\n\n /**\n * @dev Revert with an error when an account being called as an assumed\n * contract does not have code and returns no data.\n *\n * @param account The account that should contain code.\n */\n error NoContract(address account);\n\n /**\n * @dev Revert with an error when attempting to execute an 1155 batch\n * transfer using calldata not produced by default ABI encoding or with\n * different lengths for ids and amounts arrays.\n */\n error Invalid1155BatchTransferEncoding();\n}\n" - }, - "seaport/contracts/conduit/ConduitController.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// prettier-ignore\nimport {\n\tConduitControllerInterface\n} from \"../interfaces/ConduitControllerInterface.sol\";\n\nimport { ConduitInterface } from \"../interfaces/ConduitInterface.sol\";\n\nimport { Conduit } from \"./Conduit.sol\";\n\n/**\n * @title ConduitController\n * @author 0age\n * @notice ConduitController enables deploying and managing new conduits, or\n * contracts that allow registered callers (or open \"channels\") to\n * transfer approved ERC20/721/1155 tokens on their behalf.\n */\ncontract ConduitController is ConduitControllerInterface {\n // Register keys, owners, new potential owners, and channels by conduit.\n mapping(address => ConduitProperties) internal _conduits;\n\n // Set conduit creation code and runtime code hashes as immutable arguments.\n bytes32 internal immutable _CONDUIT_CREATION_CODE_HASH;\n bytes32 internal immutable _CONDUIT_RUNTIME_CODE_HASH;\n\n /**\n * @dev Initialize contract by deploying a conduit and setting the creation\n * code and runtime code hashes as immutable arguments.\n */\n constructor() {\n // Derive the conduit creation code hash and set it as an immutable.\n _CONDUIT_CREATION_CODE_HASH = keccak256(type(Conduit).creationCode);\n\n // Deploy a conduit with the zero hash as the salt.\n Conduit zeroConduit = new Conduit{ salt: bytes32(0) }();\n\n // Retrieve the conduit runtime code hash and set it as an immutable.\n _CONDUIT_RUNTIME_CODE_HASH = address(zeroConduit).codehash;\n }\n\n /**\n * @notice Deploy a new conduit using a supplied conduit key and assigning\n * an initial owner for the deployed conduit. Note that the first\n * twenty bytes of the supplied conduit key must match the caller\n * and that a new conduit cannot be created if one has already been\n * deployed using the same conduit key.\n *\n * @param conduitKey The conduit key used to deploy the conduit. Note that\n * the first twenty bytes of the conduit key must match\n * the caller of this contract.\n * @param initialOwner The initial owner to set for the new conduit.\n *\n * @return conduit The address of the newly deployed conduit.\n */\n function createConduit(bytes32 conduitKey, address initialOwner)\n external\n override\n returns (address conduit)\n {\n // Ensure that an initial owner has been supplied.\n if (initialOwner == address(0)) {\n revert InvalidInitialOwner();\n }\n\n // If the first 20 bytes of the conduit key do not match the caller...\n if (address(uint160(bytes20(conduitKey))) != msg.sender) {\n // Revert with an error indicating that the creator is invalid.\n revert InvalidCreator();\n }\n\n // Derive address from deployer, conduit key and creation code hash.\n conduit = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n conduitKey,\n _CONDUIT_CREATION_CODE_HASH\n )\n )\n )\n )\n );\n\n // If derived conduit exists, as evidenced by comparing runtime code...\n if (conduit.codehash == _CONDUIT_RUNTIME_CODE_HASH) {\n // Revert with an error indicating that the conduit already exists.\n revert ConduitAlreadyExists(conduit);\n }\n\n // Deploy the conduit via CREATE2 using the conduit key as the salt.\n new Conduit{ salt: conduitKey }();\n\n // Initialize storage variable referencing conduit properties.\n ConduitProperties storage conduitProperties = _conduits[conduit];\n\n // Set the supplied initial owner as the owner of the conduit.\n conduitProperties.owner = initialOwner;\n\n // Set conduit key used to deploy the conduit to enable reverse lookup.\n conduitProperties.key = conduitKey;\n\n // Emit an event indicating that the conduit has been deployed.\n emit NewConduit(conduit, conduitKey);\n\n // Emit an event indicating that conduit ownership has been assigned.\n emit OwnershipTransferred(conduit, address(0), initialOwner);\n }\n\n /**\n * @notice Open or close a channel on a given conduit, thereby allowing the\n * specified account to execute transfers against that conduit.\n * Extreme care must be taken when updating channels, as malicious\n * or vulnerable channels can transfer any ERC20, ERC721 and ERC1155\n * tokens where the token holder has granted the conduit approval.\n * Only the owner of the conduit in question may call this function.\n *\n * @param conduit The conduit for which to open or close the channel.\n * @param channel The channel to open or close on the conduit.\n * @param isOpen A boolean indicating whether to open or close the channel.\n */\n function updateChannel(\n address conduit,\n address channel,\n bool isOpen\n ) external override {\n // Ensure the caller is the current owner of the conduit in question.\n _assertCallerIsConduitOwner(conduit);\n\n // Call the conduit, updating the channel.\n ConduitInterface(conduit).updateChannel(channel, isOpen);\n\n // Retrieve storage region where channels for the conduit are tracked.\n ConduitProperties storage conduitProperties = _conduits[conduit];\n\n // Retrieve the index, if one currently exists, for the updated channel.\n uint256 channelIndexPlusOne = (\n conduitProperties.channelIndexesPlusOne[channel]\n );\n\n // Determine whether the updated channel is already tracked as open.\n bool channelPreviouslyOpen = channelIndexPlusOne != 0;\n\n // If the channel has been set to open and was previously closed...\n if (isOpen && !channelPreviouslyOpen) {\n // Add the channel to the channels array for the conduit.\n conduitProperties.channels.push(channel);\n\n // Add new open channel length to associated mapping as index + 1.\n conduitProperties.channelIndexesPlusOne[channel] = (\n conduitProperties.channels.length\n );\n } else if (!isOpen && channelPreviouslyOpen) {\n // Set a previously open channel as closed via \"swap & pop\" method.\n // Decrement located index to get the index of the closed channel.\n uint256 removedChannelIndex;\n\n // Skip underflow check as channelPreviouslyOpen being true ensures\n // that channelIndexPlusOne is nonzero.\n unchecked {\n removedChannelIndex = channelIndexPlusOne - 1;\n }\n\n // Use length of channels array to determine index of last channel.\n uint256 finalChannelIndex = conduitProperties.channels.length - 1;\n\n // If closed channel is not last channel in the channels array...\n if (finalChannelIndex != removedChannelIndex) {\n // Retrieve the final channel and place the value on the stack.\n address finalChannel = (\n conduitProperties.channels[finalChannelIndex]\n );\n\n // Overwrite the removed channel using the final channel value.\n conduitProperties.channels[removedChannelIndex] = finalChannel;\n\n // Update final index in associated mapping to removed index.\n conduitProperties.channelIndexesPlusOne[finalChannel] = (\n channelIndexPlusOne\n );\n }\n\n // Remove the last channel from the channels array for the conduit.\n conduitProperties.channels.pop();\n\n // Remove the closed channel from associated mapping of indexes.\n delete conduitProperties.channelIndexesPlusOne[channel];\n }\n }\n\n /**\n * @notice Initiate conduit ownership transfer by assigning a new potential\n * owner for the given conduit. Once set, the new potential owner\n * may call `acceptOwnership` to claim ownership of the conduit.\n * Only the owner of the conduit in question may call this function.\n *\n * @param conduit The conduit for which to initiate ownership transfer.\n * @param newPotentialOwner The new potential owner of the conduit.\n */\n function transferOwnership(address conduit, address newPotentialOwner)\n external\n override\n {\n // Ensure the caller is the current owner of the conduit in question.\n _assertCallerIsConduitOwner(conduit);\n\n // Ensure the new potential owner is not an invalid address.\n if (newPotentialOwner == address(0)) {\n revert NewPotentialOwnerIsZeroAddress(conduit);\n }\n\n // Ensure the new potential owner is not already set.\n if (newPotentialOwner == _conduits[conduit].potentialOwner) {\n revert NewPotentialOwnerAlreadySet(conduit, newPotentialOwner);\n }\n\n // Emit an event indicating that the potential owner has been updated.\n emit PotentialOwnerUpdated(newPotentialOwner);\n\n // Set the new potential owner as the potential owner of the conduit.\n _conduits[conduit].potentialOwner = newPotentialOwner;\n }\n\n /**\n * @notice Clear the currently set potential owner, if any, from a conduit.\n * Only the owner of the conduit in question may call this function.\n *\n * @param conduit The conduit for which to cancel ownership transfer.\n */\n function cancelOwnershipTransfer(address conduit) external override {\n // Ensure the caller is the current owner of the conduit in question.\n _assertCallerIsConduitOwner(conduit);\n\n // Ensure that ownership transfer is currently possible.\n if (_conduits[conduit].potentialOwner == address(0)) {\n revert NoPotentialOwnerCurrentlySet(conduit);\n }\n\n // Emit an event indicating that the potential owner has been cleared.\n emit PotentialOwnerUpdated(address(0));\n\n // Clear the current new potential owner from the conduit.\n _conduits[conduit].potentialOwner = address(0);\n }\n\n /**\n * @notice Accept ownership of a supplied conduit. Only accounts that the\n * current owner has set as the new potential owner may call this\n * function.\n *\n * @param conduit The conduit for which to accept ownership.\n */\n function acceptOwnership(address conduit) external override {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // If caller does not match current potential owner of the conduit...\n if (msg.sender != _conduits[conduit].potentialOwner) {\n // Revert, indicating that caller is not current potential owner.\n revert CallerIsNotNewPotentialOwner(conduit);\n }\n\n // Emit an event indicating that the potential owner has been cleared.\n emit PotentialOwnerUpdated(address(0));\n\n // Clear the current new potential owner from the conduit.\n _conduits[conduit].potentialOwner = address(0);\n\n // Emit an event indicating conduit ownership has been transferred.\n emit OwnershipTransferred(\n conduit,\n _conduits[conduit].owner,\n msg.sender\n );\n\n // Set the caller as the owner of the conduit.\n _conduits[conduit].owner = msg.sender;\n }\n\n /**\n * @notice Retrieve the current owner of a deployed conduit.\n *\n * @param conduit The conduit for which to retrieve the associated owner.\n *\n * @return owner The owner of the supplied conduit.\n */\n function ownerOf(address conduit)\n external\n view\n override\n returns (address owner)\n {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // Retrieve the current owner of the conduit in question.\n owner = _conduits[conduit].owner;\n }\n\n /**\n * @notice Retrieve the conduit key for a deployed conduit via reverse\n * lookup.\n *\n * @param conduit The conduit for which to retrieve the associated conduit\n * key.\n *\n * @return conduitKey The conduit key used to deploy the supplied conduit.\n */\n function getKey(address conduit)\n external\n view\n override\n returns (bytes32 conduitKey)\n {\n // Attempt to retrieve a conduit key for the conduit in question.\n conduitKey = _conduits[conduit].key;\n\n // Revert if no conduit key was located.\n if (conduitKey == bytes32(0)) {\n revert NoConduit();\n }\n }\n\n /**\n * @notice Derive the conduit associated with a given conduit key and\n * determine whether that conduit exists (i.e. whether it has been\n * deployed).\n *\n * @param conduitKey The conduit key used to derive the conduit.\n *\n * @return conduit The derived address of the conduit.\n * @return exists A boolean indicating whether the derived conduit has been\n * deployed or not.\n */\n function getConduit(bytes32 conduitKey)\n external\n view\n override\n returns (address conduit, bool exists)\n {\n // Derive address from deployer, conduit key and creation code hash.\n conduit = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n conduitKey,\n _CONDUIT_CREATION_CODE_HASH\n )\n )\n )\n )\n );\n\n // Determine whether conduit exists by retrieving its runtime code.\n exists = (conduit.codehash == _CONDUIT_RUNTIME_CODE_HASH);\n }\n\n /**\n * @notice Retrieve the potential owner, if any, for a given conduit. The\n * current owner may set a new potential owner via\n * `transferOwnership` and that owner may then accept ownership of\n * the conduit in question via `acceptOwnership`.\n *\n * @param conduit The conduit for which to retrieve the potential owner.\n *\n * @return potentialOwner The potential owner, if any, for the conduit.\n */\n function getPotentialOwner(address conduit)\n external\n view\n override\n returns (address potentialOwner)\n {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // Retrieve the current potential owner of the conduit in question.\n potentialOwner = _conduits[conduit].potentialOwner;\n }\n\n /**\n * @notice Retrieve the status (either open or closed) of a given channel on\n * a conduit.\n *\n * @param conduit The conduit for which to retrieve the channel status.\n * @param channel The channel for which to retrieve the status.\n *\n * @return isOpen The status of the channel on the given conduit.\n */\n function getChannelStatus(address conduit, address channel)\n external\n view\n override\n returns (bool isOpen)\n {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // Retrieve the current channel status for the conduit in question.\n isOpen = _conduits[conduit].channelIndexesPlusOne[channel] != 0;\n }\n\n /**\n * @notice Retrieve the total number of open channels for a given conduit.\n *\n * @param conduit The conduit for which to retrieve the total channel count.\n *\n * @return totalChannels The total number of open channels for the conduit.\n */\n function getTotalChannels(address conduit)\n external\n view\n override\n returns (uint256 totalChannels)\n {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // Retrieve the total open channel count for the conduit in question.\n totalChannels = _conduits[conduit].channels.length;\n }\n\n /**\n * @notice Retrieve an open channel at a specific index for a given conduit.\n * Note that the index of a channel can change as a result of other\n * channels being closed on the conduit.\n *\n * @param conduit The conduit for which to retrieve the open channel.\n * @param channelIndex The index of the channel in question.\n *\n * @return channel The open channel, if any, at the specified channel index.\n */\n function getChannel(address conduit, uint256 channelIndex)\n external\n view\n override\n returns (address channel)\n {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // Retrieve the total open channel count for the conduit in question.\n uint256 totalChannels = _conduits[conduit].channels.length;\n\n // Ensure that the supplied index is within range.\n if (channelIndex >= totalChannels) {\n revert ChannelOutOfRange(conduit);\n }\n\n // Retrieve the channel at the given index.\n channel = _conduits[conduit].channels[channelIndex];\n }\n\n /**\n * @notice Retrieve all open channels for a given conduit. Note that calling\n * this function for a conduit with many channels will revert with\n * an out-of-gas error.\n *\n * @param conduit The conduit for which to retrieve open channels.\n *\n * @return channels An array of open channels on the given conduit.\n */\n function getChannels(address conduit)\n external\n view\n override\n returns (address[] memory channels)\n {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // Retrieve all of the open channels on the conduit in question.\n channels = _conduits[conduit].channels;\n }\n\n /**\n * @dev Retrieve the conduit creation code and runtime code hashes.\n */\n function getConduitCodeHashes()\n external\n view\n override\n returns (bytes32 creationCodeHash, bytes32 runtimeCodeHash)\n {\n // Retrieve the conduit creation code hash from runtime.\n creationCodeHash = _CONDUIT_CREATION_CODE_HASH;\n\n // Retrieve the conduit runtime code hash from runtime.\n runtimeCodeHash = _CONDUIT_RUNTIME_CODE_HASH;\n }\n\n /**\n * @dev Private view function to revert if the caller is not the owner of a\n * given conduit.\n *\n * @param conduit The conduit for which to assert ownership.\n */\n function _assertCallerIsConduitOwner(address conduit) private view {\n // Ensure that the conduit in question exists.\n _assertConduitExists(conduit);\n\n // If the caller does not match the current owner of the conduit...\n if (msg.sender != _conduits[conduit].owner) {\n // Revert, indicating that the caller is not the owner.\n revert CallerIsNotOwner(conduit);\n }\n }\n\n /**\n * @dev Private view function to revert if a given conduit does not exist.\n *\n * @param conduit The conduit for which to assert existence.\n */\n function _assertConduitExists(address conduit) private view {\n // Attempt to retrieve a conduit key for the conduit in question.\n if (_conduits[conduit].key == bytes32(0)) {\n // Revert if no conduit key was located.\n revert NoConduit();\n }\n }\n}\n" - }, - "seaport/contracts/interfaces/ConduitControllerInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/**\n * @title ConduitControllerInterface\n * @author 0age\n * @notice ConduitControllerInterface contains all external function interfaces,\n * structs, events, and errors for the conduit controller.\n */\ninterface ConduitControllerInterface {\n /**\n * @dev Track the conduit key, current owner, new potential owner, and open\n * channels for each deployed conduit.\n */\n struct ConduitProperties {\n bytes32 key;\n address owner;\n address potentialOwner;\n address[] channels;\n mapping(address => uint256) channelIndexesPlusOne;\n }\n\n /**\n * @dev Emit an event whenever a new conduit is created.\n *\n * @param conduit The newly created conduit.\n * @param conduitKey The conduit key used to create the new conduit.\n */\n event NewConduit(address conduit, bytes32 conduitKey);\n\n /**\n * @dev Emit an event whenever conduit ownership is transferred.\n *\n * @param conduit The conduit for which ownership has been\n * transferred.\n * @param previousOwner The previous owner of the conduit.\n * @param newOwner The new owner of the conduit.\n */\n event OwnershipTransferred(\n address indexed conduit,\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /**\n * @dev Emit an event whenever a conduit owner registers a new potential\n * owner for that conduit.\n *\n * @param newPotentialOwner The new potential owner of the conduit.\n */\n event PotentialOwnerUpdated(address indexed newPotentialOwner);\n\n /**\n * @dev Revert with an error when attempting to create a new conduit using a\n * conduit key where the first twenty bytes of the key do not match the\n * address of the caller.\n */\n error InvalidCreator();\n\n /**\n * @dev Revert with an error when attempting to create a new conduit when no\n * initial owner address is supplied.\n */\n error InvalidInitialOwner();\n\n /**\n * @dev Revert with an error when attempting to set a new potential owner\n * that is already set.\n */\n error NewPotentialOwnerAlreadySet(\n address conduit,\n address newPotentialOwner\n );\n\n /**\n * @dev Revert with an error when attempting to cancel ownership transfer\n * when no new potential owner is currently set.\n */\n error NoPotentialOwnerCurrentlySet(address conduit);\n\n /**\n * @dev Revert with an error when attempting to interact with a conduit that\n * does not yet exist.\n */\n error NoConduit();\n\n /**\n * @dev Revert with an error when attempting to create a conduit that\n * already exists.\n */\n error ConduitAlreadyExists(address conduit);\n\n /**\n * @dev Revert with an error when attempting to update channels or transfer\n * ownership of a conduit when the caller is not the owner of the\n * conduit in question.\n */\n error CallerIsNotOwner(address conduit);\n\n /**\n * @dev Revert with an error when attempting to register a new potential\n * owner and supplying the null address.\n */\n error NewPotentialOwnerIsZeroAddress(address conduit);\n\n /**\n * @dev Revert with an error when attempting to claim ownership of a conduit\n * with a caller that is not the current potential owner for the\n * conduit in question.\n */\n error CallerIsNotNewPotentialOwner(address conduit);\n\n /**\n * @dev Revert with an error when attempting to retrieve a channel using an\n * index that is out of range.\n */\n error ChannelOutOfRange(address conduit);\n\n /**\n * @notice Deploy a new conduit using a supplied conduit key and assigning\n * an initial owner for the deployed conduit. Note that the first\n * twenty bytes of the supplied conduit key must match the caller\n * and that a new conduit cannot be created if one has already been\n * deployed using the same conduit key.\n *\n * @param conduitKey The conduit key used to deploy the conduit. Note that\n * the first twenty bytes of the conduit key must match\n * the caller of this contract.\n * @param initialOwner The initial owner to set for the new conduit.\n *\n * @return conduit The address of the newly deployed conduit.\n */\n function createConduit(bytes32 conduitKey, address initialOwner)\n external\n returns (address conduit);\n\n /**\n * @notice Open or close a channel on a given conduit, thereby allowing the\n * specified account to execute transfers against that conduit.\n * Extreme care must be taken when updating channels, as malicious\n * or vulnerable channels can transfer any ERC20, ERC721 and ERC1155\n * tokens where the token holder has granted the conduit approval.\n * Only the owner of the conduit in question may call this function.\n *\n * @param conduit The conduit for which to open or close the channel.\n * @param channel The channel to open or close on the conduit.\n * @param isOpen A boolean indicating whether to open or close the channel.\n */\n function updateChannel(\n address conduit,\n address channel,\n bool isOpen\n ) external;\n\n /**\n * @notice Initiate conduit ownership transfer by assigning a new potential\n * owner for the given conduit. Once set, the new potential owner\n * may call `acceptOwnership` to claim ownership of the conduit.\n * Only the owner of the conduit in question may call this function.\n *\n * @param conduit The conduit for which to initiate ownership transfer.\n * @param newPotentialOwner The new potential owner of the conduit.\n */\n function transferOwnership(address conduit, address newPotentialOwner)\n external;\n\n /**\n * @notice Clear the currently set potential owner, if any, from a conduit.\n * Only the owner of the conduit in question may call this function.\n *\n * @param conduit The conduit for which to cancel ownership transfer.\n */\n function cancelOwnershipTransfer(address conduit) external;\n\n /**\n * @notice Accept ownership of a supplied conduit. Only accounts that the\n * current owner has set as the new potential owner may call this\n * function.\n *\n * @param conduit The conduit for which to accept ownership.\n */\n function acceptOwnership(address conduit) external;\n\n /**\n * @notice Retrieve the current owner of a deployed conduit.\n *\n * @param conduit The conduit for which to retrieve the associated owner.\n *\n * @return owner The owner of the supplied conduit.\n */\n function ownerOf(address conduit) external view returns (address owner);\n\n /**\n * @notice Retrieve the conduit key for a deployed conduit via reverse\n * lookup.\n *\n * @param conduit The conduit for which to retrieve the associated conduit\n * key.\n *\n * @return conduitKey The conduit key used to deploy the supplied conduit.\n */\n function getKey(address conduit) external view returns (bytes32 conduitKey);\n\n /**\n * @notice Derive the conduit associated with a given conduit key and\n * determine whether that conduit exists (i.e. whether it has been\n * deployed).\n *\n * @param conduitKey The conduit key used to derive the conduit.\n *\n * @return conduit The derived address of the conduit.\n * @return exists A boolean indicating whether the derived conduit has been\n * deployed or not.\n */\n function getConduit(bytes32 conduitKey)\n external\n view\n returns (address conduit, bool exists);\n\n /**\n * @notice Retrieve the potential owner, if any, for a given conduit. The\n * current owner may set a new potential owner via\n * `transferOwnership` and that owner may then accept ownership of\n * the conduit in question via `acceptOwnership`.\n *\n * @param conduit The conduit for which to retrieve the potential owner.\n *\n * @return potentialOwner The potential owner, if any, for the conduit.\n */\n function getPotentialOwner(address conduit)\n external\n view\n returns (address potentialOwner);\n\n /**\n * @notice Retrieve the status (either open or closed) of a given channel on\n * a conduit.\n *\n * @param conduit The conduit for which to retrieve the channel status.\n * @param channel The channel for which to retrieve the status.\n *\n * @return isOpen The status of the channel on the given conduit.\n */\n function getChannelStatus(address conduit, address channel)\n external\n view\n returns (bool isOpen);\n\n /**\n * @notice Retrieve the total number of open channels for a given conduit.\n *\n * @param conduit The conduit for which to retrieve the total channel count.\n *\n * @return totalChannels The total number of open channels for the conduit.\n */\n function getTotalChannels(address conduit)\n external\n view\n returns (uint256 totalChannels);\n\n /**\n * @notice Retrieve an open channel at a specific index for a given conduit.\n * Note that the index of a channel can change as a result of other\n * channels being closed on the conduit.\n *\n * @param conduit The conduit for which to retrieve the open channel.\n * @param channelIndex The index of the channel in question.\n *\n * @return channel The open channel, if any, at the specified channel index.\n */\n function getChannel(address conduit, uint256 channelIndex)\n external\n view\n returns (address channel);\n\n /**\n * @notice Retrieve all open channels for a given conduit. Note that calling\n * this function for a conduit with many channels will revert with\n * an out-of-gas error.\n *\n * @param conduit The conduit for which to retrieve open channels.\n *\n * @return channels An array of open channels on the given conduit.\n */\n function getChannels(address conduit)\n external\n view\n returns (address[] memory channels);\n\n /**\n * @dev Retrieve the conduit creation code and runtime code hashes.\n */\n function getConduitCodeHashes()\n external\n view\n returns (bytes32 creationCodeHash, bytes32 runtimeCodeHash);\n}\n" - }, - "contracts/shoyu/adapters/Transfer/ConduitAdapter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport { ConduitControllerInterface } from \"seaport/contracts/interfaces/ConduitControllerInterface.sol\";\nimport { ConduitInterface } from \"seaport/contracts/interfaces/ConduitInterface.sol\";\nimport { ConduitTransfer } from \"seaport/contracts/conduit/lib/ConduitStructs.sol\";\nimport { ConduitItemType } from \"seaport/contracts/conduit/lib/ConduitEnums.sol\";\n\ncontract ConduitAdapter {\n // Allow for interaction with the conduit controller.\n ConduitControllerInterface private immutable _CONDUIT_CONTROLLER;\n // Cache the conduit creation hash used by the conduit controller.\n bytes32 private immutable _CONDUIT_CREATION_CODE_HASH;\n\n constructor(address _conduitController) {\n // Get the conduit creation code hash from the supplied conduit\n // controller and set it as an immutable.\n ConduitControllerInterface conduitController = ConduitControllerInterface(\n _conduitController\n );\n (_CONDUIT_CREATION_CODE_HASH, ) = conduitController.getConduitCodeHashes();\n\n // Set the supplied conduit controller as an immutable.\n _CONDUIT_CONTROLLER = conduitController;\n }\n\n function _performERC20TransferWithConduit(\n address token,\n address from,\n address to,\n uint256 amount,\n bytes32 conduitKey\n ) internal {\n // Derive the conduit address from the deployer, conduit key\n // and creation code hash.\n address conduit = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(_CONDUIT_CONTROLLER),\n conduitKey,\n _CONDUIT_CREATION_CODE_HASH\n )\n )\n )\n )\n );\n\n ConduitTransfer[] memory conduitTransfers = new ConduitTransfer[](1);\n conduitTransfers[0] = ConduitTransfer(\n ConduitItemType.ERC20,\n token,\n from,\n to,\n 0,\n amount\n );\n\n // Call the conduit and execute transfer.\n ConduitInterface(conduit).execute(conduitTransfers);\n }\n\n function _performERC721TransferWithConduit(\n address token,\n address from,\n address to,\n uint256 tokenId,\n bytes32 conduitKey\n ) internal {\n // Derive the conduit address from the deployer, conduit key\n // and creation code hash.\n address conduit = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(_CONDUIT_CONTROLLER),\n conduitKey,\n _CONDUIT_CREATION_CODE_HASH\n )\n )\n )\n )\n );\n\n ConduitTransfer[] memory conduitTransfers = new ConduitTransfer[](1);\n conduitTransfers[0] = ConduitTransfer(\n ConduitItemType.ERC721,\n token,\n from,\n to,\n tokenId,\n 1\n );\n\n // Call the conduit and execute transfer.\n ConduitInterface(conduit).execute(conduitTransfers);\n }\n\n function _performERC1155TransferWithConduit(\n address token,\n address from,\n address to,\n uint256 tokenId,\n uint256 amount,\n bytes32 conduitKey\n ) internal {\n // Derive the conduit address from the deployer, conduit key\n // and creation code hash.\n address conduit = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(_CONDUIT_CONTROLLER),\n conduitKey,\n _CONDUIT_CREATION_CODE_HASH\n )\n )\n )\n )\n );\n\n ConduitTransfer[] memory conduitTransfers = new ConduitTransfer[](1);\n conduitTransfers[0] = ConduitTransfer(\n ConduitItemType.ERC1155,\n token,\n from,\n to,\n tokenId,\n amount\n );\n\n // Call the conduit and execute transfer.\n ConduitInterface(conduit).execute(conduitTransfers);\n }\n}" - }, - "contracts/shoyu/adapters/Transform/LegacySwapAdapter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport \"@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Pair.sol\";\nimport \"@rari-capital/solmate/src/tokens/ERC20.sol\";\n\nimport \"../Transfer/ConduitAdapter.sol\";\nimport \"../Transfer/TransferAdapter.sol\";\nimport { SwapExactOutDetails } from \"../../lib/ShoyuStructs.sol\";\nimport { pairFor, sortTokens, getAmountsIn, getAmountsOut } from \"../../lib/LibSushi.sol\";\nimport { TokenSource } from \"../../lib/ShoyuEnums.sol\";\n\ncontract LegacySwapAdapter is TransferAdapter {\n /// @dev The UniswapV2Factory address.\n address private immutable factory;\n /// @dev The UniswapV2 pair init code.\n bytes32 private immutable pairCodeHash;\n\n constructor(\n address _factory,\n bytes32 _pairCodeHash,\n address _conduitController,\n address _bentobox\n ) TransferAdapter (_conduitController, _bentobox) {\n factory = _factory;\n pairCodeHash = _pairCodeHash;\n }\n\n // transfers funds from msg.sender and performs swap\n function _legacySwapExactOut(\n uint256 amountOut,\n uint256 amountInMax,\n address[] memory path,\n address to,\n TokenSource tokenSource,\n bytes memory transferData\n ) internal returns (uint256 amountIn) {\n uint256[] memory amounts = getAmountsIn(\n factory,\n amountOut,\n path,\n pairCodeHash\n );\n amountIn = amounts[0];\n\n require(amountIn <= amountInMax, '_legacySwapExactOut/EXCESSIVE_AMOUNT_IN');\n\n transferERC20From(\n path[0],\n pairFor(\n factory,\n path[0],\n path[1],\n pairCodeHash\n ),\n amountIn,\n tokenSource,\n transferData\n );\n\n _swap(amounts, path, to);\n }\n\n // requires path[0] to have already been sent to address(this)\n function _legacySwapExactIn(\n uint256 amountIn,\n uint256 amountOutMin,\n address[] memory path,\n address to\n ) internal returns (uint256 amountOut) {\n uint256[] memory amounts = getAmountsOut(\n factory,\n amountIn,\n path,\n pairCodeHash\n );\n amountOut = amounts[amounts.length - 1];\n\n require(amountOut >= amountOutMin, \"_legacySwapExactIn/EXCESSIVE_AMOUNT_OUT\");\n\n ERC20(path[0]).transfer(\n pairFor(\n factory,\n path[0],\n path[1],\n pairCodeHash\n ),\n amountIn\n );\n\n _swap(amounts, path, to);\n }\n\n // requires the initial amount to have already been sent to the first pair\n function _swap(\n uint256[] memory amounts,\n address[] memory path,\n address _to\n ) internal virtual {\n for (uint256 i; i < path.length - 1; i++) {\n (address input, address output) = (path[i], path[i + 1]);\n\n (address token0, ) = sortTokens(input, output);\n\n uint256 amountOut = amounts[i + 1];\n\n (uint256 amount0Out, uint256 amount1Out) = input == token0\n ? (uint256(0), amountOut)\n : (amountOut, uint256(0));\n address to = i < path.length - 2 ? pairFor(factory, output, path[i + 2], pairCodeHash) : _to;\n\n IUniswapV2Pair(pairFor(factory, input, output, pairCodeHash)).swap(\n amount0Out,\n amount1Out,\n to,\n new bytes(0)\n );\n }\n }\n\n \n}" - }, - "@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Pair.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.5.0;\n\ninterface IUniswapV2Pair {\n event Approval(address indexed owner, address indexed spender, uint value);\n event Transfer(address indexed from, address indexed to, uint value);\n\n function name() external pure returns (string memory);\n function symbol() external pure returns (string memory);\n function decimals() external pure returns (uint8);\n function totalSupply() external view returns (uint);\n function balanceOf(address owner) external view returns (uint);\n function allowance(address owner, address spender) external view returns (uint);\n\n function approve(address spender, uint value) external returns (bool);\n function transfer(address to, uint value) external returns (bool);\n function transferFrom(address from, address to, uint value) external returns (bool);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n function nonces(address owner) external view returns (uint);\n\n function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n event Mint(address indexed sender, uint amount0, uint amount1);\n event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);\n event Swap(\n address indexed sender,\n uint amount0In,\n uint amount1In,\n uint amount0Out,\n uint amount1Out,\n address indexed to\n );\n event Sync(uint112 reserve0, uint112 reserve1);\n\n function MINIMUM_LIQUIDITY() external pure returns (uint);\n function factory() external view returns (address);\n function token0() external view returns (address);\n function token1() external view returns (address);\n function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n function price0CumulativeLast() external view returns (uint);\n function price1CumulativeLast() external view returns (uint);\n function kLast() external view returns (uint);\n\n function mint(address to) external returns (uint liquidity);\n function burn(address to) external returns (uint amount0, uint amount1);\n function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n function skim(address to) external;\n function sync() external;\n\n function initialize(address, address) external;\n}" - }, - "@rari-capital/solmate/src/tokens/ERC20.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*///////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*///////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*///////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*///////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n bytes32 public constant PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*///////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*///////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*///////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))\n )\n );\n\n address recoveredAddress = ecrecover(digest, v, r, s);\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*///////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n" - }, - "contracts/shoyu/adapters/Transfer/TransferAdapter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport \"seaport/contracts/lib/TokenTransferrer.sol\";\nimport \"./ConduitAdapter.sol\";\nimport \"./BentoAdapter.sol\";\nimport { TokenSource } from \"../../lib/ShoyuEnums.sol\";\n\n// TODO: Consider notice in TokenTransferrer.sol, maybe it shouldn't be used here\ncontract TransferAdapter is TokenTransferrer, ConduitAdapter, BentoAdapter {\n constructor(\n address _conduitController,\n address _bentoBox\n )\n ConduitAdapter(_conduitController)\n BentoAdapter(_bentoBox)\n {}\n\n function transferERC20From(\n address token,\n address to,\n uint256 amount,\n TokenSource source,\n bytes memory data\n ) public {\n if (source == TokenSource.WALLET) {\n _performERC20Transfer(\n token,\n msg.sender,\n to,\n amount\n );\n } else if (source == TokenSource.CONDUIT) {\n bytes32 conduitKey = abi.decode(data, (bytes32));\n\n _performERC20TransferWithConduit(\n token,\n msg.sender,\n to,\n amount,\n conduitKey\n );\n } else if (source == TokenSource.BENTO) {\n bool unwrapBento = abi.decode(data, (bool));\n\n _transferFromBentoBox(\n token,\n msg.sender,\n to,\n amount,\n 0,\n unwrapBento\n );\n } else {\n revert(\"transferERC20From/INVALID_TOKEN_SOURCE\");\n }\n }\n\n function transferERC721From(\n address token,\n address to,\n uint256 tokenId,\n TokenSource source,\n bytes memory data\n ) public {\n if (source == TokenSource.WALLET) {\n _performERC721Transfer(\n token,\n msg.sender,\n to,\n tokenId\n );\n } else if (source == TokenSource.CONDUIT) {\n bytes32 conduitKey = abi.decode(data, (bytes32));\n\n _performERC721TransferWithConduit(\n token,\n msg.sender,\n to,\n tokenId,\n conduitKey\n );\n } else {\n revert(\"transferERC721From/INVALID_TOKEN_SOURCE\");\n }\n }\n\n function transferERC1155From(\n address token,\n address to,\n uint256 tokenId,\n uint256 amount,\n TokenSource source,\n bytes memory data\n ) public {\n if (source == TokenSource.WALLET) {\n _performERC1155Transfer(\n token,\n msg.sender,\n to,\n tokenId,\n amount\n );\n } else if (source == TokenSource.CONDUIT) {\n bytes32 conduitKey = abi.decode(data, (bytes32));\n\n _performERC1155TransferWithConduit(\n token,\n msg.sender,\n to,\n tokenId,\n amount,\n conduitKey\n );\n } else {\n revert(\"transferERC1155From/INVALID_TOKEN_SOURCE\");\n }\n }\n\n /// @dev Transfers some amount of ETH to the given recipient and\n /// reverts if the transfer fails.\n /// @param to The recipient of the ETH.\n /// @param amount The amount of ETH to transfer.\n function _transferEth(address payable to, uint256 amount)\n internal\n {\n assembly {\n let success := call(gas(), to, amount, 0, 0, 0, 0)\n if eq(success, 0) { revert(0, 0) }\n }\n }\n}" - }, - "contracts/shoyu/lib/ShoyuStructs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nstruct OrderDetails {\n uint256 value;\n bytes data;\n}\n\nstruct SwapExactOutDetails {\n address[] path;\n uint256 amountInMax;\n uint256 amountOut;\n}\n\nstruct SwapExactInDetails {\n address[] path;\n uint256 amountIn;\n uint256 amountOutMin;\n}\n\nstruct Adapter {\n address adapterAddress;\n bool isLibrary;\n bool isActive;\n}" - }, - "contracts/shoyu/lib/LibSushi.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport \"@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Pair.sol\";\n\n// returns sorted token addresses, used to handle return values from pairs sorted in this order\nfunction sortTokens(\n address tokenA,\n address tokenB\n) pure returns (address token0, address token1) {\n require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES');\n (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);\n require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS');\n}\n\n// calculates the CREATE2 address for a pair without making any external calls\nfunction pairFor(\n address factory,\n address tokenA,\n address tokenB,\n bytes32 pairCodeHash\n) pure returns (address pair) {\n (address token0, address token1) = sortTokens(tokenA, tokenB);\n pair = address(uint160(uint(keccak256(abi.encodePacked(\n hex'ff',\n factory,\n keccak256(abi.encodePacked(token0, token1)),\n pairCodeHash // init code hash\n )))));\n}\n\n// fetches and sorts the reserves for a pair\nfunction getReserves(\n address factory,\n address tokenA,\n address tokenB,\n bytes32 pairCodeHash\n) view returns (uint reserveA, uint reserveB) {\n (address token0,) = sortTokens(tokenA, tokenB);\n (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB, pairCodeHash)).getReserves();\n (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);\n}\n\n// given some amount of an asset and pair reserves, returns an equivalent amount of the other asset\nfunction quote(\n uint amountA,\n uint reserveA,\n uint reserveB\n) pure returns (uint amountB) {\n require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT');\n require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');\n amountB = amountA * reserveB / reserveA;\n}\n\n// given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset\nfunction getAmountOut(\n uint amountIn,\n uint reserveIn,\n uint reserveOut\n) pure returns (uint amountOut) {\n require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT');\n require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');\n uint amountInWithFee = amountIn* 997;\n uint numerator = amountInWithFee * reserveOut;\n uint denominator = reserveIn * 1000 + amountInWithFee;\n amountOut = numerator / denominator;\n}\n\n// given an output amount of an asset and pair reserves, returns a required input amount of the other asset\nfunction getAmountIn(\n uint amountOut,\n uint reserveIn,\n uint reserveOut\n) pure returns (uint amountIn) {\n require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');\n require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');\n uint numerator = reserveIn * amountOut * 1000;\n uint denominator = (reserveOut - amountOut) * 997;\n amountIn = numerator / denominator + 1;\n}\n\n// performs chained getAmountOut calculations on any number of pairs\nfunction getAmountsOut(\n address factory,\n uint amountIn,\n address[] memory path,\n bytes32 pairCodeHash\n) view returns (uint[] memory amounts) {\n require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');\n amounts = new uint[](path.length);\n amounts[0] = amountIn;\n for (uint i; i < path.length - 1; i++) {\n (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1], pairCodeHash);\n amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);\n }\n}\n\n// performs chained getAmountIn calculations on any number of pairs\nfunction getAmountsIn(\n address factory,\n uint amountOut,\n address[] memory path,\n bytes32 pairCodeHash\n) view returns (uint[] memory amounts) {\n require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');\n amounts = new uint[](path.length);\n amounts[amounts.length - 1] = amountOut;\n for (uint i = path.length - 1; i > 0; i--) {\n (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i], pairCodeHash);\n amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);\n }\n}\n" - }, - "contracts/shoyu/lib/ShoyuEnums.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nenum TokenSource {\n WALLET,\n CONDUIT,\n BENTO\n}" - }, - "contracts/shoyu/adapters/Transfer/BentoAdapter.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity >=0.8.11;\n\nimport \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport \"../../../sushiswap/IBentoBoxMinimal.sol\";\n\n/// @title BentoAdapter\n/// @notice Adapter which provides all functions of BentoBox require by this contract.\n/// @dev These are generic functions, make sure, only msg.sender, address(this) and address(bentoBox)\n/// are passed in the from param, or else the attacker can sifu user's funds in bentobox.\nabstract contract BentoAdapter {\n IBentoBoxMinimal public immutable bentoBox;\n\n constructor(address _bentoBox) {\n bentoBox = IBentoBoxMinimal(_bentoBox);\n }\n\n // deposits funds from address(this) into bentobox\n function depositToBentoBox(\n bool approve,\n address token,\n address to,\n uint256 amount,\n uint256 share,\n uint256 value\n ) public {\n if (approve) {\n ERC20(token).approve(address(bentoBox), type(uint256).max);\n }\n\n bentoBox.deposit{value: value}(token, address(this), to, amount, share);\n }\n\n /// @notice Deposits the token from users wallet into the BentoBox.\n /// @dev Make sure, only msg.sender, address(this) and address(bentoBox)\n /// are passed in the from param, or else the attacker can sifu user's funds in bentobox.\n /// Pass either amount or share.\n /// @param token token to deposit. Use token as address(0) when depositing native token\n /// @param from sender\n /// @param to receiver\n /// @param amount amount to be deposited\n /// @param share share to be deposited\n /// @param value native token value to be deposited. Only use when token address is address(0)\n function _depositToBentoBox(\n address token,\n address from,\n address to,\n uint256 amount,\n uint256 share,\n uint256 value\n ) internal {\n bentoBox.deposit{value: value}(token, from, to, amount, share);\n }\n\n /// @notice Transfers the token from bentobox user to another or withdraw it to another address.\n /// @dev Make sure, only msg.sender, address(this) and address(bentoBox)\n /// are passed in the from param, or else the attacker can sifu user's funds in bentobox.\n /// Pass either amount or share.\n /// @param token token to transfer. For native tokens, use wnative token address\n /// @param from sender\n /// @param to receiver\n /// @param amount amount to transfer\n /// @param share share to transfer\n /// @param unwrapBento use true for withdraw and false for transfer\n function _transferFromBentoBox(\n address token,\n address from,\n address to,\n uint256 amount,\n uint256 share,\n bool unwrapBento\n ) internal {\n if (unwrapBento) {\n bentoBox.withdraw(token, from, to, amount, share);\n } else {\n if (amount > 0) {\n share = bentoBox.toShare(token, amount, false);\n }\n bentoBox.transfer(token, from, to, share);\n }\n }\n}\n" - }, - "contracts/sushiswap/IBentoBoxMinimal.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity >=0.8.11;\n\n/// @notice Minimal BentoBox vault interface.\n/// @dev `token` is aliased as `address` from `IERC20` for simplicity.\ninterface IBentoBoxMinimal {\n /// @notice Balance per ERC-20 token per account in shares.\n function balanceOf(address, address) external view returns (uint256);\n\n /// @dev Helper function to represent an `amount` of `token` in shares.\n /// @param token The ERC-20 token.\n /// @param amount The `token` amount.\n /// @param roundUp If the result `share` should be rounded up.\n /// @return share The token amount represented in shares.\n function toShare(\n address token,\n uint256 amount,\n bool roundUp\n ) external view returns (uint256 share);\n\n /// @dev Helper function to represent shares back into the `token` amount.\n /// @param token The ERC-20 token.\n /// @param share The amount of shares.\n /// @param roundUp If the result should be rounded up.\n /// @return amount The share amount back into native representation.\n function toAmount(\n address token,\n uint256 share,\n bool roundUp\n ) external view returns (uint256 amount);\n\n /// @notice Registers this contract so that users can approve it for BentoBox.\n function registerProtocol() external;\n\n /// @notice Deposit an amount of `token` represented in either `amount` or `share`.\n /// @param token_ The ERC-20 token to deposit.\n /// @param from which account to pull the tokens.\n /// @param to which account to push the tokens.\n /// @param amount Token amount in native representation to deposit.\n /// @param share Token amount represented in shares to deposit. Takes precedence over `amount`.\n /// @return amountOut The amount deposited.\n /// @return shareOut The deposited amount represented in shares.\n function deposit(\n address token_,\n address from,\n address to,\n uint256 amount,\n uint256 share\n ) external payable returns (uint256 amountOut, uint256 shareOut);\n\n /// @notice Withdraws an amount of `token` from a user account.\n /// @param token_ The ERC-20 token to withdraw.\n /// @param from which user to pull the tokens.\n /// @param to which user to push the tokens.\n /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.\n /// @param share Like above, but `share` takes precedence over `amount`.\n function withdraw(\n address token_,\n address from,\n address to,\n uint256 amount,\n uint256 share\n ) external returns (uint256 amountOut, uint256 shareOut);\n\n /// @notice Transfer shares from a user account to another one.\n /// @param token The ERC-20 token to transfer.\n /// @param from which user to pull the tokens.\n /// @param to which user to push the tokens.\n /// @param share The amount of `token` in shares.\n function transfer(\n address token,\n address from,\n address to,\n uint256 share\n ) external;\n\n function setMasterContractApproval(\n address user,\n address masterContract,\n bool approved,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "contracts/shoyu/adapters/Transform/TransformationAdapter.sol": { - "content": "pragma solidity >=0.8.11;\n\nimport \"@sushiswap/core/contracts/uniswapv2/interfaces/IWETH.sol\";\nimport \"./LegacySwapAdapter.sol\";\n\ncontract TransformationAdapter is LegacySwapAdapter {\n address private immutable WETH;\n\n constructor(\n address _weth,\n address _factory,\n bytes32 _pairCodeHash,\n address _conduitController,\n address _bentobox\n ) LegacySwapAdapter(_factory, _pairCodeHash, _conduitController, _bentobox) {\n WETH = _weth;\n }\n\n // transfers funds from msg.sender & performs swaps\n function swapExactOut(\n uint256 amountOut,\n uint256 amountInMax,\n address[] memory path,\n address payable to,\n TokenSource tokenSource,\n bytes memory transferData,\n bool unwrapNative\n ) public payable {\n _legacySwapExactOut(\n amountOut,\n amountInMax,\n path,\n unwrapNative ? address(this) : to,\n tokenSource,\n transferData\n );\n\n if (unwrapNative) {\n IWETH(WETH).withdraw(amountOut);\n if (to != address(this)) {\n _transferEth(to, amountOut);\n }\n }\n }\n\n // requires path[0] to have been sent to address(this)\n function swapExactIn(\n uint256 amountIn,\n uint256 amountOutMin,\n address[] memory path,\n address payable to,\n bool unwrapNative\n ) public payable {\n uint256 amountOut = _legacySwapExactIn(\n amountIn,\n amountOutMin,\n path,\n unwrapNative ? address(this) : to\n );\n\n if (unwrapNative) {\n IWETH(WETH).withdraw(amountOut);\n if (to != address(this)) {\n _transferEth(to, amountOut);\n }\n }\n\n }\n\n // requires WETH to have been sent to address(this)\n function unwrapNativeToken(\n uint256 amount,\n address payable to\n ) public payable {\n IWETH(WETH).withdraw(amount);\n if (to != address(this)) {\n _transferEth(to, amount);\n }\n }\n\n // requires ETH to have been sent to address(this)\n function wrapNativeToken(uint256 amount) public payable {\n IWETH(WETH).deposit{value: amount}();\n }\n}" - }, - "@sushiswap/core/contracts/uniswapv2/interfaces/IWETH.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.5.0;\n\ninterface IWETH {\n function deposit() external payable;\n function transfer(address to, uint value) external returns (bool);\n function withdraw(uint) external;\n}" - }, - "@sushiswap/core/contracts/uniswapv2/interfaces/IERC20.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.5.0;\n\ninterface IERC20Uniswap {\n event Approval(address indexed owner, address indexed spender, uint value);\n event Transfer(address indexed from, address indexed to, uint value);\n\n function name() external view returns (string memory);\n function symbol() external view returns (string memory);\n function decimals() external view returns (uint8);\n function totalSupply() external view returns (uint);\n function balanceOf(address owner) external view returns (uint);\n function allowance(address owner, address spender) external view returns (uint);\n\n function approve(address spender, uint value) external returns (bool);\n function transfer(address to, uint value) external returns (bool);\n function transferFrom(address from, address to, uint value) external returns (bool);\n}\n" - }, - "@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Callee.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.5.0;\n\ninterface IUniswapV2Callee {\n function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;\n}\n" - }, - "@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Factory.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.5.0;\n\ninterface IUniswapV2Factory {\n event PairCreated(address indexed token0, address indexed token1, address pair, uint);\n\n function feeTo() external view returns (address);\n function feeToSetter() external view returns (address);\n function migrator() external view returns (address);\n\n function getPair(address tokenA, address tokenB) external view returns (address pair);\n function allPairs(uint) external view returns (address pair);\n function allPairsLength() external view returns (uint);\n\n function createPair(address tokenA, address tokenB) external returns (address pair);\n\n function setFeeTo(address) external;\n function setFeeToSetter(address) external;\n function setMigrator(address) external;\n}\n" - }, - "@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Router02.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.6.2;\n\nimport './IUniswapV2Router01.sol';\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n function removeLiquidityETHSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountETH);\n function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountETH);\n\n function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n function swapExactETHForTokensSupportingFeeOnTransferTokens(\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external payable;\n function swapExactTokensForETHSupportingFeeOnTransferTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external;\n}" - }, - "@sushiswap/core/contracts/uniswapv2/interfaces/IUniswapV2Router01.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.6.2;\n\ninterface IUniswapV2Router01 {\n function factory() external pure returns (address);\n function WETH() external pure returns (address);\n\n function addLiquidity(\n address tokenA,\n address tokenB,\n uint amountADesired,\n uint amountBDesired,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB, uint liquidity);\n function addLiquidityETH(\n address token,\n uint amountTokenDesired,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n function removeLiquidity(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETH(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline\n ) external returns (uint amountToken, uint amountETH);\n function removeLiquidityWithPermit(\n address tokenA,\n address tokenB,\n uint liquidity,\n uint amountAMin,\n uint amountBMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountA, uint amountB);\n function removeLiquidityETHWithPermit(\n address token,\n uint liquidity,\n uint amountTokenMin,\n uint amountETHMin,\n address to,\n uint deadline,\n bool approveMax, uint8 v, bytes32 r, bytes32 s\n ) external returns (uint amountToken, uint amountETH);\n function swapExactTokensForTokens(\n uint amountIn,\n uint amountOutMin,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapTokensForExactTokens(\n uint amountOut,\n uint amountInMax,\n address[] calldata path,\n address to,\n uint deadline\n ) external returns (uint[] memory amounts);\n function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n external\n returns (uint[] memory amounts);\n function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n external\n payable\n returns (uint[] memory amounts);\n\n function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}" - }, - "@sushiswap/core/contracts/uniswapv2/libraries/TransferHelper.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.6.0;\n\n// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false\nlibrary TransferHelper {\n function safeApprove(address token, address to, uint value) internal {\n // bytes4(keccak256(bytes('approve(address,uint256)')));\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));\n require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');\n }\n\n function safeTransfer(address token, address to, uint value) internal {\n // bytes4(keccak256(bytes('transfer(address,uint256)')));\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));\n require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');\n }\n\n function safeTransferFrom(address token, address from, address to, uint value) internal {\n // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));\n (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));\n require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');\n }\n\n function safeTransferETH(address to, uint value) internal {\n (bool success,) = to.call{value:value}(new bytes(0));\n require(success, 'TransferHelper: ETH_TRANSFER_FAILED');\n }\n}\n" - }, - "contracts/shoyu/Shoyu.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport \"@rari-capital/solmate/src/tokens/ERC1155.sol\";\nimport \"./interfaces/IShoyu.sol\";\nimport \"./lib/AdapterRegistry.sol\";\nimport \"../sushiswap/IBentoBoxMinimal.sol\";\n\ncontract Shoyu is Initializable, UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable {\n AdapterRegistry public adapterRegistry;\n\n function initialize(address _adapterRegistery, address _bentobox) initializer public {\n adapterRegistry = AdapterRegistry(_adapterRegistery);\n IBentoBoxMinimal(_bentobox).registerProtocol();\n\n __Ownable_init();\n }\n\n function cook(\n uint8[] calldata adapterIds,\n uint256[] calldata values,\n bytes[] calldata datas\n ) external payable whenNotPaused {\n uint256 length = adapterIds.length;\n for (uint256 i; i < length; ++i) {\n (\n address adapterAddress,\n bool isLibrary,\n bool isActive\n ) = adapterRegistry.adapters(adapterIds[i]);\n\n require(isActive, \"cook: inactive adapter\");\n\n (bool success, ) = isLibrary ? adapterAddress.delegatecall(datas[i])\n : adapterAddress.call{value: values[i]}(datas[i]);\n\n if (!success) {\n assembly {\n returndatacopy(0, 0, returndatasize())\n revert(0, returndatasize())\n }\n }\n }\n\n _refundExcessETH();\n }\n\n function _transferETH(address to, uint256 amount) internal {\n assembly {\n let success := call(gas(), to, amount, 0, 0, 0, 0)\n if eq(success, 0) { revert(0, 0) }\n }\n }\n\n function _refundExcessETH() internal {\n uint256 balance = address(this).balance;\n if (balance > 0) {\n _transferETH(msg.sender, balance);\n }\n }\n\n function approveERC20(\n address token,\n address operator,\n uint256 amount\n ) external onlyOwner {\n ERC20(token).approve(operator, amount);\n }\n\n function retrieveETH(address to, uint256 amount) onlyOwner external {\n _transferETH(to, amount);\n }\n\n function retrieveERC20(address token, address to, uint256 amount) onlyOwner external {\n ERC20(token).transfer(to, amount);\n }\n\n function retrieveERC721(\n address token,\n uint256[] calldata tokenIds,\n address to\n ) onlyOwner external {\n uint256 length = tokenIds.length;\n for (uint256 i; i < length; ++i) {\n ERC721(token).safeTransferFrom(address(this), to, tokenIds[i]);\n }\n }\n\n function retrieveERC1155(\n address token,\n uint256[] calldata tokenIds,\n uint256[] calldata amounts,\n address to\n ) onlyOwner external {\n ERC1155(token).safeBatchTransferFrom(address(this), to, tokenIds, amounts, \"\");\n }\n\n /// @dev Fallback for just receiving ether.\n receive() external payable {}\n\n /// @dev Allows this contract to receive ERC1155 tokens\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) public virtual returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) public virtual returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n\n /// @dev Required by UUPSUpgradeable\n function _authorizeUpgrade(address) internal override onlyOwner {}\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\n function __UUPSUpgradeable_init() internal onlyInitializing {\n }\n\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n }\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate that the this implementation remains valid after an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeTo(address newImplementation) external virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@rari-capital/solmate/src/tokens/ERC721.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\n/// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC.\nabstract contract ERC721 {\n /*///////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*///////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*///////////////////////////////////////////////////////////////\n ERC721 STORAGE \n //////////////////////////////////////////////////////////////*/\n\n mapping(address => uint256) public balanceOf;\n\n mapping(uint256 => address) public ownerOf;\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*///////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*///////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n balanceOf[from]--;\n\n balanceOf[to]++;\n }\n\n ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes memory data\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*///////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*///////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n balanceOf[to]++;\n }\n\n ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = ownerOf[id];\n\n require(ownerOf[id] != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n balanceOf[owner]--;\n }\n\n delete ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*///////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\ninterface ERC721TokenReceiver {\n function onERC721Received(\n address operator,\n address from,\n uint256 id,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "@rari-capital/solmate/src/tokens/ERC1155.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Minimalist and gas efficient standard ERC1155 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)\nabstract contract ERC1155 {\n /*///////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event TransferSingle(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 id,\n uint256 amount\n );\n\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] amounts\n );\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n event URI(string value, uint256 indexed id);\n\n /*///////////////////////////////////////////////////////////////\n ERC1155 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(address => mapping(uint256 => uint256)) public balanceOf;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*///////////////////////////////////////////////////////////////\n METADATA LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function uri(uint256 id) public view virtual returns (string memory);\n\n /*///////////////////////////////////////////////////////////////\n ERC1155 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual {\n require(msg.sender == from || isApprovedForAll[from][msg.sender], \"NOT_AUTHORIZED\");\n\n balanceOf[from][id] -= amount;\n balanceOf[to][id] += amount;\n\n emit TransferSingle(msg.sender, from, to, id, amount);\n\n require(\n to.code.length == 0\n ? to != address(0)\n : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==\n ERC1155TokenReceiver.onERC1155Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) public virtual {\n uint256 idsLength = ids.length; // Saves MLOADs.\n\n require(idsLength == amounts.length, \"LENGTH_MISMATCH\");\n\n require(msg.sender == from || isApprovedForAll[from][msg.sender], \"NOT_AUTHORIZED\");\n\n for (uint256 i = 0; i < idsLength; ) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n\n balanceOf[from][id] -= amount;\n balanceOf[to][id] += amount;\n\n // An array can't have a total length\n // larger than the max uint256 value.\n unchecked {\n i++;\n }\n }\n\n emit TransferBatch(msg.sender, from, to, ids, amounts);\n\n require(\n to.code.length == 0\n ? to != address(0)\n : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==\n ERC1155TokenReceiver.onERC1155BatchReceived.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function balanceOfBatch(address[] memory owners, uint256[] memory ids)\n public\n view\n virtual\n returns (uint256[] memory balances)\n {\n uint256 ownersLength = owners.length; // Saves MLOADs.\n\n require(ownersLength == ids.length, \"LENGTH_MISMATCH\");\n\n balances = new uint256[](owners.length);\n\n // Unchecked because the only math done is incrementing\n // the array index counter which cannot possibly overflow.\n unchecked {\n for (uint256 i = 0; i < ownersLength; i++) {\n balances[i] = balanceOf[owners[i]][ids[i]];\n }\n }\n }\n\n /*///////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155\n interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI\n }\n\n /*///////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) internal {\n balanceOf[to][id] += amount;\n\n emit TransferSingle(msg.sender, address(0), to, id, amount);\n\n require(\n to.code.length == 0\n ? to != address(0)\n : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==\n ERC1155TokenReceiver.onERC1155Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _batchMint(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) internal {\n uint256 idsLength = ids.length; // Saves MLOADs.\n\n require(idsLength == amounts.length, \"LENGTH_MISMATCH\");\n\n for (uint256 i = 0; i < idsLength; ) {\n balanceOf[to][ids[i]] += amounts[i];\n\n // An array can't have a total length\n // larger than the max uint256 value.\n unchecked {\n i++;\n }\n }\n\n emit TransferBatch(msg.sender, address(0), to, ids, amounts);\n\n require(\n to.code.length == 0\n ? to != address(0)\n : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==\n ERC1155TokenReceiver.onERC1155BatchReceived.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _batchBurn(\n address from,\n uint256[] memory ids,\n uint256[] memory amounts\n ) internal {\n uint256 idsLength = ids.length; // Saves MLOADs.\n\n require(idsLength == amounts.length, \"LENGTH_MISMATCH\");\n\n for (uint256 i = 0; i < idsLength; ) {\n balanceOf[from][ids[i]] -= amounts[i];\n\n // An array can't have a total length\n // larger than the max uint256 value.\n unchecked {\n i++;\n }\n }\n\n emit TransferBatch(msg.sender, from, address(0), ids, amounts);\n }\n\n function _burn(\n address from,\n uint256 id,\n uint256 amount\n ) internal {\n balanceOf[from][id] -= amount;\n\n emit TransferSingle(msg.sender, from, address(0), id, amount);\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol)\ninterface ERC1155TokenReceiver {\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 amount,\n bytes calldata data\n ) external returns (bytes4);\n\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "contracts/shoyu/interfaces/IShoyu.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\ninterface IShoyu {\n function cook(\n uint8[] calldata adapterIds,\n uint256[] calldata values,\n bytes[] calldata datas\n ) payable external;\n\n function approveERC20(\n address token,\n address operator,\n uint256 amount\n ) external;\n\n function retrieveETH(address to, uint256 amount) external;\n\n function retrieveERC20(address token, address to, uint256 amount) external;\n\n function retrieveERC721(\n address token,\n uint256[] calldata tokenIds,\n address to\n ) external;\n\n function retrieveERC1155(\n address token,\n uint256[] calldata tokenIds,\n uint256[] calldata amounts,\n address to\n ) external;\n}\n" - }, - "contracts/shoyu/lib/AdapterRegistry.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/IAdapterRegistry.sol\";\nimport { Adapter } from \"./ShoyuStructs.sol\";\n\ncontract AdapterRegistry is IAdapterRegistry, Ownable {\n Adapter[] public adapters;\n\n constructor(\n uint256 length,\n address[] memory adapterAddress,\n bool[] memory isLibrary\n ) {\n for (uint256 i; i < length; ++i) {\n adapters.push(Adapter(adapterAddress[i], isLibrary[i], true));\n }\n }\n\n function setAdapterAddress(\n uint256 id,\n address adapterAddress\n ) external onlyOwner {\n Adapter storage adapter = adapters[id];\n adapter.adapterAddress = adapterAddress; \n }\n\n function setAdapterStatus(\n uint256 id,\n bool isActive\n ) external onlyOwner {\n Adapter storage adapter = adapters[id];\n adapter.isActive = isActive;\n }\n\n function addAdapter(\n address adapterAddress,\n bool isLibrary\n ) external onlyOwner {\n adapters.push(Adapter(adapterAddress, isLibrary, true));\n }\n}" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822ProxiableUpgradeable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967UpgradeUpgradeable is Initializable {\n function __ERC1967Upgrade_init() internal onlyInitializing {\n }\n\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\n }\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n _functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n }\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {\n require(AddressUpgradeable.isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return AddressUpgradeable.verifyCallResult(success, returndata, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeaconUpgradeable {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlotUpgradeable {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts/access/Ownable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" - }, - "contracts/shoyu/interfaces/IAdapterRegistry.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.11;\n\nimport { Adapter } from \"../lib/ShoyuStructs.sol\";\n\ninterface IAdapterRegistry {\n function setAdapterAddress(\n uint256 id,\n address adapterAddress\n ) external;\n\n function setAdapterStatus(\n uint256 id,\n bool isActive\n ) external;\n\n function addAdapter(\n address adapterAddress,\n bool isLibrary\n ) external;\n}" - }, - "@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "contracts/test/TestERC1155.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.7;\n\nimport \"@rari-capital/solmate/src/tokens/ERC1155.sol\";\n\n// Used for minting test ERC1155s in our tests\ncontract TestERC1155 is ERC1155 {\n function mint(\n address to,\n uint256 tokenId,\n uint256 amount\n ) public returns (bool) {\n _mint(to, tokenId, amount, \"\");\n return true;\n }\n\n function uri(uint256) public pure override returns (string memory) {\n return \"uri\";\n }\n}\n" - }, - "contracts/test/TestERC721.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.7;\n\nimport \"@rari-capital/solmate/src/tokens/ERC721.sol\";\n\n// Used for minting test ERC721s in our tests\ncontract TestERC721 is ERC721(\"Test721\", \"TST721\") {\n function mint(address to, uint256 tokenId) public returns (bool) {\n _mint(to, tokenId);\n return true;\n }\n\n function tokenURI(uint256) public pure override returns (string memory) {\n return \"tokenURI\";\n }\n}\n" - }, - "contracts/shoyu/adapters/Markets/SeaportAdapter.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.11;\n\nimport \"@rari-capital/solmate/src/tokens/ERC721.sol\";\n\ncontract SeaportAdapter {\n address public immutable seaportAddress;\n\n constructor(address _seaportAddress) {\n seaportAddress = _seaportAddress;\n }\n\n function approveBeforeFulfill (\n address[] calldata tokensToApprove,\n uint256 ethAmount,\n bytes calldata data\n ) external payable returns (bool success, bytes memory returnData) {\n uint256 length = tokensToApprove.length;\n for (uint256 i; i < length; ++i) {\n if (!ERC721(tokensToApprove[i]).isApprovedForAll(address(this), seaportAddress)) {\n ERC721(tokensToApprove[i]).setApprovalForAll(seaportAddress, true);\n }\n }\n\n (success, returnData) = seaportAddress.call{value: ethAmount}(data);\n\n if (!success) {\n assembly {\n returndatacopy(0, 0, returndatasize())\n revert(0, returndatasize())\n }\n }\n }\n\n function fulfill (\n uint256 ethAmount,\n bytes calldata data\n ) external payable returns (bool success, bytes memory returnData) {\n (success, returnData) = seaportAddress.call{value: ethAmount}(data);\n\n if (!success) {\n assembly {\n returndatacopy(0, 0, returndatasize())\n revert(0, returndatasize())\n }\n }\n }\n}" - }, - "contracts/test/TestERC20.sol": { - "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.7;\n\nimport \"@rari-capital/solmate/src/tokens/ERC20.sol\";\n\n// Used for minting test ERC20s in our tests\ncontract TestERC20 is ERC20(\"Test20\", \"TST20\", 18) {\n bool public blocked;\n\n bool public noReturnData;\n\n constructor() {\n blocked = false;\n noReturnData = false;\n }\n\n function blockTransfer(bool blocking) external {\n blocked = blocking;\n }\n\n function setNoReturnData(bool noReturn) external {\n noReturnData = noReturn;\n }\n\n function mint(address to, uint256 amount) external returns (bool) {\n _mint(to, amount);\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public override returns (bool ok) {\n if (blocked) {\n return false;\n }\n\n super.transferFrom(from, to, amount);\n\n if (noReturnData) {\n assembly {\n return(0, 0)\n }\n }\n\n ok = true;\n }\n}\n" - }, - "seaport/contracts/lib/Executor.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { ConduitInterface } from \"../interfaces/ConduitInterface.sol\";\n\nimport { ConduitItemType } from \"../conduit/lib/ConduitEnums.sol\";\n\nimport { ItemType } from \"./ConsiderationEnums.sol\";\n\nimport { ReceivedItem } from \"./ConsiderationStructs.sol\";\n\nimport { Verifiers } from \"./Verifiers.sol\";\n\nimport { TokenTransferrer } from \"./TokenTransferrer.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title Executor\n * @author 0age\n * @notice Executor contains functions related to processing executions (i.e.\n * transferring items, either directly or via conduits).\n */\ncontract Executor is Verifiers, TokenTransferrer {\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) Verifiers(conduitController) {}\n\n /**\n * @dev Internal function to transfer a given item, either directly or via\n * a corresponding conduit.\n *\n * @param item The item to transfer, including an amount and a\n * recipient.\n * @param from The account supplying the item.\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n */\n function _transfer(\n ReceivedItem memory item,\n address from,\n bytes32 conduitKey,\n bytes memory accumulator\n ) internal {\n // If the item type indicates Ether or a native token...\n if (item.itemType == ItemType.NATIVE) {\n // Ensure neither the token nor the identifier parameters are set.\n if ((uint160(item.token) | item.identifier) != 0) {\n revert UnusedItemParameters();\n }\n\n // transfer the native tokens to the recipient.\n _transferEth(item.recipient, item.amount);\n } else if (item.itemType == ItemType.ERC20) {\n // Ensure that no identifier is supplied.\n if (item.identifier != 0) {\n revert UnusedItemParameters();\n }\n\n // Transfer ERC20 tokens from the source to the recipient.\n _transferERC20(\n item.token,\n from,\n item.recipient,\n item.amount,\n conduitKey,\n accumulator\n );\n } else if (item.itemType == ItemType.ERC721) {\n // Transfer ERC721 token from the source to the recipient.\n _transferERC721(\n item.token,\n from,\n item.recipient,\n item.identifier,\n item.amount,\n conduitKey,\n accumulator\n );\n } else {\n // Transfer ERC1155 token from the source to the recipient.\n _transferERC1155(\n item.token,\n from,\n item.recipient,\n item.identifier,\n item.amount,\n conduitKey,\n accumulator\n );\n }\n }\n\n /**\n * @dev Internal function to transfer an individual ERC721 or ERC1155 item\n * from a given originator to a given recipient. The accumulator will\n * be bypassed, meaning that this function should be utilized in cases\n * where multiple item transfers can be accumulated into a single\n * conduit call. Sufficient approvals must be set, either on the\n * respective conduit or on this contract itself.\n *\n * @param itemType The type of item to transfer, either ERC721 or ERC1155.\n * @param token The token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param identifier The tokenId to transfer.\n * @param amount The amount to transfer.\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n */\n function _transferIndividual721Or1155Item(\n ItemType itemType,\n address token,\n address from,\n address to,\n uint256 identifier,\n uint256 amount,\n bytes32 conduitKey\n ) internal {\n // Determine if the transfer is to be performed via a conduit.\n if (conduitKey != bytes32(0)) {\n // Use free memory pointer as calldata offset for the conduit call.\n uint256 callDataOffset;\n\n // Utilize assembly to place each argument in free memory.\n assembly {\n // Retrieve the free memory pointer and use it as the offset.\n callDataOffset := mload(FreeMemoryPointerSlot)\n\n // Write ConduitInterface.execute.selector to memory.\n mstore(callDataOffset, Conduit_execute_signature)\n\n // Write the offset to the ConduitTransfer array in memory.\n mstore(\n add(\n callDataOffset,\n Conduit_execute_ConduitTransfer_offset_ptr\n ),\n Conduit_execute_ConduitTransfer_ptr\n )\n\n // Write the length of the ConduitTransfer array to memory.\n mstore(\n add(\n callDataOffset,\n Conduit_execute_ConduitTransfer_length_ptr\n ),\n Conduit_execute_ConduitTransfer_length\n )\n\n // Write the item type to memory.\n mstore(\n add(callDataOffset, Conduit_execute_transferItemType_ptr),\n itemType\n )\n\n // Write the token to memory.\n mstore(\n add(callDataOffset, Conduit_execute_transferToken_ptr),\n token\n )\n\n // Write the transfer source to memory.\n mstore(\n add(callDataOffset, Conduit_execute_transferFrom_ptr),\n from\n )\n\n // Write the transfer recipient to memory.\n mstore(add(callDataOffset, Conduit_execute_transferTo_ptr), to)\n\n // Write the token identifier to memory.\n mstore(\n add(callDataOffset, Conduit_execute_transferIdentifier_ptr),\n identifier\n )\n\n // Write the transfer amount to memory.\n mstore(\n add(callDataOffset, Conduit_execute_transferAmount_ptr),\n amount\n )\n }\n\n // Perform the call to the conduit.\n _callConduitUsingOffsets(\n conduitKey,\n callDataOffset,\n OneConduitExecute_size\n );\n } else {\n // Otherwise, determine whether it is an ERC721 or ERC1155 item.\n if (itemType == ItemType.ERC721) {\n // Ensure that exactly one 721 item is being transferred.\n if (amount != 1) {\n revert InvalidERC721TransferAmount();\n }\n\n // Perform transfer via the token contract directly.\n _performERC721Transfer(token, from, to, identifier);\n } else {\n // Perform transfer via the token contract directly.\n _performERC1155Transfer(token, from, to, identifier, amount);\n }\n }\n }\n\n /**\n * @dev Internal function to transfer Ether or other native tokens to a\n * given recipient.\n *\n * @param to The recipient of the transfer.\n * @param amount The amount to transfer.\n */\n function _transferEth(address payable to, uint256 amount) internal {\n // Ensure that the supplied amount is non-zero.\n _assertNonZeroAmount(amount);\n\n // Declare a variable indicating whether the call was successful or not.\n bool success;\n\n assembly {\n // Transfer the ETH and store if it succeeded or not.\n success := call(gas(), to, amount, 0, 0, 0, 0)\n }\n\n // If the call fails...\n if (!success) {\n // Revert and pass the revert reason along if one was returned.\n _revertWithReasonIfOneIsReturned();\n\n // Otherwise, revert with a generic error message.\n revert EtherTransferGenericFailure(to, amount);\n }\n }\n\n /**\n * @dev Internal function to transfer ERC20 tokens from a given originator\n * to a given recipient using a given conduit if applicable. Sufficient\n * approvals must be set on this contract or on a respective conduit.\n *\n * @param token The ERC20 token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param amount The amount to transfer.\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n */\n function _transferERC20(\n address token,\n address from,\n address to,\n uint256 amount,\n bytes32 conduitKey,\n bytes memory accumulator\n ) internal {\n // Ensure that the supplied amount is non-zero.\n _assertNonZeroAmount(amount);\n\n // Trigger accumulated transfers if the conduits differ.\n _triggerIfArmedAndNotAccumulatable(accumulator, conduitKey);\n\n // If no conduit has been specified...\n if (conduitKey == bytes32(0)) {\n // Perform the token transfer directly.\n _performERC20Transfer(token, from, to, amount);\n } else {\n // Insert the call to the conduit into the accumulator.\n _insert(\n conduitKey,\n accumulator,\n ConduitItemType.ERC20,\n token,\n from,\n to,\n uint256(0),\n amount\n );\n }\n }\n\n /**\n * @dev Internal function to transfer a single ERC721 token from a given\n * originator to a given recipient. Sufficient approvals must be set,\n * either on the respective conduit or on this contract itself.\n *\n * @param token The ERC721 token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param identifier The tokenId to transfer (must be 1 for ERC721).\n * @param amount The amount to transfer.\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n */\n function _transferERC721(\n address token,\n address from,\n address to,\n uint256 identifier,\n uint256 amount,\n bytes32 conduitKey,\n bytes memory accumulator\n ) internal {\n // Trigger accumulated transfers if the conduits differ.\n _triggerIfArmedAndNotAccumulatable(accumulator, conduitKey);\n\n // If no conduit has been specified...\n if (conduitKey == bytes32(0)) {\n // Ensure that exactly one 721 item is being transferred.\n if (amount != 1) {\n revert InvalidERC721TransferAmount();\n }\n\n // Perform transfer via the token contract directly.\n _performERC721Transfer(token, from, to, identifier);\n } else {\n // Insert the call to the conduit into the accumulator.\n _insert(\n conduitKey,\n accumulator,\n ConduitItemType.ERC721,\n token,\n from,\n to,\n identifier,\n amount\n );\n }\n }\n\n /**\n * @dev Internal function to transfer ERC1155 tokens from a given originator\n * to a given recipient. Sufficient approvals must be set, either on\n * the respective conduit or on this contract itself.\n *\n * @param token The ERC1155 token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param identifier The id to transfer.\n * @param amount The amount to transfer.\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n */\n function _transferERC1155(\n address token,\n address from,\n address to,\n uint256 identifier,\n uint256 amount,\n bytes32 conduitKey,\n bytes memory accumulator\n ) internal {\n // Ensure that the supplied amount is non-zero.\n _assertNonZeroAmount(amount);\n\n // Trigger accumulated transfers if the conduits differ.\n _triggerIfArmedAndNotAccumulatable(accumulator, conduitKey);\n\n // If no conduit has been specified...\n if (conduitKey == bytes32(0)) {\n // Perform transfer via the token contract directly.\n _performERC1155Transfer(token, from, to, identifier, amount);\n } else {\n // Insert the call to the conduit into the accumulator.\n _insert(\n conduitKey,\n accumulator,\n ConduitItemType.ERC1155,\n token,\n from,\n to,\n identifier,\n amount\n );\n }\n }\n\n /**\n * @dev Internal function to trigger a call to the conduit currently held by\n * the accumulator if the accumulator contains item transfers (i.e. it\n * is \"armed\") and the supplied conduit key does not match the key held\n * by the accumulator.\n *\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n */\n function _triggerIfArmedAndNotAccumulatable(\n bytes memory accumulator,\n bytes32 conduitKey\n ) internal {\n // Retrieve the current conduit key from the accumulator.\n bytes32 accumulatorConduitKey = _getAccumulatorConduitKey(accumulator);\n\n // Perform conduit call if the set key does not match the supplied key.\n if (accumulatorConduitKey != conduitKey) {\n _triggerIfArmed(accumulator);\n }\n }\n\n /**\n * @dev Internal function to trigger a call to the conduit currently held by\n * the accumulator if the accumulator contains item transfers (i.e. it\n * is \"armed\").\n *\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n */\n function _triggerIfArmed(bytes memory accumulator) internal {\n // Exit if the accumulator is not \"armed\".\n if (accumulator.length != AccumulatorArmed) {\n return;\n }\n\n // Retrieve the current conduit key from the accumulator.\n bytes32 accumulatorConduitKey = _getAccumulatorConduitKey(accumulator);\n\n // Perform conduit call.\n _trigger(accumulatorConduitKey, accumulator);\n }\n\n /**\n * @dev Internal function to trigger a call to the conduit corresponding to\n * a given conduit key, supplying all accumulated item transfers. The\n * accumulator will be \"disarmed\" and reset in the process.\n *\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n */\n function _trigger(bytes32 conduitKey, bytes memory accumulator) internal {\n // Declare variables for offset in memory & size of calldata to conduit.\n uint256 callDataOffset;\n uint256 callDataSize;\n\n // Call the conduit with all the accumulated transfers.\n assembly {\n // Call begins at third word; the first is length or \"armed\" status,\n // and the second is the current conduit key.\n callDataOffset := add(accumulator, TwoWords)\n\n // 68 + items * 192\n callDataSize := add(\n Accumulator_array_offset_ptr,\n mul(\n mload(add(accumulator, Accumulator_array_length_ptr)),\n Conduit_transferItem_size\n )\n )\n }\n\n // Call conduit derived from conduit key & supply accumulated transfers.\n _callConduitUsingOffsets(conduitKey, callDataOffset, callDataSize);\n\n // Reset accumulator length to signal that it is now \"disarmed\".\n assembly {\n mstore(accumulator, AccumulatorDisarmed)\n }\n }\n\n /**\n * @dev Internal function to perform a call to the conduit corresponding to\n * a given conduit key based on the offset and size of the calldata in\n * question in memory.\n *\n * @param conduitKey A bytes32 value indicating what corresponding\n * conduit, if any, to source token approvals from.\n * The zero hash signifies that no conduit should be\n * used, with direct approvals set on this contract.\n * @param callDataOffset The memory pointer where calldata is contained.\n * @param callDataSize The size of calldata in memory.\n */\n function _callConduitUsingOffsets(\n bytes32 conduitKey,\n uint256 callDataOffset,\n uint256 callDataSize\n ) internal {\n // Derive the address of the conduit using the conduit key.\n address conduit = _deriveConduit(conduitKey);\n\n bool success;\n bytes4 result;\n\n // call the conduit.\n assembly {\n // Ensure first word of scratch space is empty.\n mstore(0, 0)\n\n // Perform call, placing first word of return data in scratch space.\n success := call(\n gas(),\n conduit,\n 0,\n callDataOffset,\n callDataSize,\n 0,\n OneWord\n )\n\n // Take value from scratch space and place it on the stack.\n result := mload(0)\n }\n\n // If the call failed...\n if (!success) {\n // Pass along whatever revert reason was given by the conduit.\n _revertWithReasonIfOneIsReturned();\n\n // Otherwise, revert with a generic error.\n revert InvalidCallToConduit(conduit);\n }\n\n // Ensure result was extracted and matches EIP-1271 magic value.\n if (result != ConduitInterface.execute.selector) {\n revert InvalidConduit(conduitKey, conduit);\n }\n }\n\n /**\n * @dev Internal pure function to retrieve the current conduit key set for\n * the accumulator.\n *\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n *\n * @return accumulatorConduitKey The conduit key currently set for the\n * accumulator.\n */\n function _getAccumulatorConduitKey(bytes memory accumulator)\n internal\n pure\n returns (bytes32 accumulatorConduitKey)\n {\n // Retrieve the current conduit key from the accumulator.\n assembly {\n accumulatorConduitKey := mload(\n add(accumulator, Accumulator_conduitKey_ptr)\n )\n }\n }\n\n /**\n * @dev Internal pure function to place an item transfer into an accumulator\n * that collects a series of transfers to execute against a given\n * conduit in a single call.\n *\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. The zero hash\n * signifies that no conduit should be used, with direct\n * approvals set on this contract.\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n * @param itemType The type of the item to transfer.\n * @param token The token to transfer.\n * @param from The originator of the transfer.\n * @param to The recipient of the transfer.\n * @param identifier The tokenId to transfer.\n * @param amount The amount to transfer.\n */\n function _insert(\n bytes32 conduitKey,\n bytes memory accumulator,\n ConduitItemType itemType,\n address token,\n address from,\n address to,\n uint256 identifier,\n uint256 amount\n ) internal pure {\n uint256 elements;\n // \"Arm\" and prime accumulator if it's not already armed. The sentinel\n // value is held in the length of the accumulator array.\n if (accumulator.length == AccumulatorDisarmed) {\n elements = 1;\n bytes4 selector = ConduitInterface.execute.selector;\n assembly {\n mstore(accumulator, AccumulatorArmed) // \"arm\" the accumulator.\n mstore(add(accumulator, Accumulator_conduitKey_ptr), conduitKey)\n mstore(add(accumulator, Accumulator_selector_ptr), selector)\n mstore(\n add(accumulator, Accumulator_array_offset_ptr),\n Accumulator_array_offset\n )\n mstore(add(accumulator, Accumulator_array_length_ptr), elements)\n }\n } else {\n // Otherwise, increase the number of elements by one.\n assembly {\n elements := add(\n mload(add(accumulator, Accumulator_array_length_ptr)),\n 1\n )\n mstore(add(accumulator, Accumulator_array_length_ptr), elements)\n }\n }\n\n // Insert the item.\n assembly {\n let itemPointer := sub(\n add(accumulator, mul(elements, Conduit_transferItem_size)),\n Accumulator_itemSizeOffsetDifference\n )\n mstore(itemPointer, itemType)\n mstore(add(itemPointer, Conduit_transferItem_token_ptr), token)\n mstore(add(itemPointer, Conduit_transferItem_from_ptr), from)\n mstore(add(itemPointer, Conduit_transferItem_to_ptr), to)\n mstore(\n add(itemPointer, Conduit_transferItem_identifier_ptr),\n identifier\n )\n mstore(add(itemPointer, Conduit_transferItem_amount_ptr), amount)\n }\n }\n}\n" - }, - "seaport/contracts/lib/ConsiderationEnums.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// prettier-ignore\nenum OrderType {\n // 0: no partial fills, anyone can execute\n FULL_OPEN,\n\n // 1: partial fills supported, anyone can execute\n PARTIAL_OPEN,\n\n // 2: no partial fills, only offerer or zone can execute\n FULL_RESTRICTED,\n\n // 3: partial fills supported, only offerer or zone can execute\n PARTIAL_RESTRICTED\n}\n\n// prettier-ignore\nenum BasicOrderType {\n // 0: no partial fills, anyone can execute\n ETH_TO_ERC721_FULL_OPEN,\n\n // 1: partial fills supported, anyone can execute\n ETH_TO_ERC721_PARTIAL_OPEN,\n\n // 2: no partial fills, only offerer or zone can execute\n ETH_TO_ERC721_FULL_RESTRICTED,\n\n // 3: partial fills supported, only offerer or zone can execute\n ETH_TO_ERC721_PARTIAL_RESTRICTED,\n\n // 4: no partial fills, anyone can execute\n ETH_TO_ERC1155_FULL_OPEN,\n\n // 5: partial fills supported, anyone can execute\n ETH_TO_ERC1155_PARTIAL_OPEN,\n\n // 6: no partial fills, only offerer or zone can execute\n ETH_TO_ERC1155_FULL_RESTRICTED,\n\n // 7: partial fills supported, only offerer or zone can execute\n ETH_TO_ERC1155_PARTIAL_RESTRICTED,\n\n // 8: no partial fills, anyone can execute\n ERC20_TO_ERC721_FULL_OPEN,\n\n // 9: partial fills supported, anyone can execute\n ERC20_TO_ERC721_PARTIAL_OPEN,\n\n // 10: no partial fills, only offerer or zone can execute\n ERC20_TO_ERC721_FULL_RESTRICTED,\n\n // 11: partial fills supported, only offerer or zone can execute\n ERC20_TO_ERC721_PARTIAL_RESTRICTED,\n\n // 12: no partial fills, anyone can execute\n ERC20_TO_ERC1155_FULL_OPEN,\n\n // 13: partial fills supported, anyone can execute\n ERC20_TO_ERC1155_PARTIAL_OPEN,\n\n // 14: no partial fills, only offerer or zone can execute\n ERC20_TO_ERC1155_FULL_RESTRICTED,\n\n // 15: partial fills supported, only offerer or zone can execute\n ERC20_TO_ERC1155_PARTIAL_RESTRICTED,\n\n // 16: no partial fills, anyone can execute\n ERC721_TO_ERC20_FULL_OPEN,\n\n // 17: partial fills supported, anyone can execute\n ERC721_TO_ERC20_PARTIAL_OPEN,\n\n // 18: no partial fills, only offerer or zone can execute\n ERC721_TO_ERC20_FULL_RESTRICTED,\n\n // 19: partial fills supported, only offerer or zone can execute\n ERC721_TO_ERC20_PARTIAL_RESTRICTED,\n\n // 20: no partial fills, anyone can execute\n ERC1155_TO_ERC20_FULL_OPEN,\n\n // 21: partial fills supported, anyone can execute\n ERC1155_TO_ERC20_PARTIAL_OPEN,\n\n // 22: no partial fills, only offerer or zone can execute\n ERC1155_TO_ERC20_FULL_RESTRICTED,\n\n // 23: partial fills supported, only offerer or zone can execute\n ERC1155_TO_ERC20_PARTIAL_RESTRICTED\n}\n\n// prettier-ignore\nenum BasicOrderRouteType {\n // 0: provide Ether (or other native token) to receive offered ERC721 item.\n ETH_TO_ERC721,\n\n // 1: provide Ether (or other native token) to receive offered ERC1155 item.\n ETH_TO_ERC1155,\n\n // 2: provide ERC20 item to receive offered ERC721 item.\n ERC20_TO_ERC721,\n\n // 3: provide ERC20 item to receive offered ERC1155 item.\n ERC20_TO_ERC1155,\n\n // 4: provide ERC721 item to receive offered ERC20 item.\n ERC721_TO_ERC20,\n\n // 5: provide ERC1155 item to receive offered ERC20 item.\n ERC1155_TO_ERC20\n}\n\n// prettier-ignore\nenum ItemType {\n // 0: ETH on mainnet, MATIC on polygon, etc.\n NATIVE,\n\n // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work)\n ERC20,\n\n // 2: ERC721 items\n ERC721,\n\n // 3: ERC1155 items\n ERC1155,\n\n // 4: ERC721 items where a number of tokenIds are supported\n ERC721_WITH_CRITERIA,\n\n // 5: ERC1155 items where a number of ids are supported\n ERC1155_WITH_CRITERIA\n}\n\n// prettier-ignore\nenum Side {\n // 0: Items that can be spent\n OFFER,\n\n // 1: Items that must be received\n CONSIDERATION\n}\n" - }, - "seaport/contracts/lib/ConsiderationStructs.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// prettier-ignore\nimport {\n OrderType,\n BasicOrderType,\n ItemType,\n Side\n} from \"./ConsiderationEnums.sol\";\n\n/**\n * @dev An order contains eleven components: an offerer, a zone (or account that\n * can cancel the order or restrict who can fulfill the order depending on\n * the type), the order type (specifying partial fill support as well as\n * restricted order status), the start and end time, a hash that will be\n * provided to the zone when validating restricted orders, a salt, a key\n * corresponding to a given conduit, a counter, and an arbitrary number of\n * offer items that can be spent along with consideration items that must\n * be received by their respective recipient.\n */\nstruct OrderComponents {\n address offerer;\n address zone;\n OfferItem[] offer;\n ConsiderationItem[] consideration;\n OrderType orderType;\n uint256 startTime;\n uint256 endTime;\n bytes32 zoneHash;\n uint256 salt;\n bytes32 conduitKey;\n uint256 counter;\n}\n\n/**\n * @dev An offer item has five components: an item type (ETH or other native\n * tokens, ERC20, ERC721, and ERC1155, as well as criteria-based ERC721 and\n * ERC1155), a token address, a dual-purpose \"identifierOrCriteria\"\n * component that will either represent a tokenId or a merkle root\n * depending on the item type, and a start and end amount that support\n * increasing or decreasing amounts over the duration of the respective\n * order.\n */\nstruct OfferItem {\n ItemType itemType;\n address token;\n uint256 identifierOrCriteria;\n uint256 startAmount;\n uint256 endAmount;\n}\n\n/**\n * @dev A consideration item has the same five components as an offer item and\n * an additional sixth component designating the required recipient of the\n * item.\n */\nstruct ConsiderationItem {\n ItemType itemType;\n address token;\n uint256 identifierOrCriteria;\n uint256 startAmount;\n uint256 endAmount;\n address payable recipient;\n}\n\n/**\n * @dev A spent item is translated from a utilized offer item and has four\n * components: an item type (ETH or other native tokens, ERC20, ERC721, and\n * ERC1155), a token address, a tokenId, and an amount.\n */\nstruct SpentItem {\n ItemType itemType;\n address token;\n uint256 identifier;\n uint256 amount;\n}\n\n/**\n * @dev A received item is translated from a utilized consideration item and has\n * the same four components as a spent item, as well as an additional fifth\n * component designating the required recipient of the item.\n */\nstruct ReceivedItem {\n ItemType itemType;\n address token;\n uint256 identifier;\n uint256 amount;\n address payable recipient;\n}\n\n/**\n * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155\n * matching, a group of six functions may be called that only requires a\n * subset of the usual order arguments. Note the use of a \"basicOrderType\"\n * enum; this represents both the usual order type as well as the \"route\"\n * of the basic order (a simple derivation function for the basic order\n * type is `basicOrderType = orderType + (4 * basicOrderRoute)`.)\n */\nstruct BasicOrderParameters {\n // calldata offset\n address considerationToken; // 0x24\n uint256 considerationIdentifier; // 0x44\n uint256 considerationAmount; // 0x64\n address payable offerer; // 0x84\n address zone; // 0xa4\n address offerToken; // 0xc4\n uint256 offerIdentifier; // 0xe4\n uint256 offerAmount; // 0x104\n BasicOrderType basicOrderType; // 0x124\n uint256 startTime; // 0x144\n uint256 endTime; // 0x164\n bytes32 zoneHash; // 0x184\n uint256 salt; // 0x1a4\n bytes32 offererConduitKey; // 0x1c4\n bytes32 fulfillerConduitKey; // 0x1e4\n uint256 totalOriginalAdditionalRecipients; // 0x204\n AdditionalRecipient[] additionalRecipients; // 0x224\n bytes signature; // 0x244\n // Total length, excluding dynamic array data: 0x264 (580)\n}\n\n/**\n * @dev Basic orders can supply any number of additional recipients, with the\n * implied assumption that they are supplied from the offered ETH (or other\n * native token) or ERC20 token for the order.\n */\nstruct AdditionalRecipient {\n uint256 amount;\n address payable recipient;\n}\n\n/**\n * @dev The full set of order components, with the exception of the counter,\n * must be supplied when fulfilling more sophisticated orders or groups of\n * orders. The total number of original consideration items must also be\n * supplied, as the caller may specify additional consideration items.\n */\nstruct OrderParameters {\n address offerer; // 0x00\n address zone; // 0x20\n OfferItem[] offer; // 0x40\n ConsiderationItem[] consideration; // 0x60\n OrderType orderType; // 0x80\n uint256 startTime; // 0xa0\n uint256 endTime; // 0xc0\n bytes32 zoneHash; // 0xe0\n uint256 salt; // 0x100\n bytes32 conduitKey; // 0x120\n uint256 totalOriginalConsiderationItems; // 0x140\n // offer.length // 0x160\n}\n\n/**\n * @dev Orders require a signature in addition to the other order parameters.\n */\nstruct Order {\n OrderParameters parameters;\n bytes signature;\n}\n\n/**\n * @dev Advanced orders include a numerator (i.e. a fraction to attempt to fill)\n * and a denominator (the total size of the order) in addition to the\n * signature and other order parameters. It also supports an optional field\n * for supplying extra data; this data will be included in a staticcall to\n * `isValidOrderIncludingExtraData` on the zone for the order if the order\n * type is restricted and the offerer or zone are not the caller.\n */\nstruct AdvancedOrder {\n OrderParameters parameters;\n uint120 numerator;\n uint120 denominator;\n bytes signature;\n bytes extraData;\n}\n\n/**\n * @dev Orders can be validated (either explicitly via `validate`, or as a\n * consequence of a full or partial fill), specifically cancelled (they can\n * also be cancelled in bulk via incrementing a per-zone counter), and\n * partially or fully filled (with the fraction filled represented by a\n * numerator and denominator).\n */\nstruct OrderStatus {\n bool isValidated;\n bool isCancelled;\n uint120 numerator;\n uint120 denominator;\n}\n\n/**\n * @dev A criteria resolver specifies an order, side (offer vs. consideration),\n * and item index. It then provides a chosen identifier (i.e. tokenId)\n * alongside a merkle proof demonstrating the identifier meets the required\n * criteria.\n */\nstruct CriteriaResolver {\n uint256 orderIndex;\n Side side;\n uint256 index;\n uint256 identifier;\n bytes32[] criteriaProof;\n}\n\n/**\n * @dev A fulfillment is applied to a group of orders. It decrements a series of\n * offer and consideration items, then generates a single execution\n * element. A given fulfillment can be applied to as many offer and\n * consideration items as desired, but must contain at least one offer and\n * at least one consideration that match. The fulfillment must also remain\n * consistent on all key parameters across all offer items (same offerer,\n * token, type, tokenId, and conduit preference) as well as across all\n * consideration items (token, type, tokenId, and recipient).\n */\nstruct Fulfillment {\n FulfillmentComponent[] offerComponents;\n FulfillmentComponent[] considerationComponents;\n}\n\n/**\n * @dev Each fulfillment component contains one index referencing a specific\n * order and another referencing a specific offer or consideration item.\n */\nstruct FulfillmentComponent {\n uint256 orderIndex;\n uint256 itemIndex;\n}\n\n/**\n * @dev An execution is triggered once all consideration items have been zeroed\n * out. It sends the item in question from the offerer to the item's\n * recipient, optionally sourcing approvals from either this contract\n * directly or from the offerer's chosen conduit if one is specified. An\n * execution is not provided as an argument, but rather is derived via\n * orders, criteria resolvers, and fulfillments (where the total number of\n * executions will be less than or equal to the total number of indicated\n * fulfillments) and returned as part of `matchOrders`.\n */\nstruct Execution {\n ReceivedItem item;\n address offerer;\n bytes32 conduitKey;\n}\n" - }, - "seaport/contracts/lib/Verifiers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { OrderStatus } from \"./ConsiderationStructs.sol\";\n\nimport { Assertions } from \"./Assertions.sol\";\n\nimport { SignatureVerification } from \"./SignatureVerification.sol\";\n\n/**\n * @title Verifiers\n * @author 0age\n * @notice Verifiers contains functions for performing verifications.\n */\ncontract Verifiers is Assertions, SignatureVerification {\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) Assertions(conduitController) {}\n\n /**\n * @dev Internal view function to ensure that the current time falls within\n * an order's valid timespan.\n *\n * @param startTime The time at which the order becomes active.\n * @param endTime The time at which the order becomes inactive.\n * @param revertOnInvalid A boolean indicating whether to revert if the\n * order is not active.\n *\n * @return valid A boolean indicating whether the order is active.\n */\n function _verifyTime(\n uint256 startTime,\n uint256 endTime,\n bool revertOnInvalid\n ) internal view returns (bool valid) {\n // Revert if order's timespan hasn't started yet or has already ended.\n if (startTime > block.timestamp || endTime <= block.timestamp) {\n // Only revert if revertOnInvalid has been supplied as true.\n if (revertOnInvalid) {\n revert InvalidTime();\n }\n\n // Return false as the order is invalid.\n return false;\n }\n\n // Return true as the order time is valid.\n valid = true;\n }\n\n /**\n * @dev Internal view function to verify the signature of an order. An\n * ERC-1271 fallback will be attempted if either the signature length\n * is not 32 or 33 bytes or if the recovered signer does not match the\n * supplied offerer. Note that in cases where a 32 or 33 byte signature\n * is supplied, only standard ECDSA signatures that recover to a\n * non-zero address are supported.\n *\n * @param offerer The offerer for the order.\n * @param orderHash The order hash.\n * @param signature A signature from the offerer indicating that the order\n * has been approved.\n */\n function _verifySignature(\n address offerer,\n bytes32 orderHash,\n bytes memory signature\n ) internal view {\n // Skip signature verification if the offerer is the caller.\n if (offerer == msg.sender) {\n return;\n }\n\n // Derive EIP-712 digest using the domain separator and the order hash.\n bytes32 digest = _deriveEIP712Digest(_domainSeparator(), orderHash);\n\n // Ensure that the signature for the digest is valid for the offerer.\n _assertValidSignature(offerer, digest, signature);\n }\n\n /**\n * @dev Internal view function to validate that a given order is fillable\n * and not cancelled based on the order status.\n *\n * @param orderHash The order hash.\n * @param orderStatus The status of the order, including whether it has\n * been cancelled and the fraction filled.\n * @param onlyAllowUnused A boolean flag indicating whether partial fills\n * are supported by the calling function.\n * @param revertOnInvalid A boolean indicating whether to revert if the\n * order has been cancelled or filled beyond the\n * allowable amount.\n *\n * @return valid A boolean indicating whether the order is valid.\n */\n function _verifyOrderStatus(\n bytes32 orderHash,\n OrderStatus storage orderStatus,\n bool onlyAllowUnused,\n bool revertOnInvalid\n ) internal view returns (bool valid) {\n // Ensure that the order has not been cancelled.\n if (orderStatus.isCancelled) {\n // Only revert if revertOnInvalid has been supplied as true.\n if (revertOnInvalid) {\n revert OrderIsCancelled(orderHash);\n }\n\n // Return false as the order status is invalid.\n return false;\n }\n\n // Read order status numerator from storage and place on stack.\n uint256 orderStatusNumerator = orderStatus.numerator;\n\n // If the order is not entirely unused...\n if (orderStatusNumerator != 0) {\n // ensure the order has not been partially filled when not allowed.\n if (onlyAllowUnused) {\n // Always revert on partial fills when onlyAllowUnused is true.\n revert OrderPartiallyFilled(orderHash);\n }\n // Otherwise, ensure that order has not been entirely filled.\n else if (orderStatusNumerator >= orderStatus.denominator) {\n // Only revert if revertOnInvalid has been supplied as true.\n if (revertOnInvalid) {\n revert OrderAlreadyFilled(orderHash);\n }\n\n // Return false as the order status is invalid.\n return false;\n }\n }\n\n // Return true as the order status is valid.\n valid = true;\n }\n}\n" - }, - "seaport/contracts/lib/ConsiderationConstants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/*\n * -------------------------- Disambiguation & Other Notes ---------------------\n * - The term \"head\" is used as it is in the documentation for ABI encoding,\n * but only in reference to dynamic types, i.e. it always refers to the\n * offset or pointer to the body of a dynamic type. In calldata, the head\n * is always an offset (relative to the parent object), while in memory,\n * the head is always the pointer to the body. More information found here:\n * https://docs.soliditylang.org/en/v0.8.14/abi-spec.html#argument-encoding\n * - Note that the length of an array is separate from and precedes the\n * head of the array.\n *\n * - The term \"body\" is used in place of the term \"head\" used in the ABI\n * documentation. It refers to the start of the data for a dynamic type,\n * e.g. the first word of a struct or the first word of the first element\n * in an array.\n *\n * - The term \"pointer\" is used to describe the absolute position of a value\n * and never an offset relative to another value.\n * - The suffix \"_ptr\" refers to a memory pointer.\n * - The suffix \"_cdPtr\" refers to a calldata pointer.\n *\n * - The term \"offset\" is used to describe the position of a value relative\n * to some parent value. For example, OrderParameters_conduit_offset is the\n * offset to the \"conduit\" value in the OrderParameters struct relative to\n * the start of the body.\n * - Note: Offsets are used to derive pointers.\n *\n * - Some structs have pointers defined for all of their fields in this file.\n * Lines which are commented out are fields that are not used in the\n * codebase but have been left in for readability.\n */\n\n// Declare constants for name, version, and reentrancy sentinel values.\n\n// Name is right padded, so it touches the length which is left padded. This\n// enables writing both values at once. Length goes at byte 95 in memory, and\n// name fills bytes 96-109, so both values can be written left-padded to 77.\nuint256 constant NameLengthPtr = 77;\nuint256 constant NameWithLength = 0x0d436F6E73696465726174696F6E;\n\nuint256 constant Version = 0x312e31;\nuint256 constant Version_length = 3;\nuint256 constant Version_shift = 0xe8;\n\nuint256 constant _NOT_ENTERED = 1;\nuint256 constant _ENTERED = 2;\n\n// Common Offsets\n// Offsets for identically positioned fields shared by:\n// OfferItem, ConsiderationItem, SpentItem, ReceivedItem\n\nuint256 constant Common_token_offset = 0x20;\nuint256 constant Common_identifier_offset = 0x40;\nuint256 constant Common_amount_offset = 0x60;\n\nuint256 constant ReceivedItem_size = 0xa0;\nuint256 constant ReceivedItem_amount_offset = 0x60;\nuint256 constant ReceivedItem_recipient_offset = 0x80;\n\nuint256 constant ReceivedItem_CommonParams_size = 0x60;\n\nuint256 constant ConsiderationItem_recipient_offset = 0xa0;\n// Store the same constant in an abbreviated format for a line length fix.\nuint256 constant ConsiderItem_recipient_offset = 0xa0;\n\nuint256 constant Execution_offerer_offset = 0x20;\nuint256 constant Execution_conduit_offset = 0x40;\n\nuint256 constant InvalidFulfillmentComponentData_error_signature = (\n 0x7fda727900000000000000000000000000000000000000000000000000000000\n);\nuint256 constant InvalidFulfillmentComponentData_error_len = 0x04;\n\nuint256 constant Panic_error_signature = (\n 0x4e487b7100000000000000000000000000000000000000000000000000000000\n);\nuint256 constant Panic_error_offset = 0x04;\nuint256 constant Panic_error_length = 0x24;\nuint256 constant Panic_arithmetic = 0x11;\n\nuint256 constant MissingItemAmount_error_signature = (\n 0x91b3e51400000000000000000000000000000000000000000000000000000000\n);\nuint256 constant MissingItemAmount_error_len = 0x04;\n\nuint256 constant OrderParameters_offer_head_offset = 0x40;\nuint256 constant OrderParameters_consideration_head_offset = 0x60;\nuint256 constant OrderParameters_conduit_offset = 0x120;\nuint256 constant OrderParameters_counter_offset = 0x140;\n\nuint256 constant Fulfillment_itemIndex_offset = 0x20;\n\nuint256 constant AdvancedOrder_numerator_offset = 0x20;\n\nuint256 constant AlmostOneWord = 0x1f;\nuint256 constant OneWord = 0x20;\nuint256 constant TwoWords = 0x40;\nuint256 constant ThreeWords = 0x60;\nuint256 constant FourWords = 0x80;\nuint256 constant FiveWords = 0xa0;\n\nuint256 constant FreeMemoryPointerSlot = 0x40;\nuint256 constant ZeroSlot = 0x60;\nuint256 constant DefaultFreeMemoryPointer = 0x80;\n\nuint256 constant Slot0x80 = 0x80;\nuint256 constant Slot0xA0 = 0xa0;\n\nuint256 constant BasicOrder_endAmount_cdPtr = 0x104;\nuint256 constant BasicOrder_common_params_size = 0xa0;\nuint256 constant BasicOrder_considerationHashesArray_ptr = 0x160;\n\nuint256 constant EIP712_Order_size = 0x180;\nuint256 constant EIP712_OfferItem_size = 0xc0;\nuint256 constant EIP712_ConsiderationItem_size = 0xe0;\nuint256 constant AdditionalRecipients_size = 0x40;\n\nuint256 constant EIP712_DomainSeparator_offset = 0x02;\nuint256 constant EIP712_OrderHash_offset = 0x22;\nuint256 constant EIP712_DigestPayload_size = 0x42;\n\nuint256 constant receivedItemsHash_ptr = 0x60;\n\n/*\n * Memory layout in _prepareBasicFulfillmentFromCalldata of\n * data for OrderFulfilled\n *\n * event OrderFulfilled(\n * bytes32 orderHash,\n * address indexed offerer,\n * address indexed zone,\n * address fulfiller,\n * SpentItem[] offer,\n * > (itemType, token, id, amount)\n * ReceivedItem[] consideration\n * > (itemType, token, id, amount, recipient)\n * )\n *\n * - 0x00: orderHash\n * - 0x20: fulfiller\n * - 0x40: offer offset (0x80)\n * - 0x60: consideration offset (0x120)\n * - 0x80: offer.length (1)\n * - 0xa0: offerItemType\n * - 0xc0: offerToken\n * - 0xe0: offerIdentifier\n * - 0x100: offerAmount\n * - 0x120: consideration.length (1 + additionalRecipients.length)\n * - 0x140: considerationItemType\n * - 0x160: considerationToken\n * - 0x180: considerationIdentifier\n * - 0x1a0: considerationAmount\n * - 0x1c0: considerationRecipient\n * - ...\n */\n\n// Minimum length of the OrderFulfilled event data.\n// Must be added to the size of the ReceivedItem array for additionalRecipients\n// (0xa0 * additionalRecipients.length) to calculate full size of the buffer.\nuint256 constant OrderFulfilled_baseSize = 0x1e0;\nuint256 constant OrderFulfilled_selector = (\n 0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31\n);\n\n// Minimum offset in memory to OrderFulfilled event data.\n// Must be added to the size of the EIP712 hash array for additionalRecipients\n// (32 * additionalRecipients.length) to calculate the pointer to event data.\nuint256 constant OrderFulfilled_baseOffset = 0x180;\nuint256 constant OrderFulfilled_consideration_length_baseOffset = 0x2a0;\nuint256 constant OrderFulfilled_offer_length_baseOffset = 0x200;\n\n// uint256 constant OrderFulfilled_orderHash_offset = 0x00;\nuint256 constant OrderFulfilled_fulfiller_offset = 0x20;\nuint256 constant OrderFulfilled_offer_head_offset = 0x40;\nuint256 constant OrderFulfilled_offer_body_offset = 0x80;\nuint256 constant OrderFulfilled_consideration_head_offset = 0x60;\nuint256 constant OrderFulfilled_consideration_body_offset = 0x120;\n\n// BasicOrderParameters\nuint256 constant BasicOrder_parameters_cdPtr = 0x04;\nuint256 constant BasicOrder_considerationToken_cdPtr = 0x24;\n// uint256 constant BasicOrder_considerationIdentifier_cdPtr = 0x44;\nuint256 constant BasicOrder_considerationAmount_cdPtr = 0x64;\nuint256 constant BasicOrder_offerer_cdPtr = 0x84;\nuint256 constant BasicOrder_zone_cdPtr = 0xa4;\nuint256 constant BasicOrder_offerToken_cdPtr = 0xc4;\n// uint256 constant BasicOrder_offerIdentifier_cdPtr = 0xe4;\nuint256 constant BasicOrder_offerAmount_cdPtr = 0x104;\nuint256 constant BasicOrder_basicOrderType_cdPtr = 0x124;\nuint256 constant BasicOrder_startTime_cdPtr = 0x144;\n// uint256 constant BasicOrder_endTime_cdPtr = 0x164;\n// uint256 constant BasicOrder_zoneHash_cdPtr = 0x184;\n// uint256 constant BasicOrder_salt_cdPtr = 0x1a4;\nuint256 constant BasicOrder_offererConduit_cdPtr = 0x1c4;\nuint256 constant BasicOrder_fulfillerConduit_cdPtr = 0x1e4;\nuint256 constant BasicOrder_totalOriginalAdditionalRecipients_cdPtr = 0x204;\nuint256 constant BasicOrder_additionalRecipients_head_cdPtr = 0x224;\nuint256 constant BasicOrder_signature_cdPtr = 0x244;\nuint256 constant BasicOrder_additionalRecipients_length_cdPtr = 0x264;\nuint256 constant BasicOrder_additionalRecipients_data_cdPtr = 0x284;\n\nuint256 constant BasicOrder_parameters_ptr = 0x20;\n\nuint256 constant BasicOrder_basicOrderType_range = 0x18; // 24 values\n\n/*\n * Memory layout in _prepareBasicFulfillmentFromCalldata of\n * EIP712 data for ConsiderationItem\n * - 0x80: ConsiderationItem EIP-712 typehash (constant)\n * - 0xa0: itemType\n * - 0xc0: token\n * - 0xe0: identifier\n * - 0x100: startAmount\n * - 0x120: endAmount\n * - 0x140: recipient\n */\nuint256 constant BasicOrder_considerationItem_typeHash_ptr = 0x80; // memoryPtr\nuint256 constant BasicOrder_considerationItem_itemType_ptr = 0xa0;\nuint256 constant BasicOrder_considerationItem_token_ptr = 0xc0;\nuint256 constant BasicOrder_considerationItem_identifier_ptr = 0xe0;\nuint256 constant BasicOrder_considerationItem_startAmount_ptr = 0x100;\nuint256 constant BasicOrder_considerationItem_endAmount_ptr = 0x120;\n// uint256 constant BasicOrder_considerationItem_recipient_ptr = 0x140;\n\n/*\n * Memory layout in _prepareBasicFulfillmentFromCalldata of\n * EIP712 data for OfferItem\n * - 0x80: OfferItem EIP-712 typehash (constant)\n * - 0xa0: itemType\n * - 0xc0: token\n * - 0xe0: identifier (reused for offeredItemsHash)\n * - 0x100: startAmount\n * - 0x120: endAmount\n */\nuint256 constant BasicOrder_offerItem_typeHash_ptr = DefaultFreeMemoryPointer;\nuint256 constant BasicOrder_offerItem_itemType_ptr = 0xa0;\nuint256 constant BasicOrder_offerItem_token_ptr = 0xc0;\n// uint256 constant BasicOrder_offerItem_identifier_ptr = 0xe0;\n// uint256 constant BasicOrder_offerItem_startAmount_ptr = 0x100;\nuint256 constant BasicOrder_offerItem_endAmount_ptr = 0x120;\n\n/*\n * Memory layout in _prepareBasicFulfillmentFromCalldata of\n * EIP712 data for Order\n * - 0x80: Order EIP-712 typehash (constant)\n * - 0xa0: orderParameters.offerer\n * - 0xc0: orderParameters.zone\n * - 0xe0: keccak256(abi.encodePacked(offerHashes))\n * - 0x100: keccak256(abi.encodePacked(considerationHashes))\n * - 0x120: orderType\n * - 0x140: startTime\n * - 0x160: endTime\n * - 0x180: zoneHash\n * - 0x1a0: salt\n * - 0x1c0: conduit\n * - 0x1e0: _counters[orderParameters.offerer] (from storage)\n */\nuint256 constant BasicOrder_order_typeHash_ptr = 0x80;\nuint256 constant BasicOrder_order_offerer_ptr = 0xa0;\n// uint256 constant BasicOrder_order_zone_ptr = 0xc0;\nuint256 constant BasicOrder_order_offerHashes_ptr = 0xe0;\nuint256 constant BasicOrder_order_considerationHashes_ptr = 0x100;\nuint256 constant BasicOrder_order_orderType_ptr = 0x120;\nuint256 constant BasicOrder_order_startTime_ptr = 0x140;\n// uint256 constant BasicOrder_order_endTime_ptr = 0x160;\n// uint256 constant BasicOrder_order_zoneHash_ptr = 0x180;\n// uint256 constant BasicOrder_order_salt_ptr = 0x1a0;\n// uint256 constant BasicOrder_order_conduitKey_ptr = 0x1c0;\nuint256 constant BasicOrder_order_counter_ptr = 0x1e0;\nuint256 constant BasicOrder_additionalRecipients_head_ptr = 0x240;\nuint256 constant BasicOrder_signature_ptr = 0x260;\n\n// Signature-related\nbytes32 constant EIP2098_allButHighestBitMask = (\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n);\nbytes32 constant ECDSA_twentySeventhAndTwentyEighthBytesSet = (\n 0x0000000000000000000000000000000000000000000000000000000101000000\n);\nuint256 constant ECDSA_MaxLength = 65;\nuint256 constant ECDSA_signature_s_offset = 0x40;\nuint256 constant ECDSA_signature_v_offset = 0x60;\n\nbytes32 constant EIP1271_isValidSignature_selector = (\n 0x1626ba7e00000000000000000000000000000000000000000000000000000000\n);\nuint256 constant EIP1271_isValidSignature_signatureHead_negativeOffset = 0x20;\nuint256 constant EIP1271_isValidSignature_digest_negativeOffset = 0x40;\nuint256 constant EIP1271_isValidSignature_selector_negativeOffset = 0x44;\nuint256 constant EIP1271_isValidSignature_calldata_baseLength = 0x64;\n\nuint256 constant EIP1271_isValidSignature_signature_head_offset = 0x40;\n\n// abi.encodeWithSignature(\"NoContract(address)\")\nuint256 constant NoContract_error_signature = (\n 0x5f15d67200000000000000000000000000000000000000000000000000000000\n);\nuint256 constant NoContract_error_sig_ptr = 0x0;\nuint256 constant NoContract_error_token_ptr = 0x4;\nuint256 constant NoContract_error_length = 0x24; // 4 + 32 == 36\n\nuint256 constant EIP_712_PREFIX = (\n 0x1901000000000000000000000000000000000000000000000000000000000000\n);\n\nuint256 constant ExtraGasBuffer = 0x20;\nuint256 constant CostPerWord = 3;\nuint256 constant MemoryExpansionCoefficient = 0x200; // 512\n\nuint256 constant Create2AddressDerivation_ptr = 0x0b;\nuint256 constant Create2AddressDerivation_length = 0x55;\n\nuint256 constant MaskOverByteTwelve = (\n 0x0000000000000000000000ff0000000000000000000000000000000000000000\n);\n\nuint256 constant MaskOverLastTwentyBytes = (\n 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff\n);\n\nuint256 constant MaskOverFirstFourBytes = (\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n);\n\nuint256 constant Conduit_execute_signature = (\n 0x4ce34aa200000000000000000000000000000000000000000000000000000000\n);\n\nuint256 constant MaxUint8 = 0xff;\nuint256 constant MaxUint120 = 0xffffffffffffffffffffffffffffff;\n\nuint256 constant Conduit_execute_ConduitTransfer_ptr = 0x20;\nuint256 constant Conduit_execute_ConduitTransfer_length = 0x01;\n\nuint256 constant Conduit_execute_ConduitTransfer_offset_ptr = 0x04;\nuint256 constant Conduit_execute_ConduitTransfer_length_ptr = 0x24;\nuint256 constant Conduit_execute_transferItemType_ptr = 0x44;\nuint256 constant Conduit_execute_transferToken_ptr = 0x64;\nuint256 constant Conduit_execute_transferFrom_ptr = 0x84;\nuint256 constant Conduit_execute_transferTo_ptr = 0xa4;\nuint256 constant Conduit_execute_transferIdentifier_ptr = 0xc4;\nuint256 constant Conduit_execute_transferAmount_ptr = 0xe4;\n\nuint256 constant OneConduitExecute_size = 0x104;\n\n// Sentinel value to indicate that the conduit accumulator is not armed.\nuint256 constant AccumulatorDisarmed = 0x20;\nuint256 constant AccumulatorArmed = 0x40;\nuint256 constant Accumulator_conduitKey_ptr = 0x20;\nuint256 constant Accumulator_selector_ptr = 0x40;\nuint256 constant Accumulator_array_offset_ptr = 0x44;\nuint256 constant Accumulator_array_length_ptr = 0x64;\n\nuint256 constant Accumulator_itemSizeOffsetDifference = 0x3c;\n\nuint256 constant Accumulator_array_offset = 0x20;\nuint256 constant Conduit_transferItem_size = 0xc0;\nuint256 constant Conduit_transferItem_token_ptr = 0x20;\nuint256 constant Conduit_transferItem_from_ptr = 0x40;\nuint256 constant Conduit_transferItem_to_ptr = 0x60;\nuint256 constant Conduit_transferItem_identifier_ptr = 0x80;\nuint256 constant Conduit_transferItem_amount_ptr = 0xa0;\n\n// Declare constant for errors related to amount derivation.\n// error InexactFraction() @ AmountDerivationErrors.sol\nuint256 constant InexactFraction_error_signature = (\n 0xc63cf08900000000000000000000000000000000000000000000000000000000\n);\nuint256 constant InexactFraction_error_len = 0x04;\n\n// Declare constant for errors related to signature verification.\nuint256 constant Ecrecover_precompile = 1;\nuint256 constant Ecrecover_args_size = 0x80;\nuint256 constant Signature_lower_v = 27;\n\n// error BadSignatureV(uint8) @ SignatureVerificationErrors.sol\nuint256 constant BadSignatureV_error_signature = (\n 0x1f003d0a00000000000000000000000000000000000000000000000000000000\n);\nuint256 constant BadSignatureV_error_offset = 0x04;\nuint256 constant BadSignatureV_error_length = 0x24;\n\n// error InvalidSigner() @ SignatureVerificationErrors.sol\nuint256 constant InvalidSigner_error_signature = (\n 0x815e1d6400000000000000000000000000000000000000000000000000000000\n);\nuint256 constant InvalidSigner_error_length = 0x04;\n\n// error InvalidSignature() @ SignatureVerificationErrors.sol\nuint256 constant InvalidSignature_error_signature = (\n 0x8baa579f00000000000000000000000000000000000000000000000000000000\n);\nuint256 constant InvalidSignature_error_length = 0x04;\n\n// error BadContractSignature() @ SignatureVerificationErrors.sol\nuint256 constant BadContractSignature_error_signature = (\n 0x4f7fb80d00000000000000000000000000000000000000000000000000000000\n);\nuint256 constant BadContractSignature_error_length = 0x04;\n\nuint256 constant NumBitsAfterSelector = 0xe0;\n\n// 69 is the lowest modulus for which the remainder\n// of every selector other than the two match functions\n// is greater than those of the match functions.\nuint256 constant NonMatchSelector_MagicModulus = 69;\n// Of the two match function selectors, the highest\n// remainder modulo 69 is 29.\nuint256 constant NonMatchSelector_MagicRemainder = 0x1d;\n" - }, - "seaport/contracts/lib/Assertions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { OrderParameters } from \"./ConsiderationStructs.sol\";\n\nimport { GettersAndDerivers } from \"./GettersAndDerivers.sol\";\n\n// prettier-ignore\nimport {\n TokenTransferrerErrors\n} from \"../interfaces/TokenTransferrerErrors.sol\";\n\nimport { CounterManager } from \"./CounterManager.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title Assertions\n * @author 0age\n * @notice Assertions contains logic for making various assertions that do not\n * fit neatly within a dedicated semantic scope.\n */\ncontract Assertions is\n GettersAndDerivers,\n CounterManager,\n TokenTransferrerErrors\n{\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController)\n GettersAndDerivers(conduitController)\n {}\n\n /**\n * @dev Internal view function to ensure that the supplied consideration\n * array length on a given set of order parameters is not less than the\n * original consideration array length for that order and to retrieve\n * the current counter for a given order's offerer and zone and use it\n * to derive the order hash.\n *\n * @param orderParameters The parameters of the order to hash.\n *\n * @return The hash.\n */\n function _assertConsiderationLengthAndGetOrderHash(\n OrderParameters memory orderParameters\n ) internal view returns (bytes32) {\n // Ensure supplied consideration array length is not less than original.\n _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(\n orderParameters.consideration.length,\n orderParameters.totalOriginalConsiderationItems\n );\n\n // Derive and return order hash using current counter for the offerer.\n return\n _deriveOrderHash(\n orderParameters,\n _getCounter(orderParameters.offerer)\n );\n }\n\n /**\n * @dev Internal pure function to ensure that the supplied consideration\n * array length for an order to be fulfilled is not less than the\n * original consideration array length for that order.\n *\n * @param suppliedConsiderationItemTotal The number of consideration items\n * supplied when fulfilling the order.\n * @param originalConsiderationItemTotal The number of consideration items\n * supplied on initial order creation.\n */\n function _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(\n uint256 suppliedConsiderationItemTotal,\n uint256 originalConsiderationItemTotal\n ) internal pure {\n // Ensure supplied consideration array length is not less than original.\n if (suppliedConsiderationItemTotal < originalConsiderationItemTotal) {\n revert MissingOriginalConsiderationItems();\n }\n }\n\n /**\n * @dev Internal pure function to ensure that a given item amount is not\n * zero.\n *\n * @param amount The amount to check.\n */\n function _assertNonZeroAmount(uint256 amount) internal pure {\n // Revert if the supplied amount is equal to zero.\n if (amount == 0) {\n revert MissingItemAmount();\n }\n }\n\n /**\n * @dev Internal pure function to validate calldata offsets for dynamic\n * types in BasicOrderParameters and other parameters. This ensures\n * that functions using the calldata object normally will be using the\n * same data as the assembly functions and that values that are bound\n * to a given range are within that range. Note that no parameters are\n * supplied as all basic order functions use the same calldata\n * encoding.\n */\n function _assertValidBasicOrderParameters() internal pure {\n // Declare a boolean designating basic order parameter offset validity.\n bool validOffsets;\n\n // Utilize assembly in order to read offset data directly from calldata.\n assembly {\n /*\n * Checks:\n * 1. Order parameters struct offset == 0x20\n * 2. Additional recipients arr offset == 0x240\n * 3. Signature offset == 0x260 + (recipients.length * 0x40)\n * 4. BasicOrderType between 0 and 23 (i.e. < 24)\n */\n validOffsets := and(\n // Order parameters at calldata 0x04 must have offset of 0x20.\n eq(\n calldataload(BasicOrder_parameters_cdPtr),\n BasicOrder_parameters_ptr\n ),\n // Additional recipients at cd 0x224 must have offset of 0x240.\n eq(\n calldataload(BasicOrder_additionalRecipients_head_cdPtr),\n BasicOrder_additionalRecipients_head_ptr\n )\n )\n\n validOffsets := and(\n validOffsets,\n eq(\n // Load signature offset from calldata 0x244.\n calldataload(BasicOrder_signature_cdPtr),\n // Derive expected offset as start of recipients + len * 64.\n add(\n BasicOrder_signature_ptr,\n mul(\n // Additional recipients length at calldata 0x264.\n calldataload(\n BasicOrder_additionalRecipients_length_cdPtr\n ),\n // Each additional recipient has a length of 0x40.\n AdditionalRecipients_size\n )\n )\n )\n )\n\n validOffsets := and(\n validOffsets,\n lt(\n // BasicOrderType parameter at calldata offset 0x124.\n calldataload(BasicOrder_basicOrderType_cdPtr),\n // Value should be less than 24.\n BasicOrder_basicOrderType_range\n )\n )\n }\n\n // Revert with an error if basic order parameter offsets are invalid.\n if (!validOffsets) {\n revert InvalidBasicOrderParameterEncoding();\n }\n }\n}\n" - }, - "seaport/contracts/lib/SignatureVerification.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { EIP1271Interface } from \"../interfaces/EIP1271Interface.sol\";\n\n// prettier-ignore\nimport {\n SignatureVerificationErrors\n} from \"../interfaces/SignatureVerificationErrors.sol\";\n\nimport { LowLevelHelpers } from \"./LowLevelHelpers.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title SignatureVerification\n * @author 0age\n * @notice SignatureVerification contains logic for verifying signatures.\n */\ncontract SignatureVerification is SignatureVerificationErrors, LowLevelHelpers {\n /**\n * @dev Internal view function to verify the signature of an order. An\n * ERC-1271 fallback will be attempted if either the signature length\n * is not 64 or 65 bytes or if the recovered signer does not match the\n * supplied signer.\n *\n * @param signer The signer for the order.\n * @param digest The digest to verify the signature against.\n * @param signature A signature from the signer indicating that the order\n * has been approved.\n */\n function _assertValidSignature(\n address signer,\n bytes32 digest,\n bytes memory signature\n ) internal view {\n // Declare value for ecrecover equality or 1271 call success status.\n bool success;\n\n // Utilize assembly to perform optimized signature verification check.\n assembly {\n // Ensure that first word of scratch space is empty.\n mstore(0, 0)\n\n // Declare value for v signature parameter.\n let v\n\n // Get the length of the signature.\n let signatureLength := mload(signature)\n\n // Get the pointer to the value preceding the signature length.\n // This will be used for temporary memory overrides - either the\n // signature head for isValidSignature or the digest for ecrecover.\n let wordBeforeSignaturePtr := sub(signature, OneWord)\n\n // Cache the current value behind the signature to restore it later.\n let cachedWordBeforeSignature := mload(wordBeforeSignaturePtr)\n\n // Declare lenDiff + recoveredSigner scope to manage stack pressure.\n {\n // Take the difference between the max ECDSA signature length\n // and the actual signature length. Overflow desired for any\n // values > 65. If the diff is not 0 or 1, it is not a valid\n // ECDSA signature - move on to EIP1271 check.\n let lenDiff := sub(ECDSA_MaxLength, signatureLength)\n\n // Declare variable for recovered signer.\n let recoveredSigner\n\n // If diff is 0 or 1, it may be an ECDSA signature.\n // Try to recover signer.\n if iszero(gt(lenDiff, 1)) {\n // Read the signature `s` value.\n let originalSignatureS := mload(\n add(signature, ECDSA_signature_s_offset)\n )\n\n // Read the first byte of the word after `s`. If the\n // signature is 65 bytes, this will be the real `v` value.\n // If not, it will need to be modified - doing it this way\n // saves an extra condition.\n v := byte(\n 0,\n mload(add(signature, ECDSA_signature_v_offset))\n )\n\n // If lenDiff is 1, parse 64-byte signature as ECDSA.\n if lenDiff {\n // Extract yParity from highest bit of vs and add 27 to\n // get v.\n v := add(\n shr(MaxUint8, originalSignatureS),\n Signature_lower_v\n )\n\n // Extract canonical s from vs, all but the highest bit.\n // Temporarily overwrite the original `s` value in the\n // signature.\n mstore(\n add(signature, ECDSA_signature_s_offset),\n and(\n originalSignatureS,\n EIP2098_allButHighestBitMask\n )\n )\n }\n // Temporarily overwrite the signature length with `v` to\n // conform to the expected input for ecrecover.\n mstore(signature, v)\n\n // Temporarily overwrite the word before the length with\n // `digest` to conform to the expected input for ecrecover.\n mstore(wordBeforeSignaturePtr, digest)\n\n // Attempt to recover the signer for the given signature. Do\n // not check the call status as ecrecover will return a null\n // address if the signature is invalid.\n pop(\n staticcall(\n gas(),\n Ecrecover_precompile, // Call ecrecover precompile.\n wordBeforeSignaturePtr, // Use data memory location.\n Ecrecover_args_size, // Size of digest, v, r, and s.\n 0, // Write result to scratch space.\n OneWord // Provide size of returned result.\n )\n )\n\n // Restore cached word before signature.\n mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature)\n\n // Restore cached signature length.\n mstore(signature, signatureLength)\n\n // Restore cached signature `s` value.\n mstore(\n add(signature, ECDSA_signature_s_offset),\n originalSignatureS\n )\n\n // Read the recovered signer from the buffer given as return\n // space for ecrecover.\n recoveredSigner := mload(0)\n }\n\n // Set success to true if the signature provided was a valid\n // ECDSA signature and the signer is not the null address. Use\n // gt instead of direct as success is used outside of assembly.\n success := and(eq(signer, recoveredSigner), gt(signer, 0))\n }\n\n // If the signature was not verified with ecrecover, try EIP1271.\n if iszero(success) {\n // Temporarily overwrite the word before the signature length\n // and use it as the head of the signature input to\n // `isValidSignature`, which has a value of 64.\n mstore(\n wordBeforeSignaturePtr,\n EIP1271_isValidSignature_signature_head_offset\n )\n\n // Get pointer to use for the selector of `isValidSignature`.\n let selectorPtr := sub(\n signature,\n EIP1271_isValidSignature_selector_negativeOffset\n )\n\n // Cache the value currently stored at the selector pointer.\n let cachedWordOverwrittenBySelector := mload(selectorPtr)\n\n // Get pointer to use for `digest` input to `isValidSignature`.\n let digestPtr := sub(\n signature,\n EIP1271_isValidSignature_digest_negativeOffset\n )\n\n // Cache the value currently stored at the digest pointer.\n let cachedWordOverwrittenByDigest := mload(digestPtr)\n\n // Write the selector first, since it overlaps the digest.\n mstore(selectorPtr, EIP1271_isValidSignature_selector)\n\n // Next, write the digest.\n mstore(digestPtr, digest)\n\n // Call signer with `isValidSignature` to validate signature.\n success := staticcall(\n gas(),\n signer,\n selectorPtr,\n add(\n signatureLength,\n EIP1271_isValidSignature_calldata_baseLength\n ),\n 0,\n OneWord\n )\n\n // Determine if the signature is valid on successful calls.\n if success {\n // If first word of scratch space does not contain EIP-1271\n // signature selector, revert.\n if iszero(eq(mload(0), EIP1271_isValidSignature_selector)) {\n // Revert with bad 1271 signature if signer has code.\n if extcodesize(signer) {\n // Bad contract signature.\n mstore(0, BadContractSignature_error_signature)\n revert(0, BadContractSignature_error_length)\n }\n\n // Check if signature length was invalid.\n if gt(sub(ECDSA_MaxLength, signatureLength), 1) {\n // Revert with generic invalid signature error.\n mstore(0, InvalidSignature_error_signature)\n revert(0, InvalidSignature_error_length)\n }\n\n // Check if v was invalid.\n if iszero(\n byte(v, ECDSA_twentySeventhAndTwentyEighthBytesSet)\n ) {\n // Revert with invalid v value.\n mstore(0, BadSignatureV_error_signature)\n mstore(BadSignatureV_error_offset, v)\n revert(0, BadSignatureV_error_length)\n }\n\n // Revert with generic invalid signer error message.\n mstore(0, InvalidSigner_error_signature)\n revert(0, InvalidSigner_error_length)\n }\n }\n\n // Restore the cached values overwritten by selector, digest and\n // signature head.\n mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature)\n mstore(selectorPtr, cachedWordOverwrittenBySelector)\n mstore(digestPtr, cachedWordOverwrittenByDigest)\n }\n }\n\n // If the call failed...\n if (!success) {\n // Revert and pass reason along if one was returned.\n _revertWithReasonIfOneIsReturned();\n\n // Otherwise, revert with error indicating bad contract signature.\n assembly {\n mstore(0, BadContractSignature_error_signature)\n revert(0, BadContractSignature_error_length)\n }\n }\n }\n}\n" - }, - "seaport/contracts/lib/GettersAndDerivers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { OrderParameters } from \"./ConsiderationStructs.sol\";\n\nimport { ConsiderationBase } from \"./ConsiderationBase.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title GettersAndDerivers\n * @author 0age\n * @notice ConsiderationInternal contains pure and internal view functions\n * related to getting or deriving various values.\n */\ncontract GettersAndDerivers is ConsiderationBase {\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController)\n ConsiderationBase(conduitController)\n {}\n\n /**\n * @dev Internal view function to derive the order hash for a given order.\n * Note that only the original consideration items are included in the\n * order hash, as additional consideration items may be supplied by the\n * caller.\n *\n * @param orderParameters The parameters of the order to hash.\n * @param counter The counter of the order to hash.\n *\n * @return orderHash The hash.\n */\n function _deriveOrderHash(\n OrderParameters memory orderParameters,\n uint256 counter\n ) internal view returns (bytes32 orderHash) {\n // Get length of original consideration array and place it on the stack.\n uint256 originalConsiderationLength = (\n orderParameters.totalOriginalConsiderationItems\n );\n\n /*\n * Memory layout for an array of structs (dynamic or not) is similar\n * to ABI encoding of dynamic types, with a head segment followed by\n * a data segment. The main difference is that the head of an element\n * is a memory pointer rather than an offset.\n */\n\n // Declare a variable for the derived hash of the offer array.\n bytes32 offerHash;\n\n // Read offer item EIP-712 typehash from runtime code & place on stack.\n bytes32 typeHash = _OFFER_ITEM_TYPEHASH;\n\n // Utilize assembly so that memory regions can be reused across hashes.\n assembly {\n // Retrieve the free memory pointer and place on the stack.\n let hashArrPtr := mload(FreeMemoryPointerSlot)\n\n // Get the pointer to the offers array.\n let offerArrPtr := mload(\n add(orderParameters, OrderParameters_offer_head_offset)\n )\n\n // Load the length.\n let offerLength := mload(offerArrPtr)\n\n // Set the pointer to the first offer's head.\n offerArrPtr := add(offerArrPtr, OneWord)\n\n // Iterate over the offer items.\n // prettier-ignore\n for { let i := 0 } lt(i, offerLength) {\n i := add(i, 1)\n } {\n // Read the pointer to the offer data and subtract one word\n // to get typeHash pointer.\n let ptr := sub(mload(offerArrPtr), OneWord)\n\n // Read the current value before the offer data.\n let value := mload(ptr)\n\n // Write the type hash to the previous word.\n mstore(ptr, typeHash)\n\n // Take the EIP712 hash and store it in the hash array.\n mstore(hashArrPtr, keccak256(ptr, EIP712_OfferItem_size))\n\n // Restore the previous word.\n mstore(ptr, value)\n\n // Increment the array pointers by one word.\n offerArrPtr := add(offerArrPtr, OneWord)\n hashArrPtr := add(hashArrPtr, OneWord)\n }\n\n // Derive the offer hash using the hashes of each item.\n offerHash := keccak256(\n mload(FreeMemoryPointerSlot),\n mul(offerLength, OneWord)\n )\n }\n\n // Declare a variable for the derived hash of the consideration array.\n bytes32 considerationHash;\n\n // Read consideration item typehash from runtime code & place on stack.\n typeHash = _CONSIDERATION_ITEM_TYPEHASH;\n\n // Utilize assembly so that memory regions can be reused across hashes.\n assembly {\n // Retrieve the free memory pointer and place on the stack.\n let hashArrPtr := mload(FreeMemoryPointerSlot)\n\n // Get the pointer to the consideration array.\n let considerationArrPtr := add(\n mload(\n add(\n orderParameters,\n OrderParameters_consideration_head_offset\n )\n ),\n OneWord\n )\n\n // Iterate over the consideration items (not including tips).\n // prettier-ignore\n for { let i := 0 } lt(i, originalConsiderationLength) {\n i := add(i, 1)\n } {\n // Read the pointer to the consideration data and subtract one\n // word to get typeHash pointer.\n let ptr := sub(mload(considerationArrPtr), OneWord)\n\n // Read the current value before the consideration data.\n let value := mload(ptr)\n\n // Write the type hash to the previous word.\n mstore(ptr, typeHash)\n\n // Take the EIP712 hash and store it in the hash array.\n mstore(\n hashArrPtr,\n keccak256(ptr, EIP712_ConsiderationItem_size)\n )\n\n // Restore the previous word.\n mstore(ptr, value)\n\n // Increment the array pointers by one word.\n considerationArrPtr := add(considerationArrPtr, OneWord)\n hashArrPtr := add(hashArrPtr, OneWord)\n }\n\n // Derive the consideration hash using the hashes of each item.\n considerationHash := keccak256(\n mload(FreeMemoryPointerSlot),\n mul(originalConsiderationLength, OneWord)\n )\n }\n\n // Read order item EIP-712 typehash from runtime code & place on stack.\n typeHash = _ORDER_TYPEHASH;\n\n // Utilize assembly to access derived hashes & other arguments directly.\n assembly {\n // Retrieve pointer to the region located just behind parameters.\n let typeHashPtr := sub(orderParameters, OneWord)\n\n // Store the value at that pointer location to restore later.\n let previousValue := mload(typeHashPtr)\n\n // Store the order item EIP-712 typehash at the typehash location.\n mstore(typeHashPtr, typeHash)\n\n // Retrieve the pointer for the offer array head.\n let offerHeadPtr := add(\n orderParameters,\n OrderParameters_offer_head_offset\n )\n\n // Retrieve the data pointer referenced by the offer head.\n let offerDataPtr := mload(offerHeadPtr)\n\n // Store the offer hash at the retrieved memory location.\n mstore(offerHeadPtr, offerHash)\n\n // Retrieve the pointer for the consideration array head.\n let considerationHeadPtr := add(\n orderParameters,\n OrderParameters_consideration_head_offset\n )\n\n // Retrieve the data pointer referenced by the consideration head.\n let considerationDataPtr := mload(considerationHeadPtr)\n\n // Store the consideration hash at the retrieved memory location.\n mstore(considerationHeadPtr, considerationHash)\n\n // Retrieve the pointer for the counter.\n let counterPtr := add(\n orderParameters,\n OrderParameters_counter_offset\n )\n\n // Store the counter at the retrieved memory location.\n mstore(counterPtr, counter)\n\n // Derive the order hash using the full range of order parameters.\n orderHash := keccak256(typeHashPtr, EIP712_Order_size)\n\n // Restore the value previously held at typehash pointer location.\n mstore(typeHashPtr, previousValue)\n\n // Restore offer data pointer at the offer head pointer location.\n mstore(offerHeadPtr, offerDataPtr)\n\n // Restore consideration data pointer at the consideration head ptr.\n mstore(considerationHeadPtr, considerationDataPtr)\n\n // Restore consideration item length at the counter pointer.\n mstore(counterPtr, originalConsiderationLength)\n }\n }\n\n /**\n * @dev Internal view function to derive the address of a given conduit\n * using a corresponding conduit key.\n *\n * @param conduitKey A bytes32 value indicating what corresponding conduit,\n * if any, to source token approvals from. This value is\n * the \"salt\" parameter supplied by the deployer (i.e. the\n * conduit controller) when deploying the given conduit.\n *\n * @return conduit The address of the conduit associated with the given\n * conduit key.\n */\n function _deriveConduit(bytes32 conduitKey)\n internal\n view\n returns (address conduit)\n {\n // Read conduit controller address from runtime and place on the stack.\n address conduitController = address(_CONDUIT_CONTROLLER);\n\n // Read conduit creation code hash from runtime and place on the stack.\n bytes32 conduitCreationCodeHash = _CONDUIT_CREATION_CODE_HASH;\n\n // Leverage scratch space to perform an efficient hash.\n assembly {\n // Retrieve the free memory pointer; it will be replaced afterwards.\n let freeMemoryPointer := mload(FreeMemoryPointerSlot)\n\n // Place the control character and the conduit controller in scratch\n // space; note that eleven bytes at the beginning are left unused.\n mstore(0, or(MaskOverByteTwelve, conduitController))\n\n // Place the conduit key in the next region of scratch space.\n mstore(OneWord, conduitKey)\n\n // Place conduit creation code hash in free memory pointer location.\n mstore(TwoWords, conduitCreationCodeHash)\n\n // Derive conduit by hashing and applying a mask over last 20 bytes.\n conduit := and(\n // Hash the relevant region.\n keccak256(\n // The region starts at memory pointer 11.\n Create2AddressDerivation_ptr,\n // The region is 85 bytes long (1 + 20 + 32 + 32).\n Create2AddressDerivation_length\n ),\n // The address equals the last twenty bytes of the hash.\n MaskOverLastTwentyBytes\n )\n\n // Restore the free memory pointer.\n mstore(FreeMemoryPointerSlot, freeMemoryPointer)\n }\n }\n\n /**\n * @dev Internal view function to get the EIP-712 domain separator. If the\n * chainId matches the chainId set on deployment, the cached domain\n * separator will be returned; otherwise, it will be derived from\n * scratch.\n *\n * @return The domain separator.\n */\n function _domainSeparator() internal view returns (bytes32) {\n // prettier-ignore\n return block.chainid == _CHAIN_ID\n ? _DOMAIN_SEPARATOR\n : _deriveDomainSeparator();\n }\n\n /**\n * @dev Internal view function to retrieve configuration information for\n * this contract.\n *\n * @return version The contract version.\n * @return domainSeparator The domain separator for this contract.\n * @return conduitController The conduit Controller set for this contract.\n */\n function _information()\n internal\n view\n returns (\n string memory version,\n bytes32 domainSeparator,\n address conduitController\n )\n {\n // Derive the domain separator.\n domainSeparator = _domainSeparator();\n\n // Declare variable as immutables cannot be accessed within assembly.\n conduitController = address(_CONDUIT_CONTROLLER);\n\n // Allocate a string with the intended length.\n version = new string(Version_length);\n\n // Set the version as data on the newly allocated string.\n assembly {\n mstore(add(version, OneWord), shl(Version_shift, Version))\n }\n }\n\n /**\n * @dev Internal pure function to efficiently derive an digest to sign for\n * an order in accordance with EIP-712.\n *\n * @param domainSeparator The domain separator.\n * @param orderHash The order hash.\n *\n * @return value The hash.\n */\n function _deriveEIP712Digest(bytes32 domainSeparator, bytes32 orderHash)\n internal\n pure\n returns (bytes32 value)\n {\n // Leverage scratch space to perform an efficient hash.\n assembly {\n // Place the EIP-712 prefix at the start of scratch space.\n mstore(0, EIP_712_PREFIX)\n\n // Place the domain separator in the next region of scratch space.\n mstore(EIP712_DomainSeparator_offset, domainSeparator)\n\n // Place the order hash in scratch space, spilling into the first\n // two bytes of the free memory pointer — this should never be set\n // as memory cannot be expanded to that size, and will be zeroed out\n // after the hash is performed.\n mstore(EIP712_OrderHash_offset, orderHash)\n\n // Hash the relevant region (65 bytes).\n value := keccak256(0, EIP712_DigestPayload_size)\n\n // Clear out the dirtied bits in the memory pointer.\n mstore(EIP712_OrderHash_offset, 0)\n }\n }\n}\n" - }, - "seaport/contracts/lib/CounterManager.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\n// prettier-ignore\nimport {\n ConsiderationEventsAndErrors\n} from \"../interfaces/ConsiderationEventsAndErrors.sol\";\n\nimport { ReentrancyGuard } from \"./ReentrancyGuard.sol\";\n\n/**\n * @title CounterManager\n * @author 0age\n * @notice CounterManager contains a storage mapping and related functionality\n * for retrieving and incrementing a per-offerer counter.\n */\ncontract CounterManager is ConsiderationEventsAndErrors, ReentrancyGuard {\n // Only orders signed using an offerer's current counter are fulfillable.\n mapping(address => uint256) private _counters;\n\n /**\n * @dev Internal function to cancel all orders from a given offerer with a\n * given zone in bulk by incrementing a counter. Note that only the\n * offerer may increment the counter.\n *\n * @return newCounter The new counter.\n */\n function _incrementCounter() internal returns (uint256 newCounter) {\n // Ensure that the reentrancy guard is not currently set.\n _assertNonReentrant();\n\n // Skip overflow check as counter cannot be incremented that far.\n unchecked {\n // Increment current counter for the supplied offerer.\n newCounter = ++_counters[msg.sender];\n }\n\n // Emit an event containing the new counter.\n emit CounterIncremented(newCounter, msg.sender);\n }\n\n /**\n * @dev Internal view function to retrieve the current counter for a given\n * offerer.\n *\n * @param offerer The offerer in question.\n *\n * @return currentCounter The current counter.\n */\n function _getCounter(address offerer)\n internal\n view\n returns (uint256 currentCounter)\n {\n // Return the counter for the supplied offerer.\n currentCounter = _counters[offerer];\n }\n}\n" - }, - "seaport/contracts/lib/ConsiderationBase.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\n// prettier-ignore\nimport {\n ConduitControllerInterface\n} from \"../interfaces/ConduitControllerInterface.sol\";\n\n// prettier-ignore\nimport {\n ConsiderationEventsAndErrors\n} from \"../interfaces/ConsiderationEventsAndErrors.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title ConsiderationBase\n * @author 0age\n * @notice ConsiderationBase contains immutable constants and constructor logic.\n */\ncontract ConsiderationBase is ConsiderationEventsAndErrors {\n // Precompute hashes, original chainId, and domain separator on deployment.\n bytes32 internal immutable _NAME_HASH;\n bytes32 internal immutable _VERSION_HASH;\n bytes32 internal immutable _EIP_712_DOMAIN_TYPEHASH;\n bytes32 internal immutable _OFFER_ITEM_TYPEHASH;\n bytes32 internal immutable _CONSIDERATION_ITEM_TYPEHASH;\n bytes32 internal immutable _ORDER_TYPEHASH;\n uint256 internal immutable _CHAIN_ID;\n bytes32 internal immutable _DOMAIN_SEPARATOR;\n\n // Allow for interaction with the conduit controller.\n ConduitControllerInterface internal immutable _CONDUIT_CONTROLLER;\n\n // Cache the conduit creation code hash used by the conduit controller.\n bytes32 internal immutable _CONDUIT_CREATION_CODE_HASH;\n\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) {\n // Derive name and version hashes alongside required EIP-712 typehashes.\n (\n _NAME_HASH,\n _VERSION_HASH,\n _EIP_712_DOMAIN_TYPEHASH,\n _OFFER_ITEM_TYPEHASH,\n _CONSIDERATION_ITEM_TYPEHASH,\n _ORDER_TYPEHASH\n ) = _deriveTypehashes();\n\n // Store the current chainId and derive the current domain separator.\n _CHAIN_ID = block.chainid;\n _DOMAIN_SEPARATOR = _deriveDomainSeparator();\n\n // Set the supplied conduit controller.\n _CONDUIT_CONTROLLER = ConduitControllerInterface(conduitController);\n\n // Retrieve the conduit creation code hash from the supplied controller.\n (_CONDUIT_CREATION_CODE_HASH, ) = (\n _CONDUIT_CONTROLLER.getConduitCodeHashes()\n );\n }\n\n /**\n * @dev Internal view function to derive the EIP-712 domain separator.\n *\n * @return The derived domain separator.\n */\n function _deriveDomainSeparator() internal view returns (bytes32) {\n // prettier-ignore\n return keccak256(\n abi.encode(\n _EIP_712_DOMAIN_TYPEHASH,\n _NAME_HASH,\n _VERSION_HASH,\n block.chainid,\n address(this)\n )\n );\n }\n\n /**\n * @dev Internal pure function to retrieve the default name of this\n * contract and return.\n *\n * @return The name of this contract.\n */\n function _name() internal pure virtual returns (string memory) {\n // Return the name of the contract.\n assembly {\n // First element is the offset for the returned string. Offset the\n // value in memory by one word so that the free memory pointer will\n // be overwritten by the next write.\n mstore(OneWord, OneWord)\n\n // Name is right padded, so it touches the length which is left\n // padded. This enables writing both values at once. The free memory\n // pointer will be overwritten in the process.\n mstore(NameLengthPtr, NameWithLength)\n\n // Standard ABI encoding pads returned data to the nearest word. Use\n // the already empty zero slot memory region for this purpose and\n // return the final name string, offset by the original single word.\n return(OneWord, ThreeWords)\n }\n }\n\n /**\n * @dev Internal pure function to retrieve the default name of this contract\n * as a string that can be used internally.\n *\n * @return The name of this contract.\n */\n function _nameString() internal pure virtual returns (string memory) {\n // Return the name of the contract.\n return \"Consideration\";\n }\n\n /**\n * @dev Internal pure function to derive required EIP-712 typehashes and\n * other hashes during contract creation.\n *\n * @return nameHash The hash of the name of the contract.\n * @return versionHash The hash of the version string of the\n * contract.\n * @return eip712DomainTypehash The primary EIP-712 domain typehash.\n * @return offerItemTypehash The EIP-712 typehash for OfferItem\n * types.\n * @return considerationItemTypehash The EIP-712 typehash for\n * ConsiderationItem types.\n * @return orderTypehash The EIP-712 typehash for Order types.\n */\n function _deriveTypehashes()\n internal\n pure\n returns (\n bytes32 nameHash,\n bytes32 versionHash,\n bytes32 eip712DomainTypehash,\n bytes32 offerItemTypehash,\n bytes32 considerationItemTypehash,\n bytes32 orderTypehash\n )\n {\n // Derive hash of the name of the contract.\n nameHash = keccak256(bytes(_nameString()));\n\n // Derive hash of the version string of the contract.\n versionHash = keccak256(bytes(\"1.1\"));\n\n // Construct the OfferItem type string.\n // prettier-ignore\n bytes memory offerItemTypeString = abi.encodePacked(\n \"OfferItem(\",\n \"uint8 itemType,\",\n \"address token,\",\n \"uint256 identifierOrCriteria,\",\n \"uint256 startAmount,\",\n \"uint256 endAmount\",\n \")\"\n );\n\n // Construct the ConsiderationItem type string.\n // prettier-ignore\n bytes memory considerationItemTypeString = abi.encodePacked(\n \"ConsiderationItem(\",\n \"uint8 itemType,\",\n \"address token,\",\n \"uint256 identifierOrCriteria,\",\n \"uint256 startAmount,\",\n \"uint256 endAmount,\",\n \"address recipient\",\n \")\"\n );\n\n // Construct the OrderComponents type string, not including the above.\n // prettier-ignore\n bytes memory orderComponentsPartialTypeString = abi.encodePacked(\n \"OrderComponents(\",\n \"address offerer,\",\n \"address zone,\",\n \"OfferItem[] offer,\",\n \"ConsiderationItem[] consideration,\",\n \"uint8 orderType,\",\n \"uint256 startTime,\",\n \"uint256 endTime,\",\n \"bytes32 zoneHash,\",\n \"uint256 salt,\",\n \"bytes32 conduitKey,\",\n \"uint256 counter\",\n \")\"\n );\n\n // Construct the primary EIP-712 domain type string.\n // prettier-ignore\n eip712DomainTypehash = keccak256(\n abi.encodePacked(\n \"EIP712Domain(\",\n \"string name,\",\n \"string version,\",\n \"uint256 chainId,\",\n \"address verifyingContract\",\n \")\"\n )\n );\n\n // Derive the OfferItem type hash using the corresponding type string.\n offerItemTypehash = keccak256(offerItemTypeString);\n\n // Derive ConsiderationItem type hash using corresponding type string.\n considerationItemTypehash = keccak256(considerationItemTypeString);\n\n // Derive OrderItem type hash via combination of relevant type strings.\n orderTypehash = keccak256(\n abi.encodePacked(\n orderComponentsPartialTypeString,\n considerationItemTypeString,\n offerItemTypeString\n )\n );\n }\n}\n" - }, - "seaport/contracts/interfaces/ConsiderationEventsAndErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport { SpentItem, ReceivedItem } from \"../lib/ConsiderationStructs.sol\";\n\n/**\n * @title ConsiderationEventsAndErrors\n * @author 0age\n * @notice ConsiderationEventsAndErrors contains all events and errors.\n */\ninterface ConsiderationEventsAndErrors {\n /**\n * @dev Emit an event whenever an order is successfully fulfilled.\n *\n * @param orderHash The hash of the fulfilled order.\n * @param offerer The offerer of the fulfilled order.\n * @param zone The zone of the fulfilled order.\n * @param recipient The recipient of each spent item on the fulfilled\n * order, or the null address if there is no specific\n * fulfiller (i.e. the order is part of a group of\n * orders). Defaults to the caller unless explicitly\n * specified otherwise by the fulfiller.\n * @param offer The offer items spent as part of the order.\n * @param consideration The consideration items received as part of the\n * order along with the recipients of each item.\n */\n event OrderFulfilled(\n bytes32 orderHash,\n address indexed offerer,\n address indexed zone,\n address recipient,\n SpentItem[] offer,\n ReceivedItem[] consideration\n );\n\n /**\n * @dev Emit an event whenever an order is successfully cancelled.\n *\n * @param orderHash The hash of the cancelled order.\n * @param offerer The offerer of the cancelled order.\n * @param zone The zone of the cancelled order.\n */\n event OrderCancelled(\n bytes32 orderHash,\n address indexed offerer,\n address indexed zone\n );\n\n /**\n * @dev Emit an event whenever an order is explicitly validated. Note that\n * this event will not be emitted on partial fills even though they do\n * validate the order as part of partial fulfillment.\n *\n * @param orderHash The hash of the validated order.\n * @param offerer The offerer of the validated order.\n * @param zone The zone of the validated order.\n */\n event OrderValidated(\n bytes32 orderHash,\n address indexed offerer,\n address indexed zone\n );\n\n /**\n * @dev Emit an event whenever a counter for a given offerer is incremented.\n *\n * @param newCounter The new counter for the offerer.\n * @param offerer The offerer in question.\n */\n event CounterIncremented(uint256 newCounter, address indexed offerer);\n\n /**\n * @dev Revert with an error when attempting to fill an order that has\n * already been fully filled.\n *\n * @param orderHash The order hash on which a fill was attempted.\n */\n error OrderAlreadyFilled(bytes32 orderHash);\n\n /**\n * @dev Revert with an error when attempting to fill an order outside the\n * specified start time and end time.\n */\n error InvalidTime();\n\n /**\n * @dev Revert with an error when attempting to fill an order referencing an\n * invalid conduit (i.e. one that has not been deployed).\n */\n error InvalidConduit(bytes32 conduitKey, address conduit);\n\n /**\n * @dev Revert with an error when an order is supplied for fulfillment with\n * a consideration array that is shorter than the original array.\n */\n error MissingOriginalConsiderationItems();\n\n /**\n * @dev Revert with an error when a call to a conduit fails with revert data\n * that is too expensive to return.\n */\n error InvalidCallToConduit(address conduit);\n\n /**\n * @dev Revert with an error if a consideration amount has not been fully\n * zeroed out after applying all fulfillments.\n *\n * @param orderIndex The index of the order with the consideration\n * item with a shortfall.\n * @param considerationIndex The index of the consideration item on the\n * order.\n * @param shortfallAmount The unfulfilled consideration amount.\n */\n error ConsiderationNotMet(\n uint256 orderIndex,\n uint256 considerationIndex,\n uint256 shortfallAmount\n );\n\n /**\n * @dev Revert with an error when insufficient ether is supplied as part of\n * msg.value when fulfilling orders.\n */\n error InsufficientEtherSupplied();\n\n /**\n * @dev Revert with an error when an ether transfer reverts.\n */\n error EtherTransferGenericFailure(address account, uint256 amount);\n\n /**\n * @dev Revert with an error when a partial fill is attempted on an order\n * that does not specify partial fill support in its order type.\n */\n error PartialFillsNotEnabledForOrder();\n\n /**\n * @dev Revert with an error when attempting to fill an order that has been\n * cancelled.\n *\n * @param orderHash The hash of the cancelled order.\n */\n error OrderIsCancelled(bytes32 orderHash);\n\n /**\n * @dev Revert with an error when attempting to fill a basic order that has\n * been partially filled.\n *\n * @param orderHash The hash of the partially used order.\n */\n error OrderPartiallyFilled(bytes32 orderHash);\n\n /**\n * @dev Revert with an error when attempting to cancel an order as a caller\n * other than the indicated offerer or zone.\n */\n error InvalidCanceller();\n\n /**\n * @dev Revert with an error when supplying a fraction with a value of zero\n * for the numerator or denominator, or one where the numerator exceeds\n * the denominator.\n */\n error BadFraction();\n\n /**\n * @dev Revert with an error when a caller attempts to supply callvalue to a\n * non-payable basic order route or does not supply any callvalue to a\n * payable basic order route.\n */\n error InvalidMsgValue(uint256 value);\n\n /**\n * @dev Revert with an error when attempting to fill a basic order using\n * calldata not produced by default ABI encoding.\n */\n error InvalidBasicOrderParameterEncoding();\n\n /**\n * @dev Revert with an error when attempting to fulfill any number of\n * available orders when none are fulfillable.\n */\n error NoSpecifiedOrdersAvailable();\n\n /**\n * @dev Revert with an error when attempting to fulfill an order with an\n * offer for ETH outside of matching orders.\n */\n error InvalidNativeOfferItem();\n}\n" - }, - "seaport/contracts/lib/ReentrancyGuard.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { ReentrancyErrors } from \"../interfaces/ReentrancyErrors.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title ReentrancyGuard\n * @author 0age\n * @notice ReentrancyGuard contains a storage variable and related functionality\n * for protecting against reentrancy.\n */\ncontract ReentrancyGuard is ReentrancyErrors {\n // Prevent reentrant calls on protected functions.\n uint256 private _reentrancyGuard;\n\n /**\n * @dev Initialize the reentrancy guard during deployment.\n */\n constructor() {\n // Initialize the reentrancy guard in a cleared state.\n _reentrancyGuard = _NOT_ENTERED;\n }\n\n /**\n * @dev Internal function to ensure that the sentinel value for the\n * reentrancy guard is not currently set and, if not, to set the\n * sentinel value for the reentrancy guard.\n */\n function _setReentrancyGuard() internal {\n // Ensure that the reentrancy guard is not already set.\n _assertNonReentrant();\n\n // Set the reentrancy guard.\n _reentrancyGuard = _ENTERED;\n }\n\n /**\n * @dev Internal function to unset the reentrancy guard sentinel value.\n */\n function _clearReentrancyGuard() internal {\n // Clear the reentrancy guard.\n _reentrancyGuard = _NOT_ENTERED;\n }\n\n /**\n * @dev Internal view function to ensure that the sentinel value for the\n reentrancy guard is not currently set.\n */\n function _assertNonReentrant() internal view {\n // Ensure that the reentrancy guard is not currently set.\n if (_reentrancyGuard != _NOT_ENTERED) {\n revert NoReentrantCalls();\n }\n }\n}\n" - }, - "seaport/contracts/interfaces/ReentrancyErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/**\n * @title ReentrancyErrors\n * @author 0age\n * @notice ReentrancyErrors contains errors related to reentrancy.\n */\ninterface ReentrancyErrors {\n /**\n * @dev Revert with an error when a caller attempts to reenter a protected\n * function.\n */\n error NoReentrantCalls();\n}\n" - }, - "seaport/contracts/interfaces/EIP1271Interface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\ninterface EIP1271Interface {\n function isValidSignature(bytes32 digest, bytes calldata signature)\n external\n view\n returns (bytes4);\n}\n" - }, - "seaport/contracts/interfaces/SignatureVerificationErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/**\n * @title SignatureVerificationErrors\n * @author 0age\n * @notice SignatureVerificationErrors contains all errors related to signature\n * verification.\n */\ninterface SignatureVerificationErrors {\n /**\n * @dev Revert with an error when a signature that does not contain a v\n * value of 27 or 28 has been supplied.\n *\n * @param v The invalid v value.\n */\n error BadSignatureV(uint8 v);\n\n /**\n * @dev Revert with an error when the signer recovered by the supplied\n * signature does not match the offerer or an allowed EIP-1271 signer\n * as specified by the offerer in the event they are a contract.\n */\n error InvalidSigner();\n\n /**\n * @dev Revert with an error when a signer cannot be recovered from the\n * supplied signature.\n */\n error InvalidSignature();\n\n /**\n * @dev Revert with an error when an EIP-1271 call to an account fails.\n */\n error BadContractSignature();\n}\n" - }, - "seaport/contracts/lib/LowLevelHelpers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title LowLevelHelpers\n * @author 0age\n * @notice LowLevelHelpers contains logic for performing various low-level\n * operations.\n */\ncontract LowLevelHelpers {\n /**\n * @dev Internal view function to staticcall an arbitrary target with given\n * calldata. Note that no data is written to memory and no contract\n * size check is performed.\n *\n * @param target The account to staticcall.\n * @param callData The calldata to supply when staticcalling the target.\n *\n * @return success The status of the staticcall to the target.\n */\n function _staticcall(address target, bytes memory callData)\n internal\n view\n returns (bool success)\n {\n assembly {\n // Perform the staticcall.\n success := staticcall(\n gas(),\n target,\n add(callData, OneWord),\n mload(callData),\n 0,\n 0\n )\n }\n }\n\n /**\n * @dev Internal view function to revert and pass along the revert reason if\n * data was returned by the last call and that the size of that data\n * does not exceed the currently allocated memory size.\n */\n function _revertWithReasonIfOneIsReturned() internal view {\n assembly {\n // If it returned a message, bubble it up as long as sufficient gas\n // remains to do so:\n if returndatasize() {\n // Ensure that sufficient gas is available to copy returndata\n // while expanding memory where necessary. Start by computing\n // the word size of returndata and allocated memory.\n let returnDataWords := div(\n add(returndatasize(), AlmostOneWord),\n OneWord\n )\n\n // Note: use the free memory pointer in place of msize() to work\n // around a Yul warning that prevents accessing msize directly\n // when the IR pipeline is activated.\n let msizeWords := div(mload(FreeMemoryPointerSlot), OneWord)\n\n // Next, compute the cost of the returndatacopy.\n let cost := mul(CostPerWord, returnDataWords)\n\n // Then, compute cost of new memory allocation.\n if gt(returnDataWords, msizeWords) {\n cost := add(\n cost,\n add(\n mul(sub(returnDataWords, msizeWords), CostPerWord),\n div(\n sub(\n mul(returnDataWords, returnDataWords),\n mul(msizeWords, msizeWords)\n ),\n MemoryExpansionCoefficient\n )\n )\n )\n }\n\n // Finally, add a small constant and compare to gas remaining;\n // bubble up the revert data if enough gas is still available.\n if lt(add(cost, ExtraGasBuffer), gas()) {\n // Copy returndata to memory; overwrite existing memory.\n returndatacopy(0, 0, returndatasize())\n\n // Revert, specifying memory region with copied returndata.\n revert(0, returndatasize())\n }\n }\n }\n }\n\n /**\n * @dev Internal pure function to determine if the first word of returndata\n * matches an expected magic value.\n *\n * @param expected The expected magic value.\n *\n * @return A boolean indicating whether the expected value matches the one\n * located in the first word of returndata.\n */\n function _doesNotMatchMagic(bytes4 expected) internal pure returns (bool) {\n // Declare a variable for the value held by the return data buffer.\n bytes4 result;\n\n // Utilize assembly in order to read directly from returndata buffer.\n assembly {\n // Only put result on stack if return data is exactly one word.\n if eq(returndatasize(), OneWord) {\n // Copy the word directly from return data into scratch space.\n returndatacopy(0, 0, OneWord)\n\n // Take value from scratch space and place it on the stack.\n result := mload(0)\n }\n }\n\n // Return a boolean indicating whether expected and located value match.\n return result != expected;\n }\n}\n" - }, - "seaport/contracts/lib/FulfillmentApplier.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { ItemType, Side } from \"./ConsiderationEnums.sol\";\n\n// prettier-ignore\nimport {\n OfferItem,\n ConsiderationItem,\n ReceivedItem,\n OrderParameters,\n AdvancedOrder,\n Execution,\n FulfillmentComponent\n} from \"./ConsiderationStructs.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n// prettier-ignore\nimport {\n FulfillmentApplicationErrors\n} from \"../interfaces/FulfillmentApplicationErrors.sol\";\n\n/**\n * @title FulfillmentApplier\n * @author 0age\n * @notice FulfillmentApplier contains logic related to applying fulfillments,\n * both as part of order matching (where offer items are matched to\n * consideration items) as well as fulfilling available orders (where\n * order items and consideration items are independently aggregated).\n */\ncontract FulfillmentApplier is FulfillmentApplicationErrors {\n /**\n * @dev Internal pure function to match offer items to consideration items\n * on a group of orders via a supplied fulfillment.\n *\n * @param advancedOrders The orders to match.\n * @param offerComponents An array designating offer components to\n * match to consideration components.\n * @param considerationComponents An array designating consideration\n * components to match to offer components.\n * Note that each consideration amount must\n * be zero in order for the match operation\n * to be valid.\n *\n * @return execution The transfer performed as a result of the fulfillment.\n */\n function _applyFulfillment(\n AdvancedOrder[] memory advancedOrders,\n FulfillmentComponent[] calldata offerComponents,\n FulfillmentComponent[] calldata considerationComponents\n ) internal pure returns (Execution memory execution) {\n // Ensure 1+ of both offer and consideration components are supplied.\n if (\n offerComponents.length == 0 || considerationComponents.length == 0\n ) {\n revert OfferAndConsiderationRequiredOnFulfillment();\n }\n\n // Declare a new Execution struct.\n Execution memory considerationExecution;\n\n // Validate & aggregate consideration items to new Execution object.\n _aggregateValidFulfillmentConsiderationItems(\n advancedOrders,\n considerationComponents,\n considerationExecution\n );\n\n // Retrieve the consideration item from the execution struct.\n ReceivedItem memory considerationItem = considerationExecution.item;\n\n // Recipient does not need to be specified because it will always be set\n // to that of the consideration.\n // Validate & aggregate offer items to Execution object.\n _aggregateValidFulfillmentOfferItems(\n advancedOrders,\n offerComponents,\n execution\n );\n\n // Ensure offer and consideration share types, tokens and identifiers.\n if (\n execution.item.itemType != considerationItem.itemType ||\n execution.item.token != considerationItem.token ||\n execution.item.identifier != considerationItem.identifier\n ) {\n revert MismatchedFulfillmentOfferAndConsiderationComponents();\n }\n\n // If total consideration amount exceeds the offer amount...\n if (considerationItem.amount > execution.item.amount) {\n // Retrieve the first consideration component from the fulfillment.\n FulfillmentComponent memory targetComponent = (\n considerationComponents[0]\n );\n\n // Skip underflow check as the conditional being true implies that\n // considerationItem.amount > execution.item.amount.\n unchecked {\n // Add excess consideration item amount to original order array.\n advancedOrders[targetComponent.orderIndex]\n .parameters\n .consideration[targetComponent.itemIndex]\n .startAmount = (considerationItem.amount -\n execution.item.amount);\n }\n\n // Reduce total consideration amount to equal the offer amount.\n considerationItem.amount = execution.item.amount;\n } else {\n // Retrieve the first offer component from the fulfillment.\n FulfillmentComponent memory targetComponent = offerComponents[0];\n\n // Skip underflow check as the conditional being false implies that\n // execution.item.amount >= considerationItem.amount.\n unchecked {\n // Add excess offer item amount to the original array of orders.\n advancedOrders[targetComponent.orderIndex]\n .parameters\n .offer[targetComponent.itemIndex]\n .startAmount = (execution.item.amount -\n considerationItem.amount);\n }\n\n // Reduce total offer amount to equal the consideration amount.\n execution.item.amount = considerationItem.amount;\n }\n\n // Reuse consideration recipient.\n execution.item.recipient = considerationItem.recipient;\n\n // Return the final execution that will be triggered for relevant items.\n return execution; // Execution(considerationItem, offerer, conduitKey);\n }\n\n /**\n * @dev Internal view function to aggregate offer or consideration items\n * from a group of orders into a single execution via a supplied array\n * of fulfillment components. Items that are not available to aggregate\n * will not be included in the aggregated execution.\n *\n * @param advancedOrders The orders to aggregate.\n * @param side The side (i.e. offer or consideration).\n * @param fulfillmentComponents An array designating item components to\n * aggregate if part of an available order.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token\n * approvals from. The zero hash signifies that\n * no conduit should be used, with approvals\n * set directly on this contract.\n * @param recipient The intended recipient for all received\n * items.\n *\n * @return execution The transfer performed as a result of the fulfillment.\n */\n function _aggregateAvailable(\n AdvancedOrder[] memory advancedOrders,\n Side side,\n FulfillmentComponent[] memory fulfillmentComponents,\n bytes32 fulfillerConduitKey,\n address recipient\n ) internal view returns (Execution memory execution) {\n // Skip overflow / underflow checks; conditions checked or unreachable.\n unchecked {\n // Retrieve fulfillment components array length and place on stack.\n // Ensure at least one fulfillment component has been supplied.\n if (fulfillmentComponents.length == 0) {\n revert MissingFulfillmentComponentOnAggregation(side);\n }\n\n // If the fulfillment components are offer components...\n if (side == Side.OFFER) {\n // Set the supplied recipient on the execution item.\n execution.item.recipient = payable(recipient);\n\n // Return execution for aggregated items provided by offerer.\n _aggregateValidFulfillmentOfferItems(\n advancedOrders,\n fulfillmentComponents,\n execution\n );\n } else {\n // Otherwise, fulfillment components are consideration\n // components. Return execution for aggregated items provided by\n // the fulfiller.\n _aggregateValidFulfillmentConsiderationItems(\n advancedOrders,\n fulfillmentComponents,\n execution\n );\n\n // Set the caller as the offerer on the execution.\n execution.offerer = msg.sender;\n\n // Set fulfiller conduit key as the conduit key on execution.\n execution.conduitKey = fulfillerConduitKey;\n }\n\n // Set the offerer and recipient to null address if execution\n // amount is zero. This will cause the execution item to be skipped.\n if (execution.item.amount == 0) {\n execution.offerer = address(0);\n execution.item.recipient = payable(0);\n }\n }\n }\n\n /**\n * @dev Internal pure function to aggregate a group of offer items using\n * supplied directives on which component items are candidates for\n * aggregation, skipping items on orders that are not available.\n *\n * @param advancedOrders The orders to aggregate offer items from.\n * @param offerComponents An array of FulfillmentComponent structs\n * indicating the order index and item index of each\n * candidate offer item for aggregation.\n * @param execution The execution to apply the aggregation to.\n */\n function _aggregateValidFulfillmentOfferItems(\n AdvancedOrder[] memory advancedOrders,\n FulfillmentComponent[] memory offerComponents,\n Execution memory execution\n ) internal pure {\n assembly {\n // Declare function for reverts on invalid fulfillment data.\n function throwInvalidFulfillmentComponentData() {\n // Store the InvalidFulfillmentComponentData error signature.\n mstore(0, InvalidFulfillmentComponentData_error_signature)\n\n // Return, supplying InvalidFulfillmentComponentData signature.\n revert(0, InvalidFulfillmentComponentData_error_len)\n }\n\n // Declare function for reverts due to arithmetic overflows.\n function throwOverflow() {\n // Store the Panic error signature.\n mstore(0, Panic_error_signature)\n\n // Store the arithmetic (0x11) panic code as initial argument.\n mstore(Panic_error_offset, Panic_arithmetic)\n\n // Return, supplying Panic signature and arithmetic code.\n revert(0, Panic_error_length)\n }\n\n // Get position in offerComponents head.\n let fulfillmentHeadPtr := add(offerComponents, OneWord)\n\n // Retrieve the order index using the fulfillment pointer.\n let orderIndex := mload(mload(fulfillmentHeadPtr))\n\n // Ensure that the order index is not out of range.\n if iszero(lt(orderIndex, mload(advancedOrders))) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Read advancedOrders[orderIndex] pointer from its array head.\n let orderPtr := mload(\n // Calculate head position of advancedOrders[orderIndex].\n add(add(advancedOrders, OneWord), mul(orderIndex, OneWord))\n )\n\n // Read the pointer to OrderParameters from the AdvancedOrder.\n let paramsPtr := mload(orderPtr)\n\n // Load the offer array pointer.\n let offerArrPtr := mload(\n add(paramsPtr, OrderParameters_offer_head_offset)\n )\n\n // Retrieve item index using an offset of the fulfillment pointer.\n let itemIndex := mload(\n add(mload(fulfillmentHeadPtr), Fulfillment_itemIndex_offset)\n )\n\n // Only continue if the fulfillment is not invalid.\n if iszero(lt(itemIndex, mload(offerArrPtr))) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Retrieve consideration item pointer using the item index.\n let offerItemPtr := mload(\n add(\n // Get pointer to beginning of receivedItem.\n add(offerArrPtr, OneWord),\n // Calculate offset to pointer for desired order.\n mul(itemIndex, OneWord)\n )\n )\n\n // Declare a variable for the final aggregated item amount.\n let amount := 0\n\n // Create variable to track errors encountered with amount.\n let errorBuffer := 0\n\n // Only add offer amount to execution amount on a nonzero numerator.\n if mload(add(orderPtr, AdvancedOrder_numerator_offset)) {\n // Retrieve amount pointer using consideration item pointer.\n let amountPtr := add(offerItemPtr, Common_amount_offset)\n\n // Set the amount.\n amount := mload(amountPtr)\n\n // Zero out amount on item to indicate it is credited.\n mstore(amountPtr, 0)\n\n // Buffer indicating whether issues were found.\n errorBuffer := iszero(amount)\n }\n\n // Retrieve the received item pointer.\n let receivedItemPtr := mload(execution)\n\n // Set the item type on the received item.\n mstore(receivedItemPtr, mload(offerItemPtr))\n\n // Set the token on the received item.\n mstore(\n add(receivedItemPtr, Common_token_offset),\n mload(add(offerItemPtr, Common_token_offset))\n )\n\n // Set the identifier on the received item.\n mstore(\n add(receivedItemPtr, Common_identifier_offset),\n mload(add(offerItemPtr, Common_identifier_offset))\n )\n\n // Set the offerer on returned execution using order pointer.\n mstore(add(execution, Execution_offerer_offset), mload(paramsPtr))\n\n // Set conduitKey on returned execution via offset of order pointer.\n mstore(\n add(execution, Execution_conduit_offset),\n mload(add(paramsPtr, OrderParameters_conduit_offset))\n )\n\n // Calculate the hash of (itemType, token, identifier).\n let dataHash := keccak256(\n receivedItemPtr,\n ReceivedItem_CommonParams_size\n )\n\n // Get position one word past last element in head of array.\n let endPtr := add(\n offerComponents,\n mul(mload(offerComponents), OneWord)\n )\n\n // Iterate over remaining offer components.\n // prettier-ignore\n for {} lt(fulfillmentHeadPtr, endPtr) {} {\n // Increment the pointer to the fulfillment head by one word.\n fulfillmentHeadPtr := add(fulfillmentHeadPtr, OneWord)\n\n // Get the order index using the fulfillment pointer.\n orderIndex := mload(mload(fulfillmentHeadPtr))\n\n // Ensure the order index is in range.\n if iszero(lt(orderIndex, mload(advancedOrders))) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Get pointer to AdvancedOrder element.\n orderPtr := mload(\n add(\n add(advancedOrders, OneWord),\n mul(orderIndex, OneWord)\n )\n )\n\n // Only continue if numerator is not zero.\n if iszero(mload(\n add(orderPtr, AdvancedOrder_numerator_offset)\n )) {\n continue\n }\n\n // Read the pointer to OrderParameters from the AdvancedOrder.\n paramsPtr := mload(orderPtr)\n\n // Load offer array pointer.\n offerArrPtr := mload(\n add(\n paramsPtr,\n OrderParameters_offer_head_offset\n )\n )\n\n // Get the item index using the fulfillment pointer.\n itemIndex := mload(add(mload(fulfillmentHeadPtr), OneWord))\n\n // Throw if itemIndex is out of the range of array.\n if iszero(\n lt(itemIndex, mload(offerArrPtr))\n ) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Retrieve offer item pointer using index.\n offerItemPtr := mload(\n add(\n // Get pointer to beginning of receivedItem.\n add(offerArrPtr, OneWord),\n // Use offset to pointer for desired order.\n mul(itemIndex, OneWord)\n )\n )\n\n // Retrieve amount pointer using offer item pointer.\n let amountPtr := add(\n offerItemPtr,\n Common_amount_offset\n )\n\n // Add offer amount to execution amount.\n let newAmount := add(amount, mload(amountPtr))\n\n // Update error buffer: 1 = zero amount, 2 = overflow, 3 = both.\n errorBuffer := or(\n errorBuffer,\n or(\n shl(1, lt(newAmount, amount)),\n iszero(mload(amountPtr))\n )\n )\n\n // Update the amount to the new, summed amount.\n amount := newAmount\n\n // Zero out amount on original item to indicate it is credited.\n mstore(amountPtr, 0)\n\n // Ensure the indicated item matches original item.\n if iszero(\n and(\n and(\n // The offerer must match on both items.\n eq(\n mload(paramsPtr),\n mload(\n add(execution, Execution_offerer_offset)\n )\n ),\n // The conduit key must match on both items.\n eq(\n mload(\n add(\n paramsPtr,\n OrderParameters_conduit_offset\n )\n ),\n mload(\n add(\n execution,\n Execution_conduit_offset\n )\n )\n )\n ),\n // The itemType, token, and identifier must match.\n eq(\n dataHash,\n keccak256(\n offerItemPtr,\n ReceivedItem_CommonParams_size\n )\n )\n )\n ) {\n // Throw if any of the requirements are not met.\n throwInvalidFulfillmentComponentData()\n }\n }\n // Write final amount to execution.\n mstore(add(mload(execution), Common_amount_offset), amount)\n\n // Determine whether the error buffer contains a nonzero error code.\n if errorBuffer {\n // If errorBuffer is 1, an item had an amount of zero.\n if eq(errorBuffer, 1) {\n // Store the MissingItemAmount error signature.\n mstore(0, MissingItemAmount_error_signature)\n\n // Return, supplying MissingItemAmount signature.\n revert(0, MissingItemAmount_error_len)\n }\n\n // If errorBuffer is not 1 or 0, the sum overflowed.\n // Panic!\n throwOverflow()\n }\n }\n }\n\n /**\n * @dev Internal pure function to aggregate a group of consideration items\n * using supplied directives on which component items are candidates\n * for aggregation, skipping items on orders that are not available.\n *\n * @param advancedOrders The orders to aggregate consideration\n * items from.\n * @param considerationComponents An array of FulfillmentComponent structs\n * indicating the order index and item index\n * of each candidate consideration item for\n * aggregation.\n * @param execution The execution to apply the aggregation to.\n */\n function _aggregateValidFulfillmentConsiderationItems(\n AdvancedOrder[] memory advancedOrders,\n FulfillmentComponent[] memory considerationComponents,\n Execution memory execution\n ) internal pure {\n // Utilize assembly in order to efficiently aggregate the items.\n assembly {\n // Declare function for reverts on invalid fulfillment data.\n function throwInvalidFulfillmentComponentData() {\n // Store the InvalidFulfillmentComponentData error signature.\n mstore(0, InvalidFulfillmentComponentData_error_signature)\n\n // Return, supplying InvalidFulfillmentComponentData signature.\n revert(0, InvalidFulfillmentComponentData_error_len)\n }\n\n // Declare function for reverts due to arithmetic overflows.\n function throwOverflow() {\n // Store the Panic error signature.\n mstore(0, Panic_error_signature)\n\n // Store the arithmetic (0x11) panic code as initial argument.\n mstore(Panic_error_offset, Panic_arithmetic)\n\n // Return, supplying Panic signature and arithmetic code.\n revert(0, Panic_error_length)\n }\n\n // Get position in considerationComponents head.\n let fulfillmentHeadPtr := add(considerationComponents, OneWord)\n\n // Retrieve the order index using the fulfillment pointer.\n let orderIndex := mload(mload(fulfillmentHeadPtr))\n\n // Ensure that the order index is not out of range.\n if iszero(lt(orderIndex, mload(advancedOrders))) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Read advancedOrders[orderIndex] pointer from its array head.\n let orderPtr := mload(\n // Calculate head position of advancedOrders[orderIndex].\n add(add(advancedOrders, OneWord), mul(orderIndex, OneWord))\n )\n\n // Load consideration array pointer.\n let considerationArrPtr := mload(\n add(\n // Read pointer to OrderParameters from the AdvancedOrder.\n mload(orderPtr),\n OrderParameters_consideration_head_offset\n )\n )\n\n // Retrieve item index using an offset of the fulfillment pointer.\n let itemIndex := mload(\n add(mload(fulfillmentHeadPtr), Fulfillment_itemIndex_offset)\n )\n\n // Ensure that the order index is not out of range.\n if iszero(lt(itemIndex, mload(considerationArrPtr))) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Retrieve consideration item pointer using the item index.\n let considerationItemPtr := mload(\n add(\n // Get pointer to beginning of receivedItem.\n add(considerationArrPtr, OneWord),\n // Calculate offset to pointer for desired order.\n mul(itemIndex, OneWord)\n )\n )\n\n // Declare a variable for the final aggregated item amount.\n let amount := 0\n\n // Create variable to track errors encountered with amount.\n let errorBuffer := 0\n\n // Only add consideration amount to execution amount if numerator is\n // greater than zero.\n if mload(add(orderPtr, AdvancedOrder_numerator_offset)) {\n // Retrieve amount pointer using consideration item pointer.\n let amountPtr := add(considerationItemPtr, Common_amount_offset)\n\n // Set the amount.\n amount := mload(amountPtr)\n\n // Set error bit if amount is zero.\n errorBuffer := iszero(amount)\n\n // Zero out amount on item to indicate it is credited.\n mstore(amountPtr, 0)\n }\n\n // Retrieve ReceivedItem pointer from Execution.\n let receivedItem := mload(execution)\n\n // Set the item type on the received item.\n mstore(receivedItem, mload(considerationItemPtr))\n\n // Set the token on the received item.\n mstore(\n add(receivedItem, Common_token_offset),\n mload(add(considerationItemPtr, Common_token_offset))\n )\n\n // Set the identifier on the received item.\n mstore(\n add(receivedItem, Common_identifier_offset),\n mload(add(considerationItemPtr, Common_identifier_offset))\n )\n\n // Set the recipient on the received item.\n mstore(\n add(receivedItem, ReceivedItem_recipient_offset),\n mload(\n add(\n considerationItemPtr,\n ConsiderationItem_recipient_offset\n )\n )\n )\n\n // Calculate the hash of (itemType, token, identifier).\n let dataHash := keccak256(\n receivedItem,\n ReceivedItem_CommonParams_size\n )\n\n // Get position one word past last element in head of array.\n let endPtr := add(\n considerationComponents,\n mul(mload(considerationComponents), OneWord)\n )\n\n // Iterate over remaining offer components.\n // prettier-ignore\n for {} lt(fulfillmentHeadPtr, endPtr) {} {\n // Increment position in considerationComponents head.\n fulfillmentHeadPtr := add(fulfillmentHeadPtr, OneWord)\n\n // Get the order index using the fulfillment pointer.\n orderIndex := mload(mload(fulfillmentHeadPtr))\n\n // Ensure the order index is in range.\n if iszero(lt(orderIndex, mload(advancedOrders))) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Get pointer to AdvancedOrder element.\n orderPtr := mload(\n add(\n add(advancedOrders, OneWord),\n mul(orderIndex, OneWord)\n )\n )\n\n // Only continue if numerator is not zero.\n if iszero(\n mload(add(orderPtr, AdvancedOrder_numerator_offset))\n ) {\n continue\n }\n\n // Load consideration array pointer from OrderParameters.\n considerationArrPtr := mload(\n add(\n // Get pointer to OrderParameters from AdvancedOrder.\n mload(orderPtr),\n OrderParameters_consideration_head_offset\n )\n )\n\n // Get the item index using the fulfillment pointer.\n itemIndex := mload(add(mload(fulfillmentHeadPtr), OneWord))\n\n // Check if itemIndex is within the range of array.\n if iszero(lt(itemIndex, mload(considerationArrPtr))) {\n throwInvalidFulfillmentComponentData()\n }\n\n // Retrieve consideration item pointer using index.\n considerationItemPtr := mload(\n add(\n // Get pointer to beginning of receivedItem.\n add(considerationArrPtr, OneWord),\n // Use offset to pointer for desired order.\n mul(itemIndex, OneWord)\n )\n )\n\n // Retrieve amount pointer using consideration item pointer.\n let amountPtr := add(\n considerationItemPtr,\n Common_amount_offset\n )\n\n // Add offer amount to execution amount.\n let newAmount := add(amount, mload(amountPtr))\n\n // Update error buffer: 1 = zero amount, 2 = overflow, 3 = both.\n errorBuffer := or(\n errorBuffer,\n or(\n shl(1, lt(newAmount, amount)),\n iszero(mload(amountPtr))\n )\n )\n\n // Update the amount to the new, summed amount.\n amount := newAmount\n\n // Zero out amount on original item to indicate it is credited.\n mstore(amountPtr, 0)\n\n // Ensure the indicated item matches original item.\n if iszero(\n and(\n // Item recipients must match.\n eq(\n mload(\n add(\n considerationItemPtr,\n ConsiderItem_recipient_offset\n )\n ),\n mload(\n add(\n receivedItem,\n ReceivedItem_recipient_offset\n )\n )\n ),\n // The itemType, token, identifier must match.\n eq(\n dataHash,\n keccak256(\n considerationItemPtr,\n ReceivedItem_CommonParams_size\n )\n )\n )\n ) {\n // Throw if any of the requirements are not met.\n throwInvalidFulfillmentComponentData()\n }\n }\n // Write final amount to execution.\n mstore(add(receivedItem, Common_amount_offset), amount)\n\n // Determine whether the error buffer contains a nonzero error code.\n if errorBuffer {\n // If errorBuffer is 1, an item had an amount of zero.\n if eq(errorBuffer, 1) {\n // Store the MissingItemAmount error signature.\n mstore(0, MissingItemAmount_error_signature)\n\n // Return, supplying MissingItemAmount signature.\n revert(0, MissingItemAmount_error_len)\n }\n\n // If errorBuffer is not 1 or 0, the sum overflowed.\n // Panic!\n throwOverflow()\n }\n }\n }\n}\n" - }, - "seaport/contracts/interfaces/FulfillmentApplicationErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport { Side } from \"../lib/ConsiderationEnums.sol\";\n\n/**\n * @title FulfillmentApplicationErrors\n * @author 0age\n * @notice FulfillmentApplicationErrors contains errors related to fulfillment\n * application and aggregation.\n */\ninterface FulfillmentApplicationErrors {\n /**\n * @dev Revert with an error when a fulfillment is provided that does not\n * declare at least one component as part of a call to fulfill\n * available orders.\n */\n error MissingFulfillmentComponentOnAggregation(Side side);\n\n /**\n * @dev Revert with an error when a fulfillment is provided that does not\n * declare at least one offer component and at least one consideration\n * component.\n */\n error OfferAndConsiderationRequiredOnFulfillment();\n\n /**\n * @dev Revert with an error when the initial offer item named by a\n * fulfillment component does not match the type, token, identifier,\n * or conduit preference of the initial consideration item.\n */\n error MismatchedFulfillmentOfferAndConsiderationComponents();\n\n /**\n * @dev Revert with an error when an order or item index are out of range\n * or a fulfillment component does not match the type, token,\n * identifier, or conduit preference of the initial consideration item.\n */\n error InvalidFulfillmentComponentData();\n}\n" - }, - "seaport/contracts/lib/CriteriaResolution.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { ItemType, Side } from \"./ConsiderationEnums.sol\";\n\n// prettier-ignore\nimport {\n OfferItem,\n ConsiderationItem,\n OrderParameters,\n AdvancedOrder,\n CriteriaResolver\n} from \"./ConsiderationStructs.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n// prettier-ignore\nimport {\n CriteriaResolutionErrors\n} from \"../interfaces/CriteriaResolutionErrors.sol\";\n\n/**\n * @title CriteriaResolution\n * @author 0age\n * @notice CriteriaResolution contains a collection of pure functions related to\n * resolving criteria-based items.\n */\ncontract CriteriaResolution is CriteriaResolutionErrors {\n /**\n * @dev Internal pure function to apply criteria resolvers containing\n * specific token identifiers and associated proofs to order items.\n *\n * @param advancedOrders The orders to apply criteria resolvers to.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific order as well as that\n * order's offer or consideration, a token\n * identifier, and a proof that the supplied token\n * identifier is contained in the order's merkle\n * root. Note that a root of zero indicates that\n * any transferable token identifier is valid and\n * that no proof needs to be supplied.\n */\n function _applyCriteriaResolvers(\n AdvancedOrder[] memory advancedOrders,\n CriteriaResolver[] memory criteriaResolvers\n ) internal pure {\n // Skip overflow checks as all for loops are indexed starting at zero.\n unchecked {\n // Retrieve length of criteria resolvers array and place on stack.\n uint256 totalCriteriaResolvers = criteriaResolvers.length;\n\n // Retrieve length of orders array and place on stack.\n uint256 totalAdvancedOrders = advancedOrders.length;\n\n // Iterate over each criteria resolver.\n for (uint256 i = 0; i < totalCriteriaResolvers; ++i) {\n // Retrieve the criteria resolver.\n CriteriaResolver memory criteriaResolver = (\n criteriaResolvers[i]\n );\n\n // Read the order index from memory and place it on the stack.\n uint256 orderIndex = criteriaResolver.orderIndex;\n\n // Ensure that the order index is in range.\n if (orderIndex >= totalAdvancedOrders) {\n revert OrderCriteriaResolverOutOfRange();\n }\n\n // Skip criteria resolution for order if not fulfilled.\n if (advancedOrders[orderIndex].numerator == 0) {\n continue;\n }\n\n // Retrieve the parameters for the order.\n OrderParameters memory orderParameters = (\n advancedOrders[orderIndex].parameters\n );\n\n // Read component index from memory and place it on the stack.\n uint256 componentIndex = criteriaResolver.index;\n\n // Declare values for item's type and criteria.\n ItemType itemType;\n uint256 identifierOrCriteria;\n\n // If the criteria resolver refers to an offer item...\n if (criteriaResolver.side == Side.OFFER) {\n // Retrieve the offer.\n OfferItem[] memory offer = orderParameters.offer;\n\n // Ensure that the component index is in range.\n if (componentIndex >= offer.length) {\n revert OfferCriteriaResolverOutOfRange();\n }\n\n // Retrieve relevant item using the component index.\n OfferItem memory offerItem = offer[componentIndex];\n\n // Read item type and criteria from memory & place on stack.\n itemType = offerItem.itemType;\n identifierOrCriteria = offerItem.identifierOrCriteria;\n\n // Optimistically update item type to remove criteria usage.\n // Use assembly to operate on ItemType enum as a number.\n ItemType newItemType;\n assembly {\n // Item type 4 becomes 2 and item type 5 becomes 3.\n newItemType := sub(3, eq(itemType, 4))\n }\n offerItem.itemType = newItemType;\n\n // Optimistically update identifier w/ supplied identifier.\n offerItem.identifierOrCriteria = criteriaResolver\n .identifier;\n } else {\n // Otherwise, the resolver refers to a consideration item.\n ConsiderationItem[] memory consideration = (\n orderParameters.consideration\n );\n\n // Ensure that the component index is in range.\n if (componentIndex >= consideration.length) {\n revert ConsiderationCriteriaResolverOutOfRange();\n }\n\n // Retrieve relevant item using order and component index.\n ConsiderationItem memory considerationItem = (\n consideration[componentIndex]\n );\n\n // Read item type and criteria from memory & place on stack.\n itemType = considerationItem.itemType;\n identifierOrCriteria = (\n considerationItem.identifierOrCriteria\n );\n\n // Optimistically update item type to remove criteria usage.\n // Use assembly to operate on ItemType enum as a number.\n ItemType newItemType;\n assembly {\n // Item type 4 becomes 2 and item type 5 becomes 3.\n newItemType := sub(3, eq(itemType, 4))\n }\n considerationItem.itemType = newItemType;\n\n // Optimistically update identifier w/ supplied identifier.\n considerationItem.identifierOrCriteria = (\n criteriaResolver.identifier\n );\n }\n\n // Ensure the specified item type indicates criteria usage.\n if (!_isItemWithCriteria(itemType)) {\n revert CriteriaNotEnabledForItem();\n }\n\n // If criteria is not 0 (i.e. a collection-wide offer)...\n if (identifierOrCriteria != uint256(0)) {\n // Verify identifier inclusion in criteria root using proof.\n _verifyProof(\n criteriaResolver.identifier,\n identifierOrCriteria,\n criteriaResolver.criteriaProof\n );\n }\n }\n\n // Iterate over each advanced order.\n for (uint256 i = 0; i < totalAdvancedOrders; ++i) {\n // Retrieve the advanced order.\n AdvancedOrder memory advancedOrder = advancedOrders[i];\n\n // Skip criteria resolution for order if not fulfilled.\n if (advancedOrder.numerator == 0) {\n continue;\n }\n\n // Retrieve the parameters for the order.\n OrderParameters memory orderParameters = (\n advancedOrder.parameters\n );\n\n // Read consideration length from memory and place on stack.\n uint256 totalItems = orderParameters.consideration.length;\n\n // Iterate over each consideration item on the order.\n for (uint256 j = 0; j < totalItems; ++j) {\n // Ensure item type no longer indicates criteria usage.\n if (\n _isItemWithCriteria(\n orderParameters.consideration[j].itemType\n )\n ) {\n revert UnresolvedConsiderationCriteria();\n }\n }\n\n // Read offer length from memory and place on stack.\n totalItems = orderParameters.offer.length;\n\n // Iterate over each offer item on the order.\n for (uint256 j = 0; j < totalItems; ++j) {\n // Ensure item type no longer indicates criteria usage.\n if (\n _isItemWithCriteria(orderParameters.offer[j].itemType)\n ) {\n revert UnresolvedOfferCriteria();\n }\n }\n }\n }\n }\n\n /**\n * @dev Internal pure function to check whether a given item type represents\n * a criteria-based ERC721 or ERC1155 item (e.g. an item that can be\n * resolved to one of a number of different identifiers at the time of\n * order fulfillment).\n *\n * @param itemType The item type in question.\n *\n * @return withCriteria A boolean indicating that the item type in question\n * represents a criteria-based item.\n */\n function _isItemWithCriteria(ItemType itemType)\n internal\n pure\n returns (bool withCriteria)\n {\n // ERC721WithCriteria is ItemType 4. ERC1155WithCriteria is ItemType 5.\n assembly {\n withCriteria := gt(itemType, 3)\n }\n }\n\n /**\n * @dev Internal pure function to ensure that a given element is contained\n * in a merkle root via a supplied proof.\n *\n * @param leaf The element for which to prove inclusion.\n * @param root The merkle root that inclusion will be proved against.\n * @param proof The merkle proof.\n */\n function _verifyProof(\n uint256 leaf,\n uint256 root,\n bytes32[] memory proof\n ) internal pure {\n // Declare a variable that will be used to determine proof validity.\n bool isValid;\n\n // Utilize assembly to efficiently verify the proof against the root.\n assembly {\n // Store the leaf at the beginning of scratch space.\n mstore(0, leaf)\n\n // Derive the hash of the leaf to use as the initial proof element.\n let computedHash := keccak256(0, OneWord)\n\n // Based on: https://github.com/Rari-Capital/solmate/blob/v7/src/utils/MerkleProof.sol\n // Get memory start location of the first element in proof array.\n let data := add(proof, OneWord)\n\n // Iterate over each proof element to compute the root hash.\n for {\n // Left shift by 5 is equivalent to multiplying by 0x20.\n let end := add(data, shl(5, mload(proof)))\n } lt(data, end) {\n // Increment by one word at a time.\n data := add(data, OneWord)\n } {\n // Get the proof element.\n let loadedData := mload(data)\n\n // Sort proof elements and place them in scratch space.\n // Slot of `computedHash` in scratch space.\n // If the condition is true: 0x20, otherwise: 0x00.\n let scratch := shl(5, gt(computedHash, loadedData))\n\n // Store elements to hash contiguously in scratch space. Scratch\n // space is 64 bytes (0x00 - 0x3f) & both elements are 32 bytes.\n mstore(scratch, computedHash)\n mstore(xor(scratch, OneWord), loadedData)\n\n // Derive the updated hash.\n computedHash := keccak256(0, TwoWords)\n }\n\n // Compare the final hash to the supplied root.\n isValid := eq(computedHash, root)\n }\n\n // Revert if computed hash does not equal supplied root.\n if (!isValid) {\n revert InvalidProof();\n }\n }\n}\n" - }, - "seaport/contracts/interfaces/CriteriaResolutionErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/**\n * @title CriteriaResolutionErrors\n * @author 0age\n * @notice CriteriaResolutionErrors contains all errors related to criteria\n * resolution.\n */\ninterface CriteriaResolutionErrors {\n /**\n * @dev Revert with an error when providing a criteria resolver that refers\n * to an order that has not been supplied.\n */\n error OrderCriteriaResolverOutOfRange();\n\n /**\n * @dev Revert with an error if an offer item still has unresolved criteria\n * after applying all criteria resolvers.\n */\n error UnresolvedOfferCriteria();\n\n /**\n * @dev Revert with an error if a consideration item still has unresolved\n * criteria after applying all criteria resolvers.\n */\n error UnresolvedConsiderationCriteria();\n\n /**\n * @dev Revert with an error when providing a criteria resolver that refers\n * to an order with an offer item that has not been supplied.\n */\n error OfferCriteriaResolverOutOfRange();\n\n /**\n * @dev Revert with an error when providing a criteria resolver that refers\n * to an order with a consideration item that has not been supplied.\n */\n error ConsiderationCriteriaResolverOutOfRange();\n\n /**\n * @dev Revert with an error when providing a criteria resolver that refers\n * to an order with an item that does not expect a criteria to be\n * resolved.\n */\n error CriteriaNotEnabledForItem();\n\n /**\n * @dev Revert with an error when providing a criteria resolver that\n * contains an invalid proof with respect to the given item and\n * chosen identifier.\n */\n error InvalidProof();\n}\n" - }, - "contracts/test/TestZone.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\nimport { ZoneInterface } from \"seaport/contracts/interfaces/ZoneInterface.sol\";\n\n// prettier-ignore\nimport {\n AdvancedOrder,\n CriteriaResolver\n} from \"seaport/contracts/lib/ConsiderationStructs.sol\";\n\ncontract TestZone is ZoneInterface {\n function isValidOrder(\n bytes32 orderHash,\n address caller,\n address offerer,\n bytes32 zoneHash\n ) external pure override returns (bytes4 validOrderMagicValue) {\n orderHash;\n caller;\n offerer;\n\n if (zoneHash == bytes32(uint256(1))) {\n revert(\"Revert on zone hash 1\");\n } else if (zoneHash == bytes32(uint256(2))) {\n assembly {\n revert(0, 0)\n }\n }\n\n validOrderMagicValue = zoneHash != bytes32(uint256(3))\n ? ZoneInterface.isValidOrder.selector\n : bytes4(0xffffffff);\n }\n\n function isValidOrderIncludingExtraData(\n bytes32 orderHash,\n address caller,\n AdvancedOrder calldata order,\n bytes32[] calldata priorOrderHashes,\n CriteriaResolver[] calldata criteriaResolvers\n ) external pure override returns (bytes4 validOrderMagicValue) {\n orderHash;\n caller;\n order;\n priorOrderHashes;\n criteriaResolvers;\n\n if (order.extraData.length == 4) {\n revert(\"Revert on extraData length 4\");\n } else if (order.extraData.length == 5) {\n assembly {\n revert(0, 0)\n }\n }\n\n validOrderMagicValue = order.parameters.zoneHash != bytes32(uint256(3))\n ? ZoneInterface.isValidOrder.selector\n : bytes4(0xffffffff);\n }\n}\n" - }, - "seaport/contracts/interfaces/ZoneInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// prettier-ignore\nimport {\n AdvancedOrder,\n CriteriaResolver\n} from \"../lib/ConsiderationStructs.sol\";\n\ninterface ZoneInterface {\n // Called by Consideration whenever extraData is not provided by the caller.\n function isValidOrder(\n bytes32 orderHash,\n address caller,\n address offerer,\n bytes32 zoneHash\n ) external view returns (bytes4 validOrderMagicValue);\n\n // Called by Consideration whenever any extraData is provided by the caller.\n function isValidOrderIncludingExtraData(\n bytes32 orderHash,\n address caller,\n AdvancedOrder calldata order,\n bytes32[] calldata priorOrderHashes,\n CriteriaResolver[] calldata criteriaResolvers\n ) external view returns (bytes4 validOrderMagicValue);\n}\n" - }, - "contracts/seaport/Zones/PausableZone.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\nimport { ZoneInterface } from \"seaport/contracts/interfaces/ZoneInterface.sol\";\nimport { ZoneInteractionErrors } from \"seaport/contracts/interfaces/ZoneInteractionErrors.sol\";\n\n// prettier-ignore\nimport {\n PausableZoneEventsAndErrors\n} from \"./PausableZoneEventsAndErrors.sol\";\n\nimport { SeaportInterface } from \"seaport/contracts/interfaces/SeaportInterface.sol\";\n\n// prettier-ignore\nimport {\n AdvancedOrder,\n CriteriaResolver,\n Order,\n OrderComponents,\n Fulfillment,\n Execution\n} from \"seaport/contracts/lib/ConsiderationStructs.sol\";\n\nimport { PausableZoneInterface } from \"./PausableZoneInterface.sol\";\n\n/**\n * @title PausableZone\n * @author cupOJoseph, BCLeFevre, ryanio\n * @notice PausableZone is a simple zone implementation that approves every\n * order. It can be self-destructed by its controller to pause\n * restricted orders that have it set as their zone.\n */\ncontract PausableZone is\n PausableZoneEventsAndErrors,\n ZoneInterface,\n PausableZoneInterface\n{\n // Set an immutable controller that can pause the zone & update an operator.\n address internal immutable _controller;\n\n // Set an operator that can instruct the zone to cancel or execute orders.\n address public operator;\n\n /**\n * @dev Ensure that the caller is either the operator or controller.\n */\n modifier isOperator() {\n // Ensure that the caller is either the operator or the controller.\n if (msg.sender != operator && msg.sender != _controller) {\n revert InvalidOperator();\n }\n\n // Continue with function execution.\n _;\n }\n\n /**\n * @dev Ensure that the caller is the controller.\n */\n modifier isController() {\n // Ensure that the caller is the controller.\n if (msg.sender != _controller) {\n revert InvalidController();\n }\n\n // Continue with function execution.\n _;\n }\n\n /**\n * @notice Set the deployer as the controller of the zone.\n */\n constructor() {\n // Set the controller to the deployer.\n _controller = msg.sender;\n\n // Emit an event signifying that the zone is unpaused.\n emit Unpaused();\n }\n\n /**\n * @notice Cancel an arbitrary number of orders that have agreed to use the\n * contract as their zone.\n *\n * @param seaport The Seaport address.\n * @param orders The orders to cancel.\n *\n * @return cancelled A boolean indicating whether the supplied orders have\n * been successfully cancelled.\n */\n function cancelOrders(\n SeaportInterface seaport,\n OrderComponents[] calldata orders\n ) external override isOperator returns (bool cancelled) {\n // Call cancel on Seaport and return its boolean value.\n cancelled = seaport.cancel(orders);\n }\n\n /**\n * @notice Pause this contract, safely stopping orders from using\n * the contract as a zone. Restricted orders with this address as a\n * zone will not be fulfillable unless the zone is redeployed to the\n * same address.\n */\n function pause(address payee) external override isController {\n // Emit an event signifying that the zone is paused.\n emit Paused();\n\n // Destroy the zone, sending any ether to the transaction submitter.\n selfdestruct(payable(payee));\n }\n\n /**\n * @notice Assign the given address with the ability to operate the zone.\n *\n * @param operatorToAssign The address to assign as the operator.\n */\n function assignOperator(address operatorToAssign)\n external\n override\n isController\n {\n // Ensure the operator being assigned is not the null address.\n if (operatorToAssign == address(0)) {\n revert PauserCanNotBeSetAsZero();\n }\n\n // Set the given address as the new operator.\n operator = operatorToAssign;\n\n // Emit an event indicating the operator has been updated.\n emit OperatorUpdated(operator);\n }\n\n /**\n * @notice Execute an arbitrary number of matched orders, each with\n * an arbitrary number of items for offer and consideration\n * along with a set of fulfillments allocating offer components\n * to consideration components.\n *\n * @param seaport The Seaport address.\n * @param orders The orders to match.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchOrders(\n SeaportInterface seaport,\n Order[] calldata orders,\n Fulfillment[] calldata fulfillments\n )\n external\n payable\n override\n isOperator\n returns (Execution[] memory executions)\n {\n // Call matchOrders on Seaport and return the sequence of transfers\n // performed as part of matching the given orders.\n executions = seaport.matchOrders{ value: msg.value }(\n orders,\n fulfillments\n );\n }\n\n /**\n * @notice Execute an arbitrary number of matched advanced orders,\n * each with an arbitrary number of items for offer and\n * consideration along with a set of fulfillments allocating\n * offer components to consideration components.\n *\n * @param seaport The Seaport address.\n * @param orders The orders to match.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific order as well as that order's\n * offer or consideration, a token identifier, and\n * a proof that the supplied token identifier is\n * contained in the order's merkle root.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchAdvancedOrders(\n SeaportInterface seaport,\n AdvancedOrder[] calldata orders,\n CriteriaResolver[] calldata criteriaResolvers,\n Fulfillment[] calldata fulfillments\n )\n external\n payable\n override\n isOperator\n returns (Execution[] memory executions)\n {\n // Call matchAdvancedOrders on Seaport and return the sequence of\n // transfers performed as part of matching the given orders.\n executions = seaport.matchAdvancedOrders{ value: msg.value }(\n orders,\n criteriaResolvers,\n fulfillments\n );\n }\n\n /**\n * @notice Check if a given order is currently valid.\n *\n * @dev This function is called by Seaport whenever extraData is not\n * provided by the caller.\n *\n * @param orderHash The hash of the order.\n * @param caller The caller in question.\n * @param offerer The offerer in question.\n * @param zoneHash The hash to provide upon calling the zone.\n *\n * @return validOrderMagicValue A magic value indicating if the order is\n * currently valid.\n */\n function isValidOrder(\n bytes32 orderHash,\n address caller,\n address offerer,\n bytes32 zoneHash\n ) external pure override returns (bytes4 validOrderMagicValue) {\n orderHash;\n caller;\n offerer;\n zoneHash;\n\n // Return the selector of isValidOrder as the magic value.\n validOrderMagicValue = ZoneInterface.isValidOrder.selector;\n }\n\n /**\n * @notice Check if a given order including extraData is currently valid.\n *\n * @dev This function is called by Seaport whenever any extraData is\n * provided by the caller.\n *\n * @param orderHash The hash of the order.\n * @param caller The caller in question.\n * @param order The order in question.\n * @param priorOrderHashes The order hashes of each order supplied prior to\n * the current order as part of a \"match\" variety\n * of order fulfillment.\n * @param criteriaResolvers The criteria resolvers corresponding to\n * the order.\n *\n * @return validOrderMagicValue A magic value indicating if the order is\n * currently valid.\n */\n function isValidOrderIncludingExtraData(\n bytes32 orderHash,\n address caller,\n AdvancedOrder calldata order,\n bytes32[] calldata priorOrderHashes,\n CriteriaResolver[] calldata criteriaResolvers\n ) external pure override returns (bytes4 validOrderMagicValue) {\n orderHash;\n caller;\n order;\n priorOrderHashes;\n criteriaResolvers;\n\n // Return the selector of isValidOrder as the magic value.\n validOrderMagicValue = ZoneInterface.isValidOrder.selector;\n }\n}\n" - }, - "seaport/contracts/interfaces/ZoneInteractionErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/**\n * @title ZoneInteractionErrors\n * @author 0age\n * @notice ZoneInteractionErrors contains errors related to zone interaction.\n */\ninterface ZoneInteractionErrors {\n /**\n * @dev Revert with an error when attempting to fill an order that specifies\n * a restricted submitter as its order type when not submitted by\n * either the offerer or the order's zone or approved as valid by the\n * zone in question via a staticcall to `isValidOrder`.\n *\n * @param orderHash The order hash for the invalid restricted order.\n */\n error InvalidRestrictedOrder(bytes32 orderHash);\n}\n" - }, - "contracts/seaport/Zones/PausableZoneEventsAndErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\n/**\n * @notice PausableZoneEventsAndErrors contains errors and events\n * related to zone interaction.\n */\ninterface PausableZoneEventsAndErrors {\n /**\n * @dev Emit an event whenever a zone is successfully paused.\n */\n event Paused();\n\n /**\n * @dev Emit an event whenever a zone is successfully unpaused (created).\n */\n event Unpaused();\n\n /**\n * @dev Emit an event whenever a zone owner registers a new potential\n * owner for that zone.\n *\n * @param newPotentialOwner The new potential owner of the zone.\n */\n event PotentialOwnerUpdated(address newPotentialOwner);\n\n /**\n * @dev Emit an event whenever zone ownership is transferred.\n *\n * @param previousOwner The previous owner of the zone.\n * @param newOwner The new owner of the zone.\n */\n event OwnershipTransferred(address previousOwner, address newOwner);\n\n /**\n * @dev Emit an event whenever a new zone is created.\n *\n * @param zone The address of the zone.\n * @param salt The salt used to deploy the zone.\n */\n event ZoneCreated(address zone, bytes32 salt);\n\n /**\n * @dev Emit an event whenever a zone owner assigns a new pauser\n *\n * @param newPauser The new pausear of the zone.\n */\n event PauserUpdated(address newPauser);\n\n /**\n * @dev Emit an event whenever a zone owner assigns a new operator\n *\n * @param newOperator The new operator of the zone.\n */\n event OperatorUpdated(address newOperator);\n\n /**\n * @dev Revert with an error when attempting to pause the zone\n * while the caller is not the owner or pauser of the zone.\n */\n error InvalidPauser();\n\n /**\n * @dev Revert with an error when attempting to call an operation\n * while the caller is not the controller or operator of the zone.\n */\n error InvalidOperator();\n\n /**\n * @dev Revert with an error when attempting to pause the zone or update the\n * operator while the caller is not the controller of the zone.\n */\n error InvalidController();\n /**\n * @dev Revert with an error when attempting to deploy a zone that is\n * currently deployed.\n */\n error ZoneAlreadyExists(address zone);\n\n /**\n * @dev Revert with an error when the caller does not have the _owner role\n *\n */\n error CallerIsNotOwner();\n\n /**\n * @dev Revert with an error when the caller does not have the operator role\n *\n */\n error CallerIsNotOperator();\n\n /**\n * @dev Revert with an error when attempting to set the new potential owner\n * as the 0 address.\n *\n */\n error OwnerCanNotBeSetAsZero();\n\n /**\n * @dev Revert with an error when attempting to set the new potential pauser\n * as the 0 address.\n *\n */\n error PauserCanNotBeSetAsZero();\n\n /**\n * @dev Revert with an error when the caller does not have\n * the potentialOwner role.\n */\n error CallerIsNotPotentialOwner();\n}\n" - }, - "seaport/contracts/interfaces/SeaportInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// prettier-ignore\nimport {\n BasicOrderParameters,\n OrderComponents,\n Fulfillment,\n FulfillmentComponent,\n Execution,\n Order,\n AdvancedOrder,\n OrderStatus,\n CriteriaResolver\n} from \"../lib/ConsiderationStructs.sol\";\n\n/**\n * @title SeaportInterface\n * @author 0age\n * @custom:version 1.1\n * @notice Seaport is a generalized ETH/ERC20/ERC721/ERC1155 marketplace. It\n * minimizes external calls to the greatest extent possible and provides\n * lightweight methods for common routes as well as more flexible\n * methods for composing advanced orders.\n *\n * @dev SeaportInterface contains all external function interfaces for Seaport.\n */\ninterface SeaportInterface {\n /**\n * @notice Fulfill an order offering an ERC721 token by supplying Ether (or\n * the native token for the given chain) as consideration for the\n * order. An arbitrary number of \"additional recipients\" may also be\n * supplied which will each receive native tokens from the fulfiller\n * as consideration.\n *\n * @param parameters Additional information on the fulfilled order. Note\n * that the offerer must first approve this contract (or\n * their preferred conduit if indicated by the order) for\n * their offered ERC721 token to be transferred.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillBasicOrder(BasicOrderParameters calldata parameters)\n external\n payable\n returns (bool fulfilled);\n\n /**\n * @notice Fulfill an order with an arbitrary number of items for offer and\n * consideration. Note that this function does not support\n * criteria-based orders or partial filling of orders (though\n * filling the remainder of a partially-filled order is supported).\n *\n * @param order The order to fulfill. Note that both the\n * offerer and the fulfiller must first approve\n * this contract (or the corresponding conduit if\n * indicated) to transfer any relevant tokens on\n * their behalf and that contracts must implement\n * `onERC1155Received` to receive ERC1155 tokens\n * as consideration.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used, with direct approvals set on\n * Seaport.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillOrder(Order calldata order, bytes32 fulfillerConduitKey)\n external\n payable\n returns (bool fulfilled);\n\n /**\n * @notice Fill an order, fully or partially, with an arbitrary number of\n * items for offer and consideration alongside criteria resolvers\n * containing specific token identifiers and associated proofs.\n *\n * @param advancedOrder The order to fulfill along with the fraction\n * of the order to attempt to fill. Note that\n * both the offerer and the fulfiller must first\n * approve this contract (or their preferred\n * conduit if indicated by the order) to transfer\n * any relevant tokens on their behalf and that\n * contracts must implement `onERC1155Received`\n * to receive ERC1155 tokens as consideration.\n * Also note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount with\n * the supplied fraction for the partial fill to\n * be considered valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a proof\n * that the supplied token identifier is\n * contained in the merkle root held by the item\n * in question's criteria element. Note that an\n * empty criteria indicates that any\n * (transferable) token identifier on the token\n * in question is valid and that no associated\n * proof needs to be supplied.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used, with direct approvals set on\n * Seaport.\n * @param recipient The intended recipient for all received items,\n * with `address(0)` indicating that the caller\n * should receive the items.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillAdvancedOrder(\n AdvancedOrder calldata advancedOrder,\n CriteriaResolver[] calldata criteriaResolvers,\n bytes32 fulfillerConduitKey,\n address recipient\n ) external payable returns (bool fulfilled);\n\n /**\n * @notice Attempt to fill a group of orders, each with an arbitrary number\n * of items for offer and consideration. Any order that is not\n * currently active, has already been fully filled, or has been\n * cancelled will be omitted. Remaining offer and consideration\n * items will then be aggregated where possible as indicated by the\n * supplied offer and consideration component arrays and aggregated\n * items will be transferred to the fulfiller or to each intended\n * recipient, respectively. Note that a failing item transfer or an\n * issue with order formatting will cause the entire batch to fail.\n * Note that this function does not support criteria-based orders or\n * partial filling of orders (though filling the remainder of a\n * partially-filled order is supported).\n *\n * @param orders The orders to fulfill. Note that both\n * the offerer and the fulfiller must first\n * approve this contract (or the\n * corresponding conduit if indicated) to\n * transfer any relevant tokens on their\n * behalf and that contracts must implement\n * `onERC1155Received` to receive ERC1155\n * tokens as consideration.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used, with\n * direct approvals set on this contract.\n * @param maximumFulfilled The maximum number of orders to fulfill.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function fulfillAvailableOrders(\n Order[] calldata orders,\n FulfillmentComponent[][] calldata offerFulfillments,\n FulfillmentComponent[][] calldata considerationFulfillments,\n bytes32 fulfillerConduitKey,\n uint256 maximumFulfilled\n )\n external\n payable\n returns (bool[] memory availableOrders, Execution[] memory executions);\n\n /**\n * @notice Attempt to fill a group of orders, fully or partially, with an\n * arbitrary number of items for offer and consideration per order\n * alongside criteria resolvers containing specific token\n * identifiers and associated proofs. Any order that is not\n * currently active, has already been fully filled, or has been\n * cancelled will be omitted. Remaining offer and consideration\n * items will then be aggregated where possible as indicated by the\n * supplied offer and consideration component arrays and aggregated\n * items will be transferred to the fulfiller or to each intended\n * recipient, respectively. Note that a failing item transfer or an\n * issue with order formatting will cause the entire batch to fail.\n *\n * @param advancedOrders The orders to fulfill along with the\n * fraction of those orders to attempt to\n * fill. Note that both the offerer and the\n * fulfiller must first approve this\n * contract (or their preferred conduit if\n * indicated by the order) to transfer any\n * relevant tokens on their behalf and that\n * contracts must implement\n * `onERC1155Received` to enable receipt of\n * ERC1155 tokens as consideration. Also\n * note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount\n * with the supplied fraction for an\n * order's partial fill amount to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a\n * proof that the supplied token identifier\n * is contained in the merkle root held by\n * the item in question's criteria element.\n * Note that an empty criteria indicates\n * that any (transferable) token\n * identifier on the token in question is\n * valid and that no associated proof needs\n * to be supplied.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used, with\n * direct approvals set on this contract.\n * @param recipient The intended recipient for all received\n * items, with `address(0)` indicating that\n * the caller should receive the items.\n * @param maximumFulfilled The maximum number of orders to fulfill.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function fulfillAvailableAdvancedOrders(\n AdvancedOrder[] calldata advancedOrders,\n CriteriaResolver[] calldata criteriaResolvers,\n FulfillmentComponent[][] calldata offerFulfillments,\n FulfillmentComponent[][] calldata considerationFulfillments,\n bytes32 fulfillerConduitKey,\n address recipient,\n uint256 maximumFulfilled\n )\n external\n payable\n returns (bool[] memory availableOrders, Execution[] memory executions);\n\n /**\n * @notice Match an arbitrary number of orders, each with an arbitrary\n * number of items for offer and consideration along with as set of\n * fulfillments allocating offer components to consideration\n * components. Note that this function does not support\n * criteria-based or partial filling of orders (though filling the\n * remainder of a partially-filled order is supported).\n *\n * @param orders The orders to match. Note that both the offerer and\n * fulfiller on each order must first approve this\n * contract (or their conduit if indicated by the order)\n * to transfer any relevant tokens on their behalf and\n * each consideration recipient must implement\n * `onERC1155Received` to enable ERC1155 token receipt.\n * @param fulfillments An array of elements allocating offer components to\n * consideration components. Note that each\n * consideration component must be fully met for the\n * match operation to be valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function matchOrders(\n Order[] calldata orders,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Match an arbitrary number of full or partial orders, each with an\n * arbitrary number of items for offer and consideration, supplying\n * criteria resolvers containing specific token identifiers and\n * associated proofs as well as fulfillments allocating offer\n * components to consideration components.\n *\n * @param orders The advanced orders to match. Note that both the\n * offerer and fulfiller on each order must first\n * approve this contract (or a preferred conduit if\n * indicated by the order) to transfer any relevant\n * tokens on their behalf and each consideration\n * recipient must implement `onERC1155Received` in\n * order to receive ERC1155 tokens. Also note that\n * the offer and consideration components for each\n * order must have no remainder after multiplying\n * the respective amount with the supplied fraction\n * in order for the group of partial fills to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific order as well as that order's\n * offer or consideration, a token identifier, and\n * a proof that the supplied token identifier is\n * contained in the order's merkle root. Note that\n * an empty root indicates that any (transferable)\n * token identifier is valid and that no associated\n * proof needs to be supplied.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components. Note that each\n * consideration component must be fully met in\n * order for the match operation to be valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function matchAdvancedOrders(\n AdvancedOrder[] calldata orders,\n CriteriaResolver[] calldata criteriaResolvers,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Cancel an arbitrary number of orders. Note that only the offerer\n * or the zone of a given order may cancel it. Callers should ensure\n * that the intended order was cancelled by calling `getOrderStatus`\n * and confirming that `isCancelled` returns `true`.\n *\n * @param orders The orders to cancel.\n *\n * @return cancelled A boolean indicating whether the supplied orders have\n * been successfully cancelled.\n */\n function cancel(OrderComponents[] calldata orders)\n external\n returns (bool cancelled);\n\n /**\n * @notice Validate an arbitrary number of orders, thereby registering their\n * signatures as valid and allowing the fulfiller to skip signature\n * verification on fulfillment. Note that validated orders may still\n * be unfulfillable due to invalid item amounts or other factors;\n * callers should determine whether validated orders are fulfillable\n * by simulating the fulfillment call prior to execution. Also note\n * that anyone can validate a signed order, but only the offerer can\n * validate an order without supplying a signature.\n *\n * @param orders The orders to validate.\n *\n * @return validated A boolean indicating whether the supplied orders have\n * been successfully validated.\n */\n function validate(Order[] calldata orders)\n external\n returns (bool validated);\n\n /**\n * @notice Cancel all orders from a given offerer with a given zone in bulk\n * by incrementing a counter. Note that only the offerer may\n * increment the counter.\n *\n * @return newCounter The new counter.\n */\n function incrementCounter() external returns (uint256 newCounter);\n\n /**\n * @notice Retrieve the order hash for a given order.\n *\n * @param order The components of the order.\n *\n * @return orderHash The order hash.\n */\n function getOrderHash(OrderComponents calldata order)\n external\n view\n returns (bytes32 orderHash);\n\n /**\n * @notice Retrieve the status of a given order by hash, including whether\n * the order has been cancelled or validated and the fraction of the\n * order that has been filled.\n *\n * @param orderHash The order hash in question.\n *\n * @return isValidated A boolean indicating whether the order in question\n * has been validated (i.e. previously approved or\n * partially filled).\n * @return isCancelled A boolean indicating whether the order in question\n * has been cancelled.\n * @return totalFilled The total portion of the order that has been filled\n * (i.e. the \"numerator\").\n * @return totalSize The total size of the order that is either filled or\n * unfilled (i.e. the \"denominator\").\n */\n function getOrderStatus(bytes32 orderHash)\n external\n view\n returns (\n bool isValidated,\n bool isCancelled,\n uint256 totalFilled,\n uint256 totalSize\n );\n\n /**\n * @notice Retrieve the current counter for a given offerer.\n *\n * @param offerer The offerer in question.\n *\n * @return counter The current counter.\n */\n function getCounter(address offerer)\n external\n view\n returns (uint256 counter);\n\n /**\n * @notice Retrieve configuration information for this contract.\n *\n * @return version The contract version.\n * @return domainSeparator The domain separator for this contract.\n * @return conduitController The conduit Controller set for this contract.\n */\n function information()\n external\n view\n returns (\n string memory version,\n bytes32 domainSeparator,\n address conduitController\n );\n\n /**\n * @notice Retrieve the name of this contract.\n *\n * @return contractName The name of this contract.\n */\n function name() external view returns (string memory contractName);\n}\n" - }, - "contracts/seaport/Zones/PausableZoneInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\nimport { SeaportInterface } from \"seaport/contracts/interfaces/SeaportInterface.sol\";\n\n// prettier-ignore\nimport {\n AdvancedOrder,\n CriteriaResolver,\n Order,\n OrderComponents,\n Fulfillment,\n Execution\n} from \"seaport/contracts/lib/ConsiderationStructs.sol\";\n\n/**\n * @title PausableZone\n * @author cupOJoseph, BCLeFevre, ryanio\n * @notice PausableZone is a simple zone implementation that approves every\n * order. It can be self-destructed by its controller to pause\n * restricted orders that have it set as their zone.\n */\ninterface PausableZoneInterface {\n /**\n * @notice Cancel an arbitrary number of orders that have agreed to use the\n * contract as their zone.\n *\n * @param seaport The Seaport address.\n * @param orders The orders to cancel.\n *\n * @return cancelled A boolean indicating whether the supplied orders have\n * been successfully cancelled.\n */\n function cancelOrders(\n SeaportInterface seaport,\n OrderComponents[] calldata orders\n ) external returns (bool cancelled);\n\n /**\n * @notice Execute an arbitrary number of matched orders, each with\n * an arbitrary number of items for offer and consideration\n * along with a set of fulfillments allocating offer components\n * to consideration components.\n *\n * @param seaport The Seaport address.\n * @param orders The orders to match.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchOrders(\n SeaportInterface seaport,\n Order[] calldata orders,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Execute an arbitrary number of matched advanced orders,\n * each with an arbitrary number of items for offer and\n * consideration along with a set of fulfillments allocating\n * offer components to consideration components.\n *\n * @param seaport The Seaport address.\n * @param orders The orders to match.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific order as well as that order's\n * offer or consideration, a token identifier, and\n * a proof that the supplied token identifier is\n * contained in the order's merkle root.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchAdvancedOrders(\n SeaportInterface seaport,\n AdvancedOrder[] calldata orders,\n CriteriaResolver[] calldata criteriaResolvers,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Pause this contract, safely stopping orders from using\n * the contract as a zone. Restricted orders with this address as a\n * zone will not be fulfillable unless the zone is redeployed to the\n * same address.\n */\n function pause(address payee) external;\n\n /**\n * @notice Assign the given address with the ability to operate the zone.\n *\n * @param operatorToAssign The address to assign as the operator.\n */\n function assignOperator(address operatorToAssign) external;\n}\n" - }, - "contracts/seaport/Zones/PausableZoneControllerInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\nimport { PausableZone } from \"./PausableZone.sol\";\n\n// prettier-ignore\nimport {\n PausableZoneEventsAndErrors\n} from \"./PausableZoneEventsAndErrors.sol\";\n\n// prettier-ignore\nimport {\n Order,\n Fulfillment,\n OrderComponents,\n AdvancedOrder,\n CriteriaResolver,\n Execution\n} from \"seaport/contracts/lib/ConsiderationStructs.sol\";\n\nimport { SeaportInterface } from \"seaport/contracts/interfaces/SeaportInterface.sol\";\n\n/**\n * @title PausableZoneController\n * @author cupOJoseph, BCLeFevre, stuckinaboot\n * @notice PausableZoneController enables deploying, pausing and executing\n * orders on PausableZones. This deployer is designed to be owned\n * by a gnosis safe, DAO, or trusted party.\n */\ninterface PausableZoneControllerInterface {\n /**\n * @notice Deploy a PausableZone to a precomputed address.\n *\n * @param salt The salt to be used to derive the zone address\n *\n * @return derivedAddress The derived address for the zone.\n */\n function createZone(bytes32 salt) external returns (address derivedAddress);\n\n /**\n * @notice Pause orders on a given zone.\n *\n * @param zone The address of the zone to be paused.\n *\n * @return success A boolean indicating the zone has been paused.\n */\n function pause(address zone) external returns (bool success);\n\n /**\n * @notice Cancel Seaport offers on a given zone.\n *\n * @param pausableZoneAddress The zone that manages the orders to be\n * cancelled.\n * @param seaportAddress The Seaport address.\n * @param orders The orders to cancel.\n */\n function cancelOrders(\n address pausableZoneAddress,\n SeaportInterface seaportAddress,\n OrderComponents[] calldata orders\n ) external;\n\n /**\n * @notice Execute an arbitrary number of matched orders on a given zone.\n *\n * @param pausableZoneAddress The zone that manages the orders to be\n * cancelled.\n * @param seaportAddress The Seaport address.\n * @param orders The orders to match.\n * @param fulfillments An array of elements allocating offer\n * components to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchOrders(\n address pausableZoneAddress,\n SeaportInterface seaportAddress,\n Order[] calldata orders,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Execute an arbitrary number of matched advanced orders on a\n * given zone.\n *\n * @param pausableZoneAddress The zone that manages the orders to be\n * cancelled.\n * @param seaportAddress The Seaport address.\n * @param orders The orders to match.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific order as well as\n * that order's offer or consideration,\n * a token identifier, and a proof that\n * the supplied token identifier is\n * contained in the order's merkle root.\n * @param fulfillments An array of elements allocating offer\n * components to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchAdvancedOrders(\n address pausableZoneAddress,\n SeaportInterface seaportAddress,\n AdvancedOrder[] calldata orders,\n CriteriaResolver[] calldata criteriaResolvers,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Initiate Zone ownership transfer by assigning a new potential\n * owner this contract. Once set, the new potential owner\n * may call `acceptOwnership` to claim ownership.\n * Only the owner in question may call this function.\n *\n * @param newPotentialOwner The address for which to initiate ownership\n * transfer to.\n */\n function transferOwnership(address newPotentialOwner) external;\n\n /**\n * @notice Clear the currently set potential owner, if any.\n * Only the owner of this contract may call this function.\n */\n function cancelOwnershipTransfer() external;\n\n /**\n * @notice Accept ownership of this contract. Only the account that the\n * current owner has set as the new potential owner may call this\n * function.\n */\n function acceptOwnership() external;\n\n /**\n * @notice Assign the given address with the ability to pause the zone.\n *\n * @param pauserToAssign The address to assign the pauser role.\n */\n function assignPauser(address pauserToAssign) external;\n\n /**\n * @notice Assign the given address with the ability to operate the\n * given zone.\n *\n * @param pausableZoneAddress The zone address to assign operator role.\n * @param operatorToAssign The address to assign as operator.\n */\n function assignOperator(\n address pausableZoneAddress,\n address operatorToAssign\n ) external;\n\n /**\n * @notice An external view function that returns the owner.\n *\n * @return The address of the owner.\n */\n function owner() external view returns (address);\n\n /**\n * @notice An external view function that return the potential owner.\n *\n * @return The address of the potential owner.\n */\n function potentialOwner() external view returns (address);\n\n /**\n * @notice An external view function that returns the pauser.\n *\n * @return The address of the pauser.\n */\n function pauser() external view returns (address);\n}\n" - }, - "contracts/seaport/Zones/PausableZoneController.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.7;\n\nimport { PausableZone } from \"./PausableZone.sol\";\n\n// prettier-ignore\nimport {\n PausableZoneControllerInterface\n} from \"./PausableZoneControllerInterface.sol\";\n\n// prettier-ignore\nimport {\n PausableZoneEventsAndErrors\n} from \"./PausableZoneEventsAndErrors.sol\";\n\n// prettier-ignore\nimport {\n Order,\n Fulfillment,\n OrderComponents,\n AdvancedOrder,\n CriteriaResolver,\n Execution\n} from \"seaport/contracts/lib/ConsiderationStructs.sol\";\n\nimport { SeaportInterface } from \"seaport/contracts/interfaces/SeaportInterface.sol\";\n\n/**\n * @title PausableZoneController\n * @author cupOJoseph, BCLeFevre, stuckinaboot, stephankmin\n * @notice PausableZoneController enables deploying, pausing and executing\n * orders on PausableZones. This deployer is designed to be owned\n * by a gnosis safe, DAO, or trusted party.\n */\ncontract PausableZoneController is\n PausableZoneControllerInterface,\n PausableZoneEventsAndErrors\n{\n // Set the owner that can deploy, pause and execute orders on PausableZones.\n address internal _owner;\n\n // Set the address of the new potential owner of the zone.\n address private _potentialOwner;\n\n // Set the address with the ability to pause the zone.\n address internal _pauser;\n\n // Set the immutable zone creation code hash.\n bytes32 public immutable zoneCreationCode;\n\n /**\n * @dev Throws if called by any account other than the owner or pauser.\n */\n modifier isPauser() {\n if (msg.sender != _pauser && msg.sender != _owner) {\n revert InvalidPauser();\n }\n _;\n }\n\n /**\n * @notice Set the owner of the controller and store\n * the zone creation code.\n *\n * @param ownerAddress The deployer to be set as the owner.\n */\n constructor(address ownerAddress) {\n // Set the owner address as the owner.\n _owner = ownerAddress;\n\n // Hash and store the zone creation code.\n zoneCreationCode = keccak256(type(PausableZone).creationCode);\n }\n\n /**\n * @notice Deploy a PausableZone to a precomputed address.\n *\n * @param salt The salt to be used to derive the zone address\n *\n * @return derivedAddress The derived address for the zone.\n */\n function createZone(bytes32 salt)\n external\n override\n returns (address derivedAddress)\n {\n // Ensure the caller is the owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n\n // Derive the PausableZone address.\n // This expression demonstrates address computation but is not required.\n derivedAddress = address(\n uint160(\n uint256(\n keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(this),\n salt,\n zoneCreationCode\n )\n )\n )\n )\n );\n\n // Revert if a zone is currently deployed to the derived address.\n if (derivedAddress.code.length != 0) {\n revert ZoneAlreadyExists(derivedAddress);\n }\n\n // Deploy the zone using the supplied salt.\n new PausableZone{ salt: salt }();\n\n // Emit an event signifying that the zone was created.\n emit ZoneCreated(derivedAddress, salt);\n }\n\n /**\n * @notice Pause orders on a given zone.\n *\n * @param zone The address of the zone to be paused.\n *\n * @return success A boolean indicating the zone has been paused.\n */\n function pause(address zone)\n external\n override\n isPauser\n returns (bool success)\n {\n // Call pause on the given zone.\n PausableZone(zone).pause(msg.sender);\n\n // Return a boolean indicating the pause was successful.\n success = true;\n }\n\n /**\n * @notice Cancel Seaport orders on a given zone.\n *\n * @param pausableZoneAddress The zone that manages the\n * orders to be cancelled.\n * @param seaportAddress The Seaport address.\n * @param orders The orders to cancel.\n */\n function cancelOrders(\n address pausableZoneAddress,\n SeaportInterface seaportAddress,\n OrderComponents[] calldata orders\n ) external override {\n // Ensure the caller is the owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n\n // Create a zone object from the zone address.\n PausableZone zone = PausableZone(pausableZoneAddress);\n\n // Call cancelOrders on the given zone.\n zone.cancelOrders(seaportAddress, orders);\n }\n\n /**\n * @notice Execute an arbitrary number of matched orders on a given zone.\n *\n * @param pausableZoneAddress The zone that manages the orders\n * to be cancelled.\n * @param seaportAddress The Seaport address.\n * @param orders The orders to match.\n * @param fulfillments An array of elements allocating offer\n * components to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchOrders(\n address pausableZoneAddress,\n SeaportInterface seaportAddress,\n Order[] calldata orders,\n Fulfillment[] calldata fulfillments\n ) external payable override returns (Execution[] memory executions) {\n // Ensure the caller is the owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n\n // Create a zone object from the zone address.\n PausableZone zone = PausableZone(pausableZoneAddress);\n\n // Call executeMatchOrders on the given zone and return the sequence\n // of transfers performed as part of matching the given orders.\n executions = zone.executeMatchOrders{ value: msg.value }(\n seaportAddress,\n orders,\n fulfillments\n );\n }\n\n /**\n * @notice Execute an arbitrary number of matched advanced orders on a given\n * zone.\n *\n * @param pausableZoneAddress The zone that manages the orders to be\n * cancelled.\n * @param seaportAddress The Seaport address.\n * @param orders The orders to match.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific order as well as that\n * order's offer or consideration, a token\n * identifier, and a proof that the supplied\n * token identifier is contained in the\n * order's merkle root.\n * @param fulfillments An array of elements allocating offer\n * components to consideration components.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function executeMatchAdvancedOrders(\n address pausableZoneAddress,\n SeaportInterface seaportAddress,\n AdvancedOrder[] calldata orders,\n CriteriaResolver[] calldata criteriaResolvers,\n Fulfillment[] calldata fulfillments\n ) external payable override returns (Execution[] memory executions) {\n // Ensure the caller is the owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n\n // Create a zone object from the zone address.\n PausableZone zone = PausableZone(pausableZoneAddress);\n\n // Call executeMatchOrders on the given zone and return the sequence\n // of transfers performed as part of matching the given orders.\n executions = zone.executeMatchAdvancedOrders{ value: msg.value }(\n seaportAddress,\n orders,\n criteriaResolvers,\n fulfillments\n );\n }\n\n /**\n * @notice Initiate Zone ownership transfer by assigning a new potential\n * owner this contract. Once set, the new potential owner\n * may call `acceptOwnership` to claim ownership.\n * Only the owner in question may call this function.\n *\n * @param newPotentialOwner The address for which to initiate ownership\n * transfer to.\n */\n function transferOwnership(address newPotentialOwner) external override {\n // Ensure the caller is the owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n // Ensure the new potential owner is not an invalid address.\n if (newPotentialOwner == address(0)) {\n revert OwnerCanNotBeSetAsZero();\n }\n\n // Emit an event indicating that the potential owner has been updated.\n emit PotentialOwnerUpdated(newPotentialOwner);\n\n // Set the new potential owner as the potential owner.\n _potentialOwner = newPotentialOwner;\n }\n\n /**\n * @notice Clear the currently set potential owner, if any.\n * Only the owner of this contract may call this function.\n */\n function cancelOwnershipTransfer() external override {\n // Ensure the caller is the current owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n\n // Emit an event indicating that the potential owner has been cleared.\n emit PotentialOwnerUpdated(address(0));\n\n // Clear the current new potential owner.\n delete _potentialOwner;\n }\n\n /**\n * @notice Accept ownership of this contract. Only the account that the\n * current owner has set as the new potential owner may call this\n * function.\n */\n function acceptOwnership() external override {\n // Ensure the caller is the potential owner.\n if (msg.sender != _potentialOwner) {\n revert CallerIsNotPotentialOwner();\n }\n\n // Emit an event indicating that the potential owner has been cleared.\n emit PotentialOwnerUpdated(address(0));\n\n // Clear the current new potential owner\n delete _potentialOwner;\n\n // Emit an event indicating ownership has been transferred.\n emit OwnershipTransferred(_owner, msg.sender);\n\n // Set the caller as the owner of this contract.\n _owner = msg.sender;\n }\n\n /**\n * @notice Assign the given address with the ability to pause the zone.\n *\n * @param pauserToAssign The address to assign the pauser role.\n */\n function assignPauser(address pauserToAssign) external override {\n // Ensure the caller is the owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n // Ensure the pauser to assign is not an invalid address.\n if (pauserToAssign == address(0)) {\n revert PauserCanNotBeSetAsZero();\n }\n\n // Set the given account as the pauser.\n _pauser = pauserToAssign;\n\n // Emit an event indicating the pauser has been assigned.\n emit PauserUpdated(_pauser);\n }\n\n /**\n * @notice Assign the given address with the ability to operate the\n * given zone.\n *\n * @param pausableZoneAddress The zone address to assign operator role.\n * @param operatorToAssign The address to assign as operator.\n */\n function assignOperator(\n address pausableZoneAddress,\n address operatorToAssign\n ) external override {\n // Ensure the caller is the owner.\n if (msg.sender != _owner) {\n revert CallerIsNotOwner();\n }\n // Create a zone object from the zone address.\n PausableZone zone = PausableZone(pausableZoneAddress);\n\n // Call assignOperator on the zone by passing in the given\n // operator address.\n zone.assignOperator(operatorToAssign);\n }\n\n /**\n * @notice An external view function that returns the owner.\n *\n * @return The address of the owner.\n */\n function owner() external view override returns (address) {\n return _owner;\n }\n\n /**\n * @notice An external view function that return the potential owner.\n *\n * @return The address of the potential owner.\n */\n function potentialOwner() external view override returns (address) {\n return _potentialOwner;\n }\n\n /**\n * @notice An external view function that returns the pauser.\n *\n * @return The address of the pauser.\n */\n function pauser() external view override returns (address) {\n return _pauser;\n }\n}\n" - }, - "seaport/contracts/lib/ZoneInteraction.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { ZoneInterface } from \"../interfaces/ZoneInterface.sol\";\n\nimport { OrderType } from \"./ConsiderationEnums.sol\";\n\n// prettier-ignore\nimport { AdvancedOrder, CriteriaResolver } from \"./ConsiderationStructs.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n// prettier-ignore\nimport {\n ZoneInteractionErrors\n} from \"../interfaces/ZoneInteractionErrors.sol\";\n\nimport { LowLevelHelpers } from \"./LowLevelHelpers.sol\";\n\n/**\n * @title ZoneInteraction\n * @author 0age\n * @notice ZoneInteraction contains logic related to interacting with zones.\n */\ncontract ZoneInteraction is ZoneInteractionErrors, LowLevelHelpers {\n /**\n * @dev Internal view function to determine if an order has a restricted\n * order type and, if so, to ensure that either the offerer or the zone\n * are the fulfiller or that a staticcall to `isValidOrder` on the zone\n * returns a magic value indicating that the order is currently valid.\n *\n * @param orderHash The hash of the order.\n * @param zoneHash The hash to provide upon calling the zone.\n * @param orderType The type of the order.\n * @param offerer The offerer in question.\n * @param zone The zone in question.\n */\n function _assertRestrictedBasicOrderValidity(\n bytes32 orderHash,\n bytes32 zoneHash,\n OrderType orderType,\n address offerer,\n address zone\n ) internal view {\n // Order type 2-3 require zone or offerer be caller or zone to approve.\n if (\n uint256(orderType) > 1 &&\n msg.sender != zone &&\n msg.sender != offerer\n ) {\n // Perform minimal staticcall to the zone.\n _callIsValidOrder(zone, orderHash, offerer, zoneHash);\n }\n }\n\n function _callIsValidOrder(\n address zone,\n bytes32 orderHash,\n address offerer,\n bytes32 zoneHash\n ) internal view {\n // Perform minimal staticcall to the zone.\n bool success = _staticcall(\n zone,\n abi.encodeWithSelector(\n ZoneInterface.isValidOrder.selector,\n orderHash,\n msg.sender,\n offerer,\n zoneHash\n )\n );\n\n // Ensure call was successful and returned the correct magic value.\n _assertIsValidOrderStaticcallSuccess(success, orderHash);\n }\n\n /**\n * @dev Internal view function to determine whether an order is a restricted\n * order and, if so, to ensure that it was either submitted by the\n * offerer or the zone for the order, or that the zone returns the\n * expected magic value upon performing a staticcall to `isValidOrder`\n * or `isValidOrderIncludingExtraData` depending on whether the order\n * fulfillment specifies extra data or criteria resolvers.\n *\n * @param advancedOrder The advanced order in question.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific offer or consideration, a token\n * identifier, and a proof that the supplied token\n * identifier is contained in the order's merkle\n * root. Note that a criteria of zero indicates\n * that any (transferable) token identifier is\n * valid and that no proof needs to be supplied.\n * @param priorOrderHashes The order hashes of each order supplied prior to\n * the current order as part of a \"match\" variety\n * of order fulfillment (e.g. this array will be\n * empty for single or \"fulfill available\").\n * @param orderHash The hash of the order.\n * @param zoneHash The hash to provide upon calling the zone.\n * @param orderType The type of the order.\n * @param offerer The offerer in question.\n * @param zone The zone in question.\n */\n function _assertRestrictedAdvancedOrderValidity(\n AdvancedOrder memory advancedOrder,\n CriteriaResolver[] memory criteriaResolvers,\n bytes32[] memory priorOrderHashes,\n bytes32 orderHash,\n bytes32 zoneHash,\n OrderType orderType,\n address offerer,\n address zone\n ) internal view {\n // Order type 2-3 require zone or offerer be caller or zone to approve.\n if (\n uint256(orderType) > 1 &&\n msg.sender != zone &&\n msg.sender != offerer\n ) {\n // If no extraData or criteria resolvers are supplied...\n if (\n advancedOrder.extraData.length == 0 &&\n criteriaResolvers.length == 0\n ) {\n // Perform minimal staticcall to the zone.\n _callIsValidOrder(zone, orderHash, offerer, zoneHash);\n } else {\n // Otherwise, extra data or criteria resolvers were supplied; in\n // that event, perform a more verbose staticcall to the zone.\n bool success = _staticcall(\n zone,\n abi.encodeWithSelector(\n ZoneInterface.isValidOrderIncludingExtraData.selector,\n orderHash,\n msg.sender,\n advancedOrder,\n priorOrderHashes,\n criteriaResolvers\n )\n );\n\n // Ensure call was successful and returned correct magic value.\n _assertIsValidOrderStaticcallSuccess(success, orderHash);\n }\n }\n }\n\n /**\n * @dev Internal view function to ensure that a staticcall to `isValidOrder`\n * or `isValidOrderIncludingExtraData` as part of validating a\n * restricted order that was not submitted by the named offerer or zone\n * was successful and returned the required magic value.\n *\n * @param success A boolean indicating the status of the staticcall.\n * @param orderHash The order hash of the order in question.\n */\n function _assertIsValidOrderStaticcallSuccess(\n bool success,\n bytes32 orderHash\n ) internal view {\n // If the call failed...\n if (!success) {\n // Revert and pass reason along if one was returned.\n _revertWithReasonIfOneIsReturned();\n\n // Otherwise, revert with a generic error message.\n revert InvalidRestrictedOrder(orderHash);\n }\n\n // Ensure result was extracted and matches isValidOrder magic value.\n if (_doesNotMatchMagic(ZoneInterface.isValidOrder.selector)) {\n revert InvalidRestrictedOrder(orderHash);\n }\n }\n}\n" - }, - "seaport/contracts/lib/OrderValidator.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { OrderType } from \"./ConsiderationEnums.sol\";\n\n// prettier-ignore\nimport {\n OrderParameters,\n Order,\n AdvancedOrder,\n OrderComponents,\n OrderStatus,\n CriteriaResolver\n} from \"./ConsiderationStructs.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\nimport { Executor } from \"./Executor.sol\";\n\nimport { ZoneInteraction } from \"./ZoneInteraction.sol\";\n\n/**\n * @title OrderValidator\n * @author 0age\n * @notice OrderValidator contains functionality related to validating orders\n * and updating their status.\n */\ncontract OrderValidator is Executor, ZoneInteraction {\n // Track status of each order (validated, cancelled, and fraction filled).\n mapping(bytes32 => OrderStatus) private _orderStatus;\n\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) Executor(conduitController) {}\n\n /**\n * @dev Internal function to verify and update the status of a basic order.\n *\n * @param orderHash The hash of the order.\n * @param offerer The offerer of the order.\n * @param signature A signature from the offerer indicating that the order\n * has been approved.\n */\n function _validateBasicOrderAndUpdateStatus(\n bytes32 orderHash,\n address offerer,\n bytes memory signature\n ) internal {\n // Retrieve the order status for the given order hash.\n OrderStatus storage orderStatus = _orderStatus[orderHash];\n\n // Ensure order is fillable and is not cancelled.\n _verifyOrderStatus(\n orderHash,\n orderStatus,\n true, // Only allow unused orders when fulfilling basic orders.\n true // Signifies to revert if the order is invalid.\n );\n\n // If the order is not already validated, verify the supplied signature.\n if (!orderStatus.isValidated) {\n _verifySignature(offerer, orderHash, signature);\n }\n\n // Update order status as fully filled, packing struct values.\n orderStatus.isValidated = true;\n orderStatus.isCancelled = false;\n orderStatus.numerator = 1;\n orderStatus.denominator = 1;\n }\n\n /**\n * @dev Internal function to validate an order, determine what portion to\n * fill, and update its status. The desired fill amount is supplied as\n * a fraction, as is the returned amount to fill.\n *\n * @param advancedOrder The order to fulfill as well as the fraction to\n * fill. Note that all offer and consideration\n * amounts must divide with no remainder in order\n * for a partial fill to be valid.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific offer or consideration, a token\n * identifier, and a proof that the supplied token\n * identifier is contained in the order's merkle\n * root. Note that a criteria of zero indicates\n * that any (transferable) token identifier is\n * valid and that no proof needs to be supplied.\n * @param revertOnInvalid A boolean indicating whether to revert if the\n * order is invalid due to the time or status.\n * @param priorOrderHashes The order hashes of each order supplied prior to\n * the current order as part of a \"match\" variety\n * of order fulfillment (e.g. this array will be\n * empty for single or \"fulfill available\").\n *\n * @return orderHash The order hash.\n * @return newNumerator A value indicating the portion of the order that\n * will be filled.\n * @return newDenominator A value indicating the total size of the order.\n */\n function _validateOrderAndUpdateStatus(\n AdvancedOrder memory advancedOrder,\n CriteriaResolver[] memory criteriaResolvers,\n bool revertOnInvalid,\n bytes32[] memory priorOrderHashes\n )\n internal\n returns (\n bytes32 orderHash,\n uint256 newNumerator,\n uint256 newDenominator\n )\n {\n // Retrieve the parameters for the order.\n OrderParameters memory orderParameters = advancedOrder.parameters;\n\n // Ensure current timestamp falls between order start time and end time.\n if (\n !_verifyTime(\n orderParameters.startTime,\n orderParameters.endTime,\n revertOnInvalid\n )\n ) {\n // Assuming an invalid time and no revert, return zeroed out values.\n return (bytes32(0), 0, 0);\n }\n\n // Read numerator and denominator from memory and place on the stack.\n uint256 numerator = uint256(advancedOrder.numerator);\n uint256 denominator = uint256(advancedOrder.denominator);\n\n // Ensure that the supplied numerator and denominator are valid.\n if (numerator > denominator || numerator == 0) {\n revert BadFraction();\n }\n\n // If attempting partial fill (n < d) check order type & ensure support.\n if (\n numerator < denominator &&\n _doesNotSupportPartialFills(orderParameters.orderType)\n ) {\n // Revert if partial fill was attempted on an unsupported order.\n revert PartialFillsNotEnabledForOrder();\n }\n\n // Retrieve current counter & use it w/ parameters to derive order hash.\n orderHash = _assertConsiderationLengthAndGetOrderHash(orderParameters);\n\n // Ensure restricted orders have a valid submitter or pass a zone check.\n _assertRestrictedAdvancedOrderValidity(\n advancedOrder,\n criteriaResolvers,\n priorOrderHashes,\n orderHash,\n orderParameters.zoneHash,\n orderParameters.orderType,\n orderParameters.offerer,\n orderParameters.zone\n );\n\n // Retrieve the order status using the derived order hash.\n OrderStatus storage orderStatus = _orderStatus[orderHash];\n\n // Ensure order is fillable and is not cancelled.\n if (\n !_verifyOrderStatus(\n orderHash,\n orderStatus,\n false, // Allow partially used orders to be filled.\n revertOnInvalid\n )\n ) {\n // Assuming an invalid order status and no revert, return zero fill.\n return (orderHash, 0, 0);\n }\n\n // If the order is not already validated, verify the supplied signature.\n if (!orderStatus.isValidated) {\n _verifySignature(\n orderParameters.offerer,\n orderHash,\n advancedOrder.signature\n );\n }\n\n // Read filled amount as numerator and denominator and put on the stack.\n uint256 filledNumerator = orderStatus.numerator;\n uint256 filledDenominator = orderStatus.denominator;\n\n // If order (orderStatus) currently has a non-zero denominator it is\n // partially filled.\n if (filledDenominator != 0) {\n // If denominator of 1 supplied, fill all remaining amount on order.\n if (denominator == 1) {\n // Scale numerator & denominator to match current denominator.\n numerator = filledDenominator;\n denominator = filledDenominator;\n }\n // Otherwise, if supplied denominator differs from current one...\n else if (filledDenominator != denominator) {\n // scale current numerator by the supplied denominator, then...\n filledNumerator *= denominator;\n\n // the supplied numerator & denominator by current denominator.\n numerator *= filledDenominator;\n denominator *= filledDenominator;\n }\n\n // Once adjusted, if current+supplied numerator exceeds denominator:\n if (filledNumerator + numerator > denominator) {\n // Skip underflow check: denominator >= orderStatus.numerator\n unchecked {\n // Reduce current numerator so it + supplied = denominator.\n numerator = denominator - filledNumerator;\n }\n }\n\n // Increment the filled numerator by the new numerator.\n filledNumerator += numerator;\n\n // Use assembly to ensure fractional amounts are below max uint120.\n assembly {\n // Check filledNumerator and denominator for uint120 overflow.\n if or(\n gt(filledNumerator, MaxUint120),\n gt(denominator, MaxUint120)\n ) {\n // Derive greatest common divisor using euclidean algorithm.\n function gcd(_a, _b) -> out {\n for {\n\n } _b {\n\n } {\n let _c := _b\n _b := mod(_a, _c)\n _a := _c\n }\n out := _a\n }\n let scaleDown := gcd(\n numerator,\n gcd(filledNumerator, denominator)\n )\n\n // Ensure that the divisor is at least one.\n let safeScaleDown := add(scaleDown, iszero(scaleDown))\n\n // Scale all fractional values down by gcd.\n numerator := div(numerator, safeScaleDown)\n filledNumerator := div(filledNumerator, safeScaleDown)\n denominator := div(denominator, safeScaleDown)\n\n // Perform the overflow check a second time.\n if or(\n gt(filledNumerator, MaxUint120),\n gt(denominator, MaxUint120)\n ) {\n // Store the Panic error signature.\n mstore(0, Panic_error_signature)\n\n // Set arithmetic (0x11) panic code as initial argument.\n mstore(Panic_error_offset, Panic_arithmetic)\n\n // Return, supplying Panic signature & arithmetic code.\n revert(0, Panic_error_length)\n }\n }\n }\n // Skip overflow check: checked above unless numerator is reduced.\n unchecked {\n // Update order status and fill amount, packing struct values.\n orderStatus.isValidated = true;\n orderStatus.isCancelled = false;\n orderStatus.numerator = uint120(filledNumerator);\n orderStatus.denominator = uint120(denominator);\n }\n } else {\n // Update order status and fill amount, packing struct values.\n orderStatus.isValidated = true;\n orderStatus.isCancelled = false;\n orderStatus.numerator = uint120(numerator);\n orderStatus.denominator = uint120(denominator);\n }\n\n // Return order hash, a modified numerator, and a modified denominator.\n return (orderHash, numerator, denominator);\n }\n\n /**\n * @dev Internal function to cancel an arbitrary number of orders. Note that\n * only the offerer or the zone of a given order may cancel it. Callers\n * should ensure that the intended order was cancelled by calling\n * `getOrderStatus` and confirming that `isCancelled` returns `true`.\n *\n * @param orders The orders to cancel.\n *\n * @return cancelled A boolean indicating whether the supplied orders were\n * successfully cancelled.\n */\n function _cancel(OrderComponents[] calldata orders)\n internal\n returns (bool cancelled)\n {\n // Ensure that the reentrancy guard is not currently set.\n _assertNonReentrant();\n\n // Declare variables outside of the loop.\n OrderStatus storage orderStatus;\n address offerer;\n address zone;\n\n // Skip overflow check as for loop is indexed starting at zero.\n unchecked {\n // Read length of the orders array from memory and place on stack.\n uint256 totalOrders = orders.length;\n\n // Iterate over each order.\n for (uint256 i = 0; i < totalOrders; ) {\n // Retrieve the order.\n OrderComponents calldata order = orders[i];\n\n offerer = order.offerer;\n zone = order.zone;\n\n // Ensure caller is either offerer or zone of the order.\n if (msg.sender != offerer && msg.sender != zone) {\n revert InvalidCanceller();\n }\n\n // Derive order hash using the order parameters and the counter.\n bytes32 orderHash = _deriveOrderHash(\n OrderParameters(\n offerer,\n zone,\n order.offer,\n order.consideration,\n order.orderType,\n order.startTime,\n order.endTime,\n order.zoneHash,\n order.salt,\n order.conduitKey,\n order.consideration.length\n ),\n order.counter\n );\n\n // Retrieve the order status using the derived order hash.\n orderStatus = _orderStatus[orderHash];\n\n // Update the order status as not valid and cancelled.\n orderStatus.isValidated = false;\n orderStatus.isCancelled = true;\n\n // Emit an event signifying that the order has been cancelled.\n emit OrderCancelled(orderHash, offerer, zone);\n\n // Increment counter inside body of loop for gas efficiency.\n ++i;\n }\n }\n\n // Return a boolean indicating that orders were successfully cancelled.\n cancelled = true;\n }\n\n /**\n * @dev Internal function to validate an arbitrary number of orders, thereby\n * registering their signatures as valid and allowing the fulfiller to\n * skip signature verification on fulfillment. Note that validated\n * orders may still be unfulfillable due to invalid item amounts or\n * other factors; callers should determine whether validated orders are\n * fulfillable by simulating the fulfillment call prior to execution.\n * Also note that anyone can validate a signed order, but only the\n * offerer can validate an order without supplying a signature.\n *\n * @param orders The orders to validate.\n *\n * @return validated A boolean indicating whether the supplied orders were\n * successfully validated.\n */\n function _validate(Order[] calldata orders)\n internal\n returns (bool validated)\n {\n // Ensure that the reentrancy guard is not currently set.\n _assertNonReentrant();\n\n // Declare variables outside of the loop.\n OrderStatus storage orderStatus;\n bytes32 orderHash;\n address offerer;\n\n // Skip overflow check as for loop is indexed starting at zero.\n unchecked {\n // Read length of the orders array from memory and place on stack.\n uint256 totalOrders = orders.length;\n\n // Iterate over each order.\n for (uint256 i = 0; i < totalOrders; ) {\n // Retrieve the order.\n Order calldata order = orders[i];\n\n // Retrieve the order parameters.\n OrderParameters calldata orderParameters = order.parameters;\n\n // Move offerer from memory to the stack.\n offerer = orderParameters.offerer;\n\n // Get current counter & use it w/ params to derive order hash.\n orderHash = _assertConsiderationLengthAndGetOrderHash(\n orderParameters\n );\n\n // Retrieve the order status using the derived order hash.\n orderStatus = _orderStatus[orderHash];\n\n // Ensure order is fillable and retrieve the filled amount.\n _verifyOrderStatus(\n orderHash,\n orderStatus,\n false, // Signifies that partially filled orders are valid.\n true // Signifies to revert if the order is invalid.\n );\n\n // If the order has not already been validated...\n if (!orderStatus.isValidated) {\n // Verify the supplied signature.\n _verifySignature(offerer, orderHash, order.signature);\n\n // Update order status to mark the order as valid.\n orderStatus.isValidated = true;\n\n // Emit an event signifying the order has been validated.\n emit OrderValidated(\n orderHash,\n offerer,\n orderParameters.zone\n );\n }\n\n // Increment counter inside body of the loop for gas efficiency.\n ++i;\n }\n }\n\n // Return a boolean indicating that orders were successfully validated.\n validated = true;\n }\n\n /**\n * @dev Internal view function to retrieve the status of a given order by\n * hash, including whether the order has been cancelled or validated\n * and the fraction of the order that has been filled.\n *\n * @param orderHash The order hash in question.\n *\n * @return isValidated A boolean indicating whether the order in question\n * has been validated (i.e. previously approved or\n * partially filled).\n * @return isCancelled A boolean indicating whether the order in question\n * has been cancelled.\n * @return totalFilled The total portion of the order that has been filled\n * (i.e. the \"numerator\").\n * @return totalSize The total size of the order that is either filled or\n * unfilled (i.e. the \"denominator\").\n */\n function _getOrderStatus(bytes32 orderHash)\n internal\n view\n returns (\n bool isValidated,\n bool isCancelled,\n uint256 totalFilled,\n uint256 totalSize\n )\n {\n // Retrieve the order status using the order hash.\n OrderStatus storage orderStatus = _orderStatus[orderHash];\n\n // Return the fields on the order status.\n return (\n orderStatus.isValidated,\n orderStatus.isCancelled,\n orderStatus.numerator,\n orderStatus.denominator\n );\n }\n\n /**\n * @dev Internal pure function to check whether a given order type indicates\n * that partial fills are not supported (e.g. only \"full fills\" are\n * allowed for the order in question).\n *\n * @param orderType The order type in question.\n *\n * @return isFullOrder A boolean indicating whether the order type only\n * supports full fills.\n */\n function _doesNotSupportPartialFills(OrderType orderType)\n internal\n pure\n returns (bool isFullOrder)\n {\n // The \"full\" order types are even, while \"partial\" order types are odd.\n // Bitwise and by 1 is equivalent to modulo by 2, but 2 gas cheaper.\n assembly {\n // Equivalent to `uint256(orderType) & 1 == 0`.\n isFullOrder := iszero(and(orderType, 1))\n }\n }\n}\n" - }, - "seaport/contracts/lib/BasicOrderFulfiller.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { ConduitInterface } from \"../interfaces/ConduitInterface.sol\";\n\n// prettier-ignore\nimport {\n OrderType,\n ItemType,\n BasicOrderRouteType\n} from \"./ConsiderationEnums.sol\";\n\n// prettier-ignore\nimport {\n AdditionalRecipient,\n BasicOrderParameters,\n OfferItem,\n ConsiderationItem,\n SpentItem,\n ReceivedItem\n} from \"./ConsiderationStructs.sol\";\n\nimport { OrderValidator } from \"./OrderValidator.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title BasicOrderFulfiller\n * @author 0age\n * @notice BasicOrderFulfiller contains functionality for fulfilling \"basic\"\n * orders with minimal overhead. See documentation for details on what\n * qualifies as a basic order.\n */\ncontract BasicOrderFulfiller is OrderValidator {\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) OrderValidator(conduitController) {}\n\n /**\n * @dev Internal function to fulfill an order offering an ERC20, ERC721, or\n * ERC1155 item by supplying Ether (or other native tokens), ERC20\n * tokens, an ERC721 item, or an ERC1155 item as consideration. Six\n * permutations are supported: Native token to ERC721, Native token to\n * ERC1155, ERC20 to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and\n * ERC1155 to ERC20 (with native tokens supplied as msg.value). For an\n * order to be eligible for fulfillment via this method, it must\n * contain a single offer item (though that item may have a greater\n * amount if the item is not an ERC721). An arbitrary number of\n * \"additional recipients\" may also be supplied which will each receive\n * native tokens or ERC20 items from the fulfiller as consideration.\n * Refer to the documentation for a more comprehensive summary of how\n * to utilize this method and what orders are compatible with it.\n *\n * @param parameters Additional information on the fulfilled order. Note\n * that the offerer and the fulfiller must first approve\n * this contract (or their chosen conduit if indicated)\n * before any tokens can be transferred. Also note that\n * contract recipients of ERC1155 consideration items must\n * implement `onERC1155Received` in order to receive those\n * items.\n *\n * @return A boolean indicating whether the order has been fulfilled.\n */\n function _validateAndFulfillBasicOrder(\n BasicOrderParameters calldata parameters\n ) internal returns (bool) {\n // Declare enums for order type & route to extract from basicOrderType.\n BasicOrderRouteType route;\n OrderType orderType;\n\n // Declare additional recipient item type to derive from the route type.\n ItemType additionalRecipientsItemType;\n\n // Utilize assembly to extract the order type and the basic order route.\n assembly {\n // Read basicOrderType from calldata.\n let basicOrderType := calldataload(BasicOrder_basicOrderType_cdPtr)\n\n // Mask all but 2 least-significant bits to derive the order type.\n orderType := and(basicOrderType, 3)\n\n // Divide basicOrderType by four to derive the route.\n route := shr(2, basicOrderType)\n\n // If route > 1 additionalRecipient items are ERC20 (1) else Eth (0)\n additionalRecipientsItemType := gt(route, 1)\n }\n\n {\n // Declare temporary variable for enforcing payable status.\n bool correctPayableStatus;\n\n // Utilize assembly to compare the route to the callvalue.\n assembly {\n // route 0 and 1 are payable, otherwise route is not payable.\n correctPayableStatus := eq(\n additionalRecipientsItemType,\n iszero(callvalue())\n )\n }\n\n // Revert if msg.value has not been supplied as part of payable\n // routes or has been supplied as part of non-payable routes.\n if (!correctPayableStatus) {\n revert InvalidMsgValue(msg.value);\n }\n }\n\n // Declare more arguments that will be derived from route and calldata.\n address additionalRecipientsToken;\n ItemType offeredItemType;\n bool offerTypeIsAdditionalRecipientsType;\n\n // Declare scope for received item type to manage stack pressure.\n {\n ItemType receivedItemType;\n\n // Utilize assembly to retrieve function arguments and cast types.\n assembly {\n // Check if offered item type == additional recipient item type.\n offerTypeIsAdditionalRecipientsType := gt(route, 3)\n\n // If route > 3 additionalRecipientsToken is at 0xc4 else 0x24.\n additionalRecipientsToken := calldataload(\n add(\n BasicOrder_considerationToken_cdPtr,\n mul(\n offerTypeIsAdditionalRecipientsType,\n BasicOrder_common_params_size\n )\n )\n )\n\n // If route > 2, receivedItemType is route - 2. If route is 2,\n // the receivedItemType is ERC20 (1). Otherwise, it is Eth (0).\n receivedItemType := add(\n mul(sub(route, 2), gt(route, 2)),\n eq(route, 2)\n )\n\n // If route > 3, offeredItemType is ERC20 (1). Route is 2 or 3,\n // offeredItemType = route. Route is 0 or 1, it is route + 2.\n offeredItemType := sub(\n add(route, mul(iszero(additionalRecipientsItemType), 2)),\n mul(\n offerTypeIsAdditionalRecipientsType,\n add(receivedItemType, 1)\n )\n )\n }\n\n // Derive & validate order using parameters and update order status.\n _prepareBasicFulfillmentFromCalldata(\n parameters,\n orderType,\n receivedItemType,\n additionalRecipientsItemType,\n additionalRecipientsToken,\n offeredItemType\n );\n }\n\n // Declare conduitKey argument used by transfer functions.\n bytes32 conduitKey;\n\n // Utilize assembly to derive conduit (if relevant) based on route.\n assembly {\n // use offerer conduit for routes 0-3, fulfiller conduit otherwise.\n conduitKey := calldataload(\n add(\n BasicOrder_offererConduit_cdPtr,\n mul(offerTypeIsAdditionalRecipientsType, OneWord)\n )\n )\n }\n\n // Transfer tokens based on the route.\n if (additionalRecipientsItemType == ItemType.NATIVE) {\n // Ensure neither the token nor the identifier parameters are set.\n if (\n (uint160(parameters.considerationToken) |\n parameters.considerationIdentifier) != 0\n ) {\n revert UnusedItemParameters();\n }\n\n // Transfer the ERC721 or ERC1155 item, bypassing the accumulator.\n _transferIndividual721Or1155Item(\n offeredItemType,\n parameters.offerToken,\n parameters.offerer,\n msg.sender,\n parameters.offerIdentifier,\n parameters.offerAmount,\n conduitKey\n );\n\n // Transfer native to recipients, return excess to caller & wrap up.\n _transferEthAndFinalize(\n parameters.considerationAmount,\n parameters.offerer,\n parameters.additionalRecipients\n );\n } else {\n // Initialize an accumulator array. From this point forward, no new\n // memory regions can be safely allocated until the accumulator is\n // no longer being utilized, as the accumulator operates in an\n // open-ended fashion from this memory pointer; existing memory may\n // still be accessed and modified, however.\n bytes memory accumulator = new bytes(AccumulatorDisarmed);\n\n // Choose transfer method for ERC721 or ERC1155 item based on route.\n if (route == BasicOrderRouteType.ERC20_TO_ERC721) {\n // Transfer ERC721 to caller using offerer's conduit preference.\n _transferERC721(\n parameters.offerToken,\n parameters.offerer,\n msg.sender,\n parameters.offerIdentifier,\n parameters.offerAmount,\n conduitKey,\n accumulator\n );\n } else if (route == BasicOrderRouteType.ERC20_TO_ERC1155) {\n // Transfer ERC1155 to caller with offerer's conduit preference.\n _transferERC1155(\n parameters.offerToken,\n parameters.offerer,\n msg.sender,\n parameters.offerIdentifier,\n parameters.offerAmount,\n conduitKey,\n accumulator\n );\n } else if (route == BasicOrderRouteType.ERC721_TO_ERC20) {\n // Transfer ERC721 to offerer using caller's conduit preference.\n _transferERC721(\n parameters.considerationToken,\n msg.sender,\n parameters.offerer,\n parameters.considerationIdentifier,\n parameters.considerationAmount,\n conduitKey,\n accumulator\n );\n } else {\n // route == BasicOrderRouteType.ERC1155_TO_ERC20\n\n // Transfer ERC1155 to offerer with caller's conduit preference.\n _transferERC1155(\n parameters.considerationToken,\n msg.sender,\n parameters.offerer,\n parameters.considerationIdentifier,\n parameters.considerationAmount,\n conduitKey,\n accumulator\n );\n }\n\n // Transfer ERC20 tokens to all recipients and wrap up.\n _transferERC20AndFinalize(\n parameters.offerer,\n parameters,\n offerTypeIsAdditionalRecipientsType,\n accumulator\n );\n\n // Trigger any remaining accumulated transfers via call to conduit.\n _triggerIfArmed(accumulator);\n }\n\n // Clear the reentrancy guard.\n _clearReentrancyGuard();\n\n return true;\n }\n\n /**\n * @dev Internal function to prepare fulfillment of a basic order with\n * manual calldata and memory access. This calculates the order hash,\n * emits an OrderFulfilled event, and asserts basic order validity.\n * Note that calldata offsets must be validated as this function\n * accesses constant calldata pointers for dynamic types that match\n * default ABI encoding, but valid ABI encoding can use arbitrary\n * offsets. Checking that the offsets were produced by default encoding\n * will ensure that other functions using Solidity's calldata accessors\n * (which calculate pointers from the stored offsets) are reading the\n * same data as the order hash is derived from. Also note that This\n * function accesses memory directly. It does not clear the expanded\n * memory regions used, nor does it update the free memory pointer, so\n * other direct memory access must not assume that unused memory is\n * empty.\n *\n * @param parameters The parameters of the basic order.\n * @param orderType The order type.\n * @param receivedItemType The item type of the initial\n * consideration item on the order.\n * @param additionalRecipientsItemType The item type of any additional\n * consideration item on the order.\n * @param additionalRecipientsToken The ERC20 token contract address (if\n * applicable) for any additional\n * consideration item on the order.\n * @param offeredItemType The item type of the offered item on\n * the order.\n */\n function _prepareBasicFulfillmentFromCalldata(\n BasicOrderParameters calldata parameters,\n OrderType orderType,\n ItemType receivedItemType,\n ItemType additionalRecipientsItemType,\n address additionalRecipientsToken,\n ItemType offeredItemType\n ) internal {\n // Ensure this function cannot be triggered during a reentrant call.\n _setReentrancyGuard();\n\n // Ensure current timestamp falls between order start time and end time.\n _verifyTime(parameters.startTime, parameters.endTime, true);\n\n // Verify that calldata offsets for all dynamic types were produced by\n // default encoding. This ensures that the constants we use for calldata\n // pointers to dynamic types are the same as those calculated by\n // Solidity using their offsets. Also verify that the basic order type\n // is within range.\n _assertValidBasicOrderParameters();\n\n // Ensure supplied consideration array length is not less than original.\n _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(\n parameters.additionalRecipients.length,\n parameters.totalOriginalAdditionalRecipients\n );\n\n // Declare stack element for the order hash.\n bytes32 orderHash;\n\n {\n /**\n * First, handle consideration items. Memory Layout:\n * 0x60: final hash of the array of consideration item hashes\n * 0x80-0x160: reused space for EIP712 hashing of each item\n * - 0x80: ConsiderationItem EIP-712 typehash (constant)\n * - 0xa0: itemType\n * - 0xc0: token\n * - 0xe0: identifier\n * - 0x100: startAmount\n * - 0x120: endAmount\n * - 0x140: recipient\n * 0x160-END_ARR: array of consideration item hashes\n * - 0x160: primary consideration item EIP712 hash\n * - 0x180-END_ARR: additional recipient item EIP712 hashes\n * END_ARR: beginning of data for OrderFulfilled event\n * - END_ARR + 0x120: length of ReceivedItem array\n * - END_ARR + 0x140: beginning of data for first ReceivedItem\n * (Note: END_ARR = 0x180 + RECIPIENTS_LENGTH * 0x20)\n */\n\n // Load consideration item typehash from runtime and place on stack.\n bytes32 typeHash = _CONSIDERATION_ITEM_TYPEHASH;\n\n // Utilize assembly to enable reuse of memory regions and use\n // constant pointers when possible.\n assembly {\n /*\n * 1. Calculate the EIP712 ConsiderationItem hash for the\n * primary consideration item of the basic order.\n */\n\n // Write ConsiderationItem type hash and item type to memory.\n mstore(BasicOrder_considerationItem_typeHash_ptr, typeHash)\n mstore(\n BasicOrder_considerationItem_itemType_ptr,\n receivedItemType\n )\n\n // Copy calldata region with (token, identifier, amount) from\n // BasicOrderParameters to ConsiderationItem. The\n // considerationAmount is written to startAmount and endAmount\n // as basic orders do not have dynamic amounts.\n calldatacopy(\n BasicOrder_considerationItem_token_ptr,\n BasicOrder_considerationToken_cdPtr,\n ThreeWords\n )\n\n // Copy calldata region with considerationAmount and offerer\n // from BasicOrderParameters to endAmount and recipient in\n // ConsiderationItem.\n calldatacopy(\n BasicOrder_considerationItem_endAmount_ptr,\n BasicOrder_considerationAmount_cdPtr,\n TwoWords\n )\n\n // Calculate EIP712 ConsiderationItem hash and store it in the\n // array of EIP712 consideration hashes.\n mstore(\n BasicOrder_considerationHashesArray_ptr,\n keccak256(\n BasicOrder_considerationItem_typeHash_ptr,\n EIP712_ConsiderationItem_size\n )\n )\n\n /*\n * 2. Write a ReceivedItem struct for the primary consideration\n * item to the consideration array in OrderFulfilled.\n */\n\n // Get the length of the additional recipients array.\n let totalAdditionalRecipients := calldataload(\n BasicOrder_additionalRecipients_length_cdPtr\n )\n\n // Calculate pointer to length of OrderFulfilled consideration\n // array.\n let eventConsiderationArrPtr := add(\n OrderFulfilled_consideration_length_baseOffset,\n mul(totalAdditionalRecipients, OneWord)\n )\n\n // Set the length of the consideration array to the number of\n // additional recipients, plus one for the primary consideration\n // item.\n mstore(\n eventConsiderationArrPtr,\n add(\n calldataload(\n BasicOrder_additionalRecipients_length_cdPtr\n ),\n 1\n )\n )\n\n // Overwrite the consideration array pointer so it points to the\n // body of the first element\n eventConsiderationArrPtr := add(\n eventConsiderationArrPtr,\n OneWord\n )\n\n // Set itemType at start of the ReceivedItem memory region.\n mstore(eventConsiderationArrPtr, receivedItemType)\n\n // Copy calldata region (token, identifier, amount & recipient)\n // from BasicOrderParameters to ReceivedItem memory.\n calldatacopy(\n add(eventConsiderationArrPtr, Common_token_offset),\n BasicOrder_considerationToken_cdPtr,\n FourWords\n )\n\n /*\n * 3. Calculate EIP712 ConsiderationItem hashes for original\n * additional recipients and add a ReceivedItem for each to the\n * consideration array in the OrderFulfilled event. The original\n * additional recipients are all the considerations signed by\n * the offerer aside from the primary consideration of the\n * order. Uses memory region from 0x80-0x160 as a buffer for\n * calculating EIP712 ConsiderationItem hashes.\n */\n\n // Put pointer to consideration hashes array on the stack.\n // This will be updated as each additional recipient is hashed\n let\n considerationHashesPtr\n := BasicOrder_considerationHashesArray_ptr\n\n // Write item type, token, & identifier for additional recipient\n // to memory region for hashing EIP712 ConsiderationItem; these\n // values will be reused for each recipient.\n mstore(\n BasicOrder_considerationItem_itemType_ptr,\n additionalRecipientsItemType\n )\n mstore(\n BasicOrder_considerationItem_token_ptr,\n additionalRecipientsToken\n )\n mstore(BasicOrder_considerationItem_identifier_ptr, 0)\n\n // Read length of the additionalRecipients array from calldata\n // and iterate.\n totalAdditionalRecipients := calldataload(\n BasicOrder_totalOriginalAdditionalRecipients_cdPtr\n )\n let i := 0\n // prettier-ignore\n for {} lt(i, totalAdditionalRecipients) {\n i := add(i, 1)\n } {\n /*\n * Calculate EIP712 ConsiderationItem hash for recipient.\n */\n\n // Retrieve calldata pointer for additional recipient.\n let additionalRecipientCdPtr := add(\n BasicOrder_additionalRecipients_data_cdPtr,\n mul(AdditionalRecipients_size, i)\n )\n\n // Copy startAmount from calldata to the ConsiderationItem\n // struct.\n calldatacopy(\n BasicOrder_considerationItem_startAmount_ptr,\n additionalRecipientCdPtr,\n OneWord\n )\n\n // Copy endAmount and recipient from calldata to the\n // ConsiderationItem struct.\n calldatacopy(\n BasicOrder_considerationItem_endAmount_ptr,\n additionalRecipientCdPtr,\n AdditionalRecipients_size\n )\n\n // Add 1 word to the pointer as part of each loop to reduce\n // operations needed to get local offset into the array.\n considerationHashesPtr := add(\n considerationHashesPtr,\n OneWord\n )\n\n // Calculate EIP712 ConsiderationItem hash and store it in\n // the array of consideration hashes.\n mstore(\n considerationHashesPtr,\n keccak256(\n BasicOrder_considerationItem_typeHash_ptr,\n EIP712_ConsiderationItem_size\n )\n )\n\n /*\n * Write ReceivedItem to OrderFulfilled data.\n */\n\n // At this point, eventConsiderationArrPtr points to the\n // beginning of the ReceivedItem struct of the previous\n // element in the array. Increase it by the size of the\n // struct to arrive at the pointer for the current element.\n eventConsiderationArrPtr := add(\n eventConsiderationArrPtr,\n ReceivedItem_size\n )\n\n // Write itemType to the ReceivedItem struct.\n mstore(\n eventConsiderationArrPtr,\n additionalRecipientsItemType\n )\n\n // Write token to the next word of the ReceivedItem struct.\n mstore(\n add(eventConsiderationArrPtr, OneWord),\n additionalRecipientsToken\n )\n\n // Copy endAmount & recipient words to ReceivedItem struct.\n calldatacopy(\n add(\n eventConsiderationArrPtr,\n ReceivedItem_amount_offset\n ),\n additionalRecipientCdPtr,\n TwoWords\n )\n }\n\n /*\n * 4. Hash packed array of ConsiderationItem EIP712 hashes:\n * `keccak256(abi.encodePacked(receivedItemHashes))`\n * Note that it is set at 0x60 — all other memory begins at\n * 0x80. 0x60 is the \"zero slot\" and will be restored at the end\n * of the assembly section and before required by the compiler.\n */\n mstore(\n receivedItemsHash_ptr,\n keccak256(\n BasicOrder_considerationHashesArray_ptr,\n mul(add(totalAdditionalRecipients, 1), OneWord)\n )\n )\n\n /*\n * 5. Add a ReceivedItem for each tip to the consideration array\n * in the OrderFulfilled event. The tips are all the\n * consideration items that were not signed by the offerer and\n * were provided by the fulfiller.\n */\n\n // Overwrite length to length of the additionalRecipients array.\n totalAdditionalRecipients := calldataload(\n BasicOrder_additionalRecipients_length_cdPtr\n )\n // prettier-ignore\n for {} lt(i, totalAdditionalRecipients) {\n i := add(i, 1)\n } {\n // Retrieve calldata pointer for additional recipient.\n let additionalRecipientCdPtr := add(\n BasicOrder_additionalRecipients_data_cdPtr,\n mul(AdditionalRecipients_size, i)\n )\n\n // At this point, eventConsiderationArrPtr points to the\n // beginning of the ReceivedItem struct of the previous\n // element in the array. Increase it by the size of the\n // struct to arrive at the pointer for the current element.\n eventConsiderationArrPtr := add(\n eventConsiderationArrPtr,\n ReceivedItem_size\n )\n\n // Write itemType to the ReceivedItem struct.\n mstore(\n eventConsiderationArrPtr,\n additionalRecipientsItemType\n )\n\n // Write token to the next word of the ReceivedItem struct.\n mstore(\n add(eventConsiderationArrPtr, OneWord),\n additionalRecipientsToken\n )\n\n // Copy endAmount & recipient words to ReceivedItem struct.\n calldatacopy(\n add(\n eventConsiderationArrPtr,\n ReceivedItem_amount_offset\n ),\n additionalRecipientCdPtr,\n TwoWords\n )\n }\n }\n }\n\n {\n /**\n * Next, handle offered items. Memory Layout:\n * EIP712 data for OfferItem\n * - 0x80: OfferItem EIP-712 typehash (constant)\n * - 0xa0: itemType\n * - 0xc0: token\n * - 0xe0: identifier (reused for offeredItemsHash)\n * - 0x100: startAmount\n * - 0x120: endAmount\n */\n\n // Place offer item typehash on the stack.\n bytes32 typeHash = _OFFER_ITEM_TYPEHASH;\n\n // Utilize assembly to enable reuse of memory regions when possible.\n assembly {\n /*\n * 1. Calculate OfferItem EIP712 hash\n */\n\n // Write the OfferItem typeHash to memory.\n mstore(BasicOrder_offerItem_typeHash_ptr, typeHash)\n\n // Write the OfferItem item type to memory.\n mstore(BasicOrder_offerItem_itemType_ptr, offeredItemType)\n\n // Copy calldata region with (offerToken, offerIdentifier,\n // offerAmount) from OrderParameters to (token, identifier,\n // startAmount) in OfferItem struct. The offerAmount is written\n // to startAmount and endAmount as basic orders do not have\n // dynamic amounts.\n calldatacopy(\n BasicOrder_offerItem_token_ptr,\n BasicOrder_offerToken_cdPtr,\n ThreeWords\n )\n\n // Copy offerAmount from calldata to endAmount in OfferItem\n // struct.\n calldatacopy(\n BasicOrder_offerItem_endAmount_ptr,\n BasicOrder_offerAmount_cdPtr,\n OneWord\n )\n\n // Compute EIP712 OfferItem hash, write result to scratch space:\n // `keccak256(abi.encode(offeredItem))`\n mstore(\n 0,\n keccak256(\n BasicOrder_offerItem_typeHash_ptr,\n EIP712_OfferItem_size\n )\n )\n\n /*\n * 2. Calculate hash of array of EIP712 hashes and write the\n * result to the corresponding OfferItem struct:\n * `keccak256(abi.encodePacked(offerItemHashes))`\n */\n mstore(BasicOrder_order_offerHashes_ptr, keccak256(0, OneWord))\n\n /*\n * 3. Write SpentItem to offer array in OrderFulfilled event.\n */\n let eventConsiderationArrPtr := add(\n OrderFulfilled_offer_length_baseOffset,\n mul(\n calldataload(\n BasicOrder_additionalRecipients_length_cdPtr\n ),\n OneWord\n )\n )\n\n // Set a length of 1 for the offer array.\n mstore(eventConsiderationArrPtr, 1)\n\n // Write itemType to the SpentItem struct.\n mstore(add(eventConsiderationArrPtr, OneWord), offeredItemType)\n\n // Copy calldata region with (offerToken, offerIdentifier,\n // offerAmount) from OrderParameters to (token, identifier,\n // amount) in SpentItem struct.\n calldatacopy(\n add(eventConsiderationArrPtr, AdditionalRecipients_size),\n BasicOrder_offerToken_cdPtr,\n ThreeWords\n )\n }\n }\n\n {\n /**\n * Once consideration items and offer items have been handled,\n * derive the final order hash. Memory Layout:\n * 0x80-0x1c0: EIP712 data for order\n * - 0x80: Order EIP-712 typehash (constant)\n * - 0xa0: orderParameters.offerer\n * - 0xc0: orderParameters.zone\n * - 0xe0: keccak256(abi.encodePacked(offerHashes))\n * - 0x100: keccak256(abi.encodePacked(considerationHashes))\n * - 0x120: orderParameters.basicOrderType (% 4 = orderType)\n * - 0x140: orderParameters.startTime\n * - 0x160: orderParameters.endTime\n * - 0x180: orderParameters.zoneHash\n * - 0x1a0: orderParameters.salt\n * - 0x1c0: orderParameters.conduitKey\n * - 0x1e0: _counters[orderParameters.offerer] (from storage)\n */\n\n // Read the offerer from calldata and place on the stack.\n address offerer;\n assembly {\n offerer := calldataload(BasicOrder_offerer_cdPtr)\n }\n\n // Read offerer's current counter from storage and place on stack.\n uint256 counter = _getCounter(offerer);\n\n // Load order typehash from runtime code and place on stack.\n bytes32 typeHash = _ORDER_TYPEHASH;\n\n assembly {\n // Set the OrderItem typeHash in memory.\n mstore(BasicOrder_order_typeHash_ptr, typeHash)\n\n // Copy offerer and zone from OrderParameters in calldata to the\n // Order struct.\n calldatacopy(\n BasicOrder_order_offerer_ptr,\n BasicOrder_offerer_cdPtr,\n TwoWords\n )\n\n // Copy receivedItemsHash from zero slot to the Order struct.\n mstore(\n BasicOrder_order_considerationHashes_ptr,\n mload(receivedItemsHash_ptr)\n )\n\n // Write the supplied orderType to the Order struct.\n mstore(BasicOrder_order_orderType_ptr, orderType)\n\n // Copy startTime, endTime, zoneHash, salt & conduit from\n // calldata to the Order struct.\n calldatacopy(\n BasicOrder_order_startTime_ptr,\n BasicOrder_startTime_cdPtr,\n FiveWords\n )\n\n // Write offerer's counter, retrieved from storage, to struct.\n mstore(BasicOrder_order_counter_ptr, counter)\n\n // Compute the EIP712 Order hash.\n orderHash := keccak256(\n BasicOrder_order_typeHash_ptr,\n EIP712_Order_size\n )\n }\n }\n\n assembly {\n /**\n * After the order hash has been derived, emit OrderFulfilled event:\n * event OrderFulfilled(\n * bytes32 orderHash,\n * address indexed offerer,\n * address indexed zone,\n * address fulfiller,\n * SpentItem[] offer,\n * > (itemType, token, id, amount)\n * ReceivedItem[] consideration\n * > (itemType, token, id, amount, recipient)\n * )\n * topic0 - OrderFulfilled event signature\n * topic1 - offerer\n * topic2 - zone\n * data:\n * - 0x00: orderHash\n * - 0x20: fulfiller\n * - 0x40: offer arr ptr (0x80)\n * - 0x60: consideration arr ptr (0x120)\n * - 0x80: offer arr len (1)\n * - 0xa0: offer.itemType\n * - 0xc0: offer.token\n * - 0xe0: offer.identifier\n * - 0x100: offer.amount\n * - 0x120: 1 + recipients.length\n * - 0x140: recipient 0\n */\n\n // Derive pointer to start of OrderFulfilled event data\n let eventDataPtr := add(\n OrderFulfilled_baseOffset,\n mul(\n calldataload(BasicOrder_additionalRecipients_length_cdPtr),\n OneWord\n )\n )\n\n // Write the order hash to the head of the event's data region.\n mstore(eventDataPtr, orderHash)\n\n // Write the fulfiller (i.e. the caller) next for receiver argument.\n mstore(add(eventDataPtr, OrderFulfilled_fulfiller_offset), caller())\n\n // Write the SpentItem and ReceivedItem array offsets (constants).\n mstore(\n // SpentItem array offset\n add(eventDataPtr, OrderFulfilled_offer_head_offset),\n OrderFulfilled_offer_body_offset\n )\n mstore(\n // ReceivedItem array offset\n add(eventDataPtr, OrderFulfilled_consideration_head_offset),\n OrderFulfilled_consideration_body_offset\n )\n\n // Derive total data size including SpentItem and ReceivedItem data.\n // SpentItem portion is already included in the baseSize constant,\n // as there can only be one element in the array.\n let dataSize := add(\n OrderFulfilled_baseSize,\n mul(\n calldataload(BasicOrder_additionalRecipients_length_cdPtr),\n ReceivedItem_size\n )\n )\n\n // Emit OrderFulfilled log with three topics (the event signature\n // as well as the two indexed arguments, the offerer and the zone).\n log3(\n // Supply the pointer for event data in memory.\n eventDataPtr,\n // Supply the size of event data in memory.\n dataSize,\n // Supply the OrderFulfilled event signature.\n OrderFulfilled_selector,\n // Supply the first topic (the offerer).\n calldataload(BasicOrder_offerer_cdPtr),\n // Supply the second topic (the zone).\n calldataload(BasicOrder_zone_cdPtr)\n )\n\n // Restore the zero slot.\n mstore(ZeroSlot, 0)\n }\n\n // Determine whether order is restricted and, if so, that it is valid.\n _assertRestrictedBasicOrderValidity(\n orderHash,\n parameters.zoneHash,\n orderType,\n parameters.offerer,\n parameters.zone\n );\n\n // Verify and update the status of the derived order.\n _validateBasicOrderAndUpdateStatus(\n orderHash,\n parameters.offerer,\n parameters.signature\n );\n }\n\n /**\n * @dev Internal function to transfer Ether (or other native tokens) to a\n * given recipient as part of basic order fulfillment. Note that\n * conduits are not utilized for native tokens as the transferred\n * amount must be provided as msg.value.\n *\n * @param amount The amount to transfer.\n * @param to The recipient of the native token transfer.\n * @param additionalRecipients The additional recipients of the order.\n */\n function _transferEthAndFinalize(\n uint256 amount,\n address payable to,\n AdditionalRecipient[] calldata additionalRecipients\n ) internal {\n // Put ether value supplied by the caller on the stack.\n uint256 etherRemaining = msg.value;\n\n // Retrieve total number of additional recipients and place on stack.\n uint256 totalAdditionalRecipients = additionalRecipients.length;\n\n // Skip overflow check as for loop is indexed starting at zero.\n unchecked {\n // Iterate over each additional recipient.\n for (uint256 i = 0; i < totalAdditionalRecipients; ++i) {\n // Retrieve the additional recipient.\n AdditionalRecipient calldata additionalRecipient = (\n additionalRecipients[i]\n );\n\n // Read ether amount to transfer to recipient & place on stack.\n uint256 additionalRecipientAmount = additionalRecipient.amount;\n\n // Ensure that sufficient Ether is available.\n if (additionalRecipientAmount > etherRemaining) {\n revert InsufficientEtherSupplied();\n }\n\n // Transfer Ether to the additional recipient.\n _transferEth(\n additionalRecipient.recipient,\n additionalRecipientAmount\n );\n\n // Reduce ether value available. Skip underflow check as\n // subtracted value is confirmed above as less than remaining.\n etherRemaining -= additionalRecipientAmount;\n }\n }\n\n // Ensure that sufficient Ether is still available.\n if (amount > etherRemaining) {\n revert InsufficientEtherSupplied();\n }\n\n // Transfer Ether to the offerer.\n _transferEth(to, amount);\n\n // If any Ether remains after transfers, return it to the caller.\n if (etherRemaining > amount) {\n // Skip underflow check as etherRemaining > amount.\n unchecked {\n // Transfer remaining Ether to the caller.\n _transferEth(payable(msg.sender), etherRemaining - amount);\n }\n }\n }\n\n /**\n * @dev Internal function to transfer ERC20 tokens to a given recipient as\n * part of basic order fulfillment.\n *\n * @param offerer The offerer of the fulfiller order.\n * @param parameters The basic order parameters.\n * @param fromOfferer A boolean indicating whether to decrement amount from\n * the offered amount.\n * @param accumulator An open-ended array that collects transfers to execute\n * against a given conduit in a single call.\n */\n function _transferERC20AndFinalize(\n address offerer,\n BasicOrderParameters calldata parameters,\n bool fromOfferer,\n bytes memory accumulator\n ) internal {\n // Declare from and to variables determined by fromOfferer value.\n address from;\n address to;\n\n // Declare token and amount variables determined by fromOfferer value.\n address token;\n uint256 amount;\n\n // Declare and check identifier variable within an isolated scope.\n {\n // Declare identifier variable determined by fromOfferer value.\n uint256 identifier;\n\n // Set ERC20 token transfer variables based on fromOfferer boolean.\n if (fromOfferer) {\n // Use offerer as from value and msg.sender as to value.\n from = offerer;\n to = msg.sender;\n\n // Use offer token and related values if token is from offerer.\n token = parameters.offerToken;\n identifier = parameters.offerIdentifier;\n amount = parameters.offerAmount;\n } else {\n // Use msg.sender as from value and offerer as to value.\n from = msg.sender;\n to = offerer;\n\n // Otherwise, use consideration token and related values.\n token = parameters.considerationToken;\n identifier = parameters.considerationIdentifier;\n amount = parameters.considerationAmount;\n }\n\n // Ensure that no identifier is supplied.\n if (identifier != 0) {\n revert UnusedItemParameters();\n }\n }\n\n // Determine the appropriate conduit to utilize.\n bytes32 conduitKey;\n\n // Utilize assembly to derive conduit (if relevant) based on route.\n assembly {\n // Use offerer conduit if fromOfferer, fulfiller conduit otherwise.\n conduitKey := calldataload(\n sub(\n BasicOrder_fulfillerConduit_cdPtr,\n mul(fromOfferer, OneWord)\n )\n )\n }\n\n // Retrieve total number of additional recipients and place on stack.\n uint256 totalAdditionalRecipients = (\n parameters.additionalRecipients.length\n );\n\n // Iterate over each additional recipient.\n for (uint256 i = 0; i < totalAdditionalRecipients; ) {\n // Retrieve the additional recipient.\n AdditionalRecipient calldata additionalRecipient = (\n parameters.additionalRecipients[i]\n );\n\n uint256 additionalRecipientAmount = additionalRecipient.amount;\n\n // Decrement the amount to transfer to fulfiller if indicated.\n if (fromOfferer) {\n amount -= additionalRecipientAmount;\n }\n\n // Transfer ERC20 tokens to additional recipient given approval.\n _transferERC20(\n token,\n from,\n additionalRecipient.recipient,\n additionalRecipientAmount,\n conduitKey,\n accumulator\n );\n\n // Skip overflow check as for loop is indexed starting at zero.\n unchecked {\n ++i;\n }\n }\n\n // Transfer ERC20 token amount (from account must have proper approval).\n _transferERC20(token, from, to, amount, conduitKey, accumulator);\n }\n}\n" - }, - "seaport/contracts/lib/OrderFulfiller.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { ItemType } from \"./ConsiderationEnums.sol\";\n\n// prettier-ignore\nimport {\n OfferItem,\n ConsiderationItem,\n SpentItem,\n ReceivedItem,\n OrderParameters,\n Order,\n AdvancedOrder,\n CriteriaResolver\n} from \"./ConsiderationStructs.sol\";\n\nimport { BasicOrderFulfiller } from \"./BasicOrderFulfiller.sol\";\n\nimport { CriteriaResolution } from \"./CriteriaResolution.sol\";\n\nimport { AmountDeriver } from \"./AmountDeriver.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title OrderFulfiller\n * @author 0age\n * @notice OrderFulfiller contains logic related to order fulfillment where a\n * single order is being fulfilled and where basic order fulfillment is\n * not available as an option.\n */\ncontract OrderFulfiller is\n BasicOrderFulfiller,\n CriteriaResolution,\n AmountDeriver\n{\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController)\n BasicOrderFulfiller(conduitController)\n {}\n\n /**\n * @dev Internal function to validate an order and update its status, adjust\n * prices based on current time, apply criteria resolvers, determine\n * what portion to fill, and transfer relevant tokens.\n *\n * @param advancedOrder The order to fulfill as well as the fraction\n * to fill. Note that all offer and consideration\n * components must divide with no remainder for\n * the partial fill to be valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a proof\n * that the supplied token identifier is\n * contained in the order's merkle root. Note\n * that a criteria of zero indicates that any\n * (transferable) token identifier is valid and\n * that no proof needs to be supplied.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used, with direct approvals set on\n * Consideration.\n * @param recipient The intended recipient for all received items.\n *\n * @return A boolean indicating whether the order has been fulfilled.\n */\n function _validateAndFulfillAdvancedOrder(\n AdvancedOrder memory advancedOrder,\n CriteriaResolver[] memory criteriaResolvers,\n bytes32 fulfillerConduitKey,\n address recipient\n ) internal returns (bool) {\n // Ensure this function cannot be triggered during a reentrant call.\n _setReentrancyGuard();\n\n // Declare empty bytes32 array (unused, will remain empty).\n bytes32[] memory priorOrderHashes;\n\n // Validate order, update status, and determine fraction to fill.\n (\n bytes32 orderHash,\n uint256 fillNumerator,\n uint256 fillDenominator\n ) = _validateOrderAndUpdateStatus(\n advancedOrder,\n criteriaResolvers,\n true,\n priorOrderHashes\n );\n\n // Create an array with length 1 containing the order.\n AdvancedOrder[] memory advancedOrders = new AdvancedOrder[](1);\n\n // Populate the order as the first and only element of the new array.\n advancedOrders[0] = advancedOrder;\n\n // Apply criteria resolvers using generated orders and details arrays.\n _applyCriteriaResolvers(advancedOrders, criteriaResolvers);\n\n // Retrieve the order parameters after applying criteria resolvers.\n OrderParameters memory orderParameters = advancedOrders[0].parameters;\n\n // Perform each item transfer with the appropriate fractional amount.\n _applyFractionsAndTransferEach(\n orderParameters,\n fillNumerator,\n fillDenominator,\n fulfillerConduitKey,\n recipient\n );\n\n // Emit an event signifying that the order has been fulfilled.\n _emitOrderFulfilledEvent(\n orderHash,\n orderParameters.offerer,\n orderParameters.zone,\n recipient,\n orderParameters.offer,\n orderParameters.consideration\n );\n\n // Clear the reentrancy guard.\n _clearReentrancyGuard();\n\n return true;\n }\n\n /**\n * @dev Internal function to transfer each item contained in a given single\n * order fulfillment after applying a respective fraction to the amount\n * being transferred.\n *\n * @param orderParameters The parameters for the fulfilled order.\n * @param numerator A value indicating the portion of the order\n * that should be filled.\n * @param denominator A value indicating the total order size.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used, with direct approvals set on\n * Consideration.\n * @param recipient The intended recipient for all received items.\n */\n function _applyFractionsAndTransferEach(\n OrderParameters memory orderParameters,\n uint256 numerator,\n uint256 denominator,\n bytes32 fulfillerConduitKey,\n address recipient\n ) internal {\n // Read start time & end time from order parameters and place on stack.\n uint256 startTime = orderParameters.startTime;\n uint256 endTime = orderParameters.endTime;\n\n // Initialize an accumulator array. From this point forward, no new\n // memory regions can be safely allocated until the accumulator is no\n // longer being utilized, as the accumulator operates in an open-ended\n // fashion from this memory pointer; existing memory may still be\n // accessed and modified, however.\n bytes memory accumulator = new bytes(AccumulatorDisarmed);\n\n // As of solidity 0.6.0, inline assembly cannot directly access function\n // definitions, but can still access locally scoped function variables.\n // This means that in order to recast the type of a function, we need to\n // create a local variable to reference the internal function definition\n // (using the same type) and a local variable with the desired type,\n // and then cast the original function pointer to the desired type.\n\n /**\n * Repurpose existing OfferItem memory regions on the offer array for\n * the order by overriding the _transfer function pointer to accept a\n * modified OfferItem argument in place of the usual ReceivedItem:\n *\n * ========= OfferItem ========== ====== ReceivedItem ======\n * ItemType itemType; ------------> ItemType itemType;\n * address token; ----------------> address token;\n * uint256 identifierOrCriteria; -> uint256 identifier;\n * uint256 startAmount; ----------> uint256 amount;\n * uint256 endAmount; ------------> address recipient;\n */\n\n // Declare a nested scope to minimize stack depth.\n unchecked {\n // Declare a virtual function pointer taking an OfferItem argument.\n function(OfferItem memory, address, bytes32, bytes memory)\n internal _transferOfferItem;\n\n {\n // Assign _transfer function to a new function pointer (it takes\n // a ReceivedItem as its initial argument)\n function(ReceivedItem memory, address, bytes32, bytes memory)\n internal _transferReceivedItem = _transfer;\n\n // Utilize assembly to override the virtual function pointer.\n assembly {\n // Cast initial ReceivedItem type to an OfferItem type.\n _transferOfferItem := _transferReceivedItem\n }\n }\n\n // Read offer array length from memory and place on stack.\n uint256 totalOfferItems = orderParameters.offer.length;\n\n // Iterate over each offer on the order.\n // Skip overflow check as for loop is indexed starting at zero.\n for (uint256 i = 0; i < totalOfferItems; ++i) {\n // Retrieve the offer item.\n OfferItem memory offerItem = orderParameters.offer[i];\n\n // Offer items for the native token can not be received\n // outside of a match order function.\n if (offerItem.itemType == ItemType.NATIVE) {\n revert InvalidNativeOfferItem();\n }\n\n // Declare an additional nested scope to minimize stack depth.\n {\n // Apply fill fraction to get offer item amount to transfer.\n uint256 amount = _applyFraction(\n offerItem.startAmount,\n offerItem.endAmount,\n numerator,\n denominator,\n startTime,\n endTime,\n false\n );\n\n // Utilize assembly to set overloaded offerItem arguments.\n assembly {\n // Write new fractional amount to startAmount as amount.\n mstore(\n add(offerItem, ReceivedItem_amount_offset),\n amount\n )\n\n // Write recipient to endAmount.\n mstore(\n add(offerItem, ReceivedItem_recipient_offset),\n recipient\n )\n }\n }\n\n // Transfer the item from the offerer to the recipient.\n _transferOfferItem(\n offerItem,\n orderParameters.offerer,\n orderParameters.conduitKey,\n accumulator\n );\n }\n }\n\n // Put ether value supplied by the caller on the stack.\n uint256 etherRemaining = msg.value;\n\n /**\n * Repurpose existing ConsiderationItem memory regions on the\n * consideration array for the order by overriding the _transfer\n * function pointer to accept a modified ConsiderationItem argument in\n * place of the usual ReceivedItem:\n *\n * ====== ConsiderationItem ===== ====== ReceivedItem ======\n * ItemType itemType; ------------> ItemType itemType;\n * address token; ----------------> address token;\n * uint256 identifierOrCriteria;--> uint256 identifier;\n * uint256 startAmount; ----------> uint256 amount;\n * uint256 endAmount; /----> address recipient;\n * address recipient; ------/\n */\n\n // Declare a nested scope to minimize stack depth.\n unchecked {\n // Declare virtual function pointer with ConsiderationItem argument.\n function(ConsiderationItem memory, address, bytes32, bytes memory)\n internal _transferConsiderationItem;\n {\n // Reassign _transfer function to a new function pointer (it\n // takes a ReceivedItem as its initial argument).\n function(ReceivedItem memory, address, bytes32, bytes memory)\n internal _transferReceivedItem = _transfer;\n\n // Utilize assembly to override the virtual function pointer.\n assembly {\n // Cast ReceivedItem type to ConsiderationItem type.\n _transferConsiderationItem := _transferReceivedItem\n }\n }\n\n // Read consideration array length from memory and place on stack.\n uint256 totalConsiderationItems = orderParameters\n .consideration\n .length;\n\n // Iterate over each consideration item on the order.\n // Skip overflow check as for loop is indexed starting at zero.\n for (uint256 i = 0; i < totalConsiderationItems; ++i) {\n // Retrieve the consideration item.\n ConsiderationItem memory considerationItem = (\n orderParameters.consideration[i]\n );\n\n // Apply fraction & derive considerationItem amount to transfer.\n uint256 amount = _applyFraction(\n considerationItem.startAmount,\n considerationItem.endAmount,\n numerator,\n denominator,\n startTime,\n endTime,\n true\n );\n\n // Use assembly to set overloaded considerationItem arguments.\n assembly {\n // Write derived fractional amount to startAmount as amount.\n mstore(\n add(considerationItem, ReceivedItem_amount_offset),\n amount\n )\n\n // Write original recipient to endAmount as recipient.\n mstore(\n add(considerationItem, ReceivedItem_recipient_offset),\n mload(\n add(\n considerationItem,\n ConsiderationItem_recipient_offset\n )\n )\n )\n }\n\n // Reduce available value if offer spent ETH or a native token.\n if (considerationItem.itemType == ItemType.NATIVE) {\n // Ensure that sufficient native tokens are still available.\n if (amount > etherRemaining) {\n revert InsufficientEtherSupplied();\n }\n\n // Skip underflow check as a comparison has just been made.\n etherRemaining -= amount;\n }\n\n // Transfer item from caller to recipient specified by the item.\n _transferConsiderationItem(\n considerationItem,\n msg.sender,\n fulfillerConduitKey,\n accumulator\n );\n }\n }\n\n // Trigger any remaining accumulated transfers via call to the conduit.\n _triggerIfArmed(accumulator);\n\n // If any ether remains after fulfillments...\n if (etherRemaining != 0) {\n // return it to the caller.\n _transferEth(payable(msg.sender), etherRemaining);\n }\n }\n\n /**\n * @dev Internal function to emit an OrderFulfilled event. OfferItems are\n * translated into SpentItems and ConsiderationItems are translated\n * into ReceivedItems.\n *\n * @param orderHash The order hash.\n * @param offerer The offerer for the order.\n * @param zone The zone for the order.\n * @param fulfiller The fulfiller of the order, or the null address if\n * the order was fulfilled via order matching.\n * @param offer The offer items for the order.\n * @param consideration The consideration items for the order.\n */\n function _emitOrderFulfilledEvent(\n bytes32 orderHash,\n address offerer,\n address zone,\n address fulfiller,\n OfferItem[] memory offer,\n ConsiderationItem[] memory consideration\n ) internal {\n // Cast already-modified offer memory region as spent items.\n SpentItem[] memory spentItems;\n assembly {\n spentItems := offer\n }\n\n // Cast already-modified consideration memory region as received items.\n ReceivedItem[] memory receivedItems;\n assembly {\n receivedItems := consideration\n }\n\n // Emit an event signifying that the order has been fulfilled.\n emit OrderFulfilled(\n orderHash,\n offerer,\n zone,\n fulfiller,\n spentItems,\n receivedItems\n );\n }\n\n /**\n * @dev Internal pure function to convert an order to an advanced order with\n * numerator and denominator of 1 and empty extraData.\n *\n * @param order The order to convert.\n *\n * @return advancedOrder The new advanced order.\n */\n function _convertOrderToAdvanced(Order calldata order)\n internal\n pure\n returns (AdvancedOrder memory advancedOrder)\n {\n // Convert to partial order (1/1 or full fill) and return new value.\n advancedOrder = AdvancedOrder(\n order.parameters,\n 1,\n 1,\n order.signature,\n \"\"\n );\n }\n\n /**\n * @dev Internal pure function to convert an array of orders to an array of\n * advanced orders with numerator and denominator of 1.\n *\n * @param orders The orders to convert.\n *\n * @return advancedOrders The new array of partial orders.\n */\n function _convertOrdersToAdvanced(Order[] calldata orders)\n internal\n pure\n returns (AdvancedOrder[] memory advancedOrders)\n {\n // Read the number of orders from calldata and place on the stack.\n uint256 totalOrders = orders.length;\n\n // Allocate new empty array for each partial order in memory.\n advancedOrders = new AdvancedOrder[](totalOrders);\n\n // Skip overflow check as the index for the loop starts at zero.\n unchecked {\n // Iterate over the given orders.\n for (uint256 i = 0; i < totalOrders; ++i) {\n // Convert to partial order (1/1 or full fill) and update array.\n advancedOrders[i] = _convertOrderToAdvanced(orders[i]);\n }\n }\n\n // Return the array of advanced orders.\n return advancedOrders;\n }\n}\n" - }, - "seaport/contracts/lib/AmountDeriver.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\n// prettier-ignore\nimport {\n AmountDerivationErrors\n} from \"../interfaces/AmountDerivationErrors.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title AmountDeriver\n * @author 0age\n * @notice AmountDeriver contains view and pure functions related to deriving\n * item amounts based on partial fill quantity and on linear\n * interpolation based on current time when the start amount and end\n * amount differ.\n */\ncontract AmountDeriver is AmountDerivationErrors {\n /**\n * @dev Internal view function to derive the current amount of a given item\n * based on the current price, the starting price, and the ending\n * price. If the start and end prices differ, the current price will be\n * interpolated on a linear basis. Note that this function expects that\n * the startTime parameter of orderParameters is not greater than the\n * current block timestamp and that the endTime parameter is greater\n * than the current block timestamp. If this condition is not upheld,\n * duration / elapsed / remaining variables will underflow.\n *\n * @param startAmount The starting amount of the item.\n * @param endAmount The ending amount of the item.\n * @param startTime The starting time of the order.\n * @param endTime The end time of the order.\n * @param roundUp A boolean indicating whether the resultant amount\n * should be rounded up or down.\n *\n * @return amount The current amount.\n */\n function _locateCurrentAmount(\n uint256 startAmount,\n uint256 endAmount,\n uint256 startTime,\n uint256 endTime,\n bool roundUp\n ) internal view returns (uint256 amount) {\n // Only modify end amount if it doesn't already equal start amount.\n if (startAmount != endAmount) {\n // Declare variables to derive in the subsequent unchecked scope.\n uint256 duration;\n uint256 elapsed;\n uint256 remaining;\n\n // Skip underflow checks as startTime <= block.timestamp < endTime.\n unchecked {\n // Derive the duration for the order and place it on the stack.\n duration = endTime - startTime;\n\n // Derive time elapsed since the order started & place on stack.\n elapsed = block.timestamp - startTime;\n\n // Derive time remaining until order expires and place on stack.\n remaining = duration - elapsed;\n }\n\n // Aggregate new amounts weighted by time with rounding factor.\n uint256 totalBeforeDivision = ((startAmount * remaining) +\n (endAmount * elapsed));\n\n // Use assembly to combine operations and skip divide-by-zero check.\n assembly {\n // Multiply by iszero(iszero(totalBeforeDivision)) to ensure\n // amount is set to zero if totalBeforeDivision is zero,\n // as intermediate overflow can occur if it is zero.\n amount := mul(\n iszero(iszero(totalBeforeDivision)),\n // Subtract 1 from the numerator and add 1 to the result if\n // roundUp is true to get the proper rounding direction.\n // Division is performed with no zero check as duration\n // cannot be zero as long as startTime < endTime.\n add(\n div(sub(totalBeforeDivision, roundUp), duration),\n roundUp\n )\n )\n }\n\n // Return the current amount.\n return amount;\n }\n\n // Return the original amount as startAmount == endAmount.\n return endAmount;\n }\n\n /**\n * @dev Internal pure function to return a fraction of a given value and to\n * ensure the resultant value does not have any fractional component.\n * Note that this function assumes that zero will never be supplied as\n * the denominator parameter; invalid / undefined behavior will result\n * should a denominator of zero be provided.\n *\n * @param numerator A value indicating the portion of the order that\n * should be filled.\n * @param denominator A value indicating the total size of the order. Note\n * that this value cannot be equal to zero.\n * @param value The value for which to compute the fraction.\n *\n * @return newValue The value after applying the fraction.\n */\n function _getFraction(\n uint256 numerator,\n uint256 denominator,\n uint256 value\n ) internal pure returns (uint256 newValue) {\n // Return value early in cases where the fraction resolves to 1.\n if (numerator == denominator) {\n return value;\n }\n\n // Ensure fraction can be applied to the value with no remainder. Note\n // that the denominator cannot be zero.\n assembly {\n // Ensure new value contains no remainder via mulmod operator.\n // Credit to @hrkrshnn + @axic for proposing this optimal solution.\n if mulmod(value, numerator, denominator) {\n mstore(0, InexactFraction_error_signature)\n revert(0, InexactFraction_error_len)\n }\n }\n\n // Multiply the numerator by the value and ensure no overflow occurs.\n uint256 valueTimesNumerator = value * numerator;\n\n // Divide and check for remainder. Note that denominator cannot be zero.\n assembly {\n // Perform division without zero check.\n newValue := div(valueTimesNumerator, denominator)\n }\n }\n\n /**\n * @dev Internal view function to apply a fraction to a consideration\n * or offer item.\n *\n * @param startAmount The starting amount of the item.\n * @param endAmount The ending amount of the item.\n * @param numerator A value indicating the portion of the order that\n * should be filled.\n * @param denominator A value indicating the total size of the order.\n * @param startTime The starting time of the order.\n * @param endTime The end time of the order.\n * @param roundUp A boolean indicating whether the resultant\n * amount should be rounded up or down.\n *\n * @return amount The received item to transfer with the final amount.\n */\n function _applyFraction(\n uint256 startAmount,\n uint256 endAmount,\n uint256 numerator,\n uint256 denominator,\n uint256 startTime,\n uint256 endTime,\n bool roundUp\n ) internal view returns (uint256 amount) {\n // If start amount equals end amount, apply fraction to end amount.\n if (startAmount == endAmount) {\n // Apply fraction to end amount.\n amount = _getFraction(numerator, denominator, endAmount);\n } else {\n // Otherwise, apply fraction to both and interpolated final amount.\n amount = _locateCurrentAmount(\n _getFraction(numerator, denominator, startAmount),\n _getFraction(numerator, denominator, endAmount),\n startTime,\n endTime,\n roundUp\n );\n }\n }\n}\n" - }, - "seaport/contracts/interfaces/AmountDerivationErrors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n/**\n * @title AmountDerivationErrors\n * @author 0age\n * @notice AmountDerivationErrors contains errors related to amount derivation.\n */\ninterface AmountDerivationErrors {\n /**\n * @dev Revert with an error when attempting to apply a fraction as part of\n * a partial fill that does not divide the target amount cleanly.\n */\n error InexactFraction();\n}\n" - }, - "seaport/contracts/lib/OrderCombiner.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { Side, ItemType } from \"./ConsiderationEnums.sol\";\n\n// prettier-ignore\nimport {\n OfferItem,\n ConsiderationItem,\n ReceivedItem,\n OrderParameters,\n Fulfillment,\n FulfillmentComponent,\n Execution,\n Order,\n AdvancedOrder,\n CriteriaResolver\n} from \"./ConsiderationStructs.sol\";\n\nimport { OrderFulfiller } from \"./OrderFulfiller.sol\";\n\nimport { FulfillmentApplier } from \"./FulfillmentApplier.sol\";\n\nimport \"./ConsiderationConstants.sol\";\n\n/**\n * @title OrderCombiner\n * @author 0age\n * @notice OrderCombiner contains logic for fulfilling combinations of orders,\n * either by matching offer items to consideration items or by\n * fulfilling orders where available.\n */\ncontract OrderCombiner is OrderFulfiller, FulfillmentApplier {\n /**\n * @dev Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) OrderFulfiller(conduitController) {}\n\n /**\n * @notice Internal function to attempt to fill a group of orders, fully or\n * partially, with an arbitrary number of items for offer and\n * consideration per order alongside criteria resolvers containing\n * specific token identifiers and associated proofs. Any order that\n * is not currently active, has already been fully filled, or has\n * been cancelled will be omitted. Remaining offer and consideration\n * items will then be aggregated where possible as indicated by the\n * supplied offer and consideration component arrays and aggregated\n * items will be transferred to the fulfiller or to each intended\n * recipient, respectively. Note that a failing item transfer or an\n * issue with order formatting will cause the entire batch to fail.\n *\n * @param advancedOrders The orders to fulfill along with the\n * fraction of those orders to attempt to\n * fill. Note that both the offerer and the\n * fulfiller must first approve this\n * contract (or a conduit if indicated by\n * the order) to transfer any relevant\n * tokens on their behalf and that\n * contracts must implement\n * `onERC1155Received` in order to receive\n * ERC1155 tokens as consideration. Also\n * note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount\n * with the supplied fraction for an\n * order's partial fill amount to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a\n * proof that the supplied token identifier\n * is contained in the merkle root held by\n * the item in question's criteria element.\n * Note that an empty criteria indicates\n * that any (transferable) token\n * identifier on the token in question is\n * valid and that no associated proof needs\n * to be supplied.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used (and\n * direct approvals set on Consideration).\n * @param recipient The intended recipient for all received\n * items.\n * @param maximumFulfilled The maximum number of orders to fulfill.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function _fulfillAvailableAdvancedOrders(\n AdvancedOrder[] memory advancedOrders,\n CriteriaResolver[] memory criteriaResolvers,\n FulfillmentComponent[][] calldata offerFulfillments,\n FulfillmentComponent[][] calldata considerationFulfillments,\n bytes32 fulfillerConduitKey,\n address recipient,\n uint256 maximumFulfilled\n )\n internal\n returns (bool[] memory availableOrders, Execution[] memory executions)\n {\n // Validate orders, apply amounts, & determine if they utilize conduits.\n _validateOrdersAndPrepareToFulfill(\n advancedOrders,\n criteriaResolvers,\n false, // Signifies that invalid orders should NOT revert.\n maximumFulfilled,\n recipient\n );\n\n // Aggregate used offer and consideration items and execute transfers.\n (availableOrders, executions) = _executeAvailableFulfillments(\n advancedOrders,\n offerFulfillments,\n considerationFulfillments,\n fulfillerConduitKey,\n recipient\n );\n\n // Return order fulfillment details and executions.\n return (availableOrders, executions);\n }\n\n /**\n * @dev Internal function to validate a group of orders, update their\n * statuses, reduce amounts by their previously filled fractions, apply\n * criteria resolvers, and emit OrderFulfilled events.\n *\n * @param advancedOrders The advanced orders to validate and reduce by\n * their previously filled amounts.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific order as well as that order's\n * offer or consideration, a token identifier, and\n * a proof that the supplied token identifier is\n * contained in the order's merkle root. Note that\n * a root of zero indicates that any transferable\n * token identifier is valid and that no proof\n * needs to be supplied.\n * @param revertOnInvalid A boolean indicating whether to revert on any\n * order being invalid; setting this to false will\n * instead cause the invalid order to be skipped.\n * @param maximumFulfilled The maximum number of orders to fulfill.\n * @param recipient The intended recipient for all received items.\n */\n function _validateOrdersAndPrepareToFulfill(\n AdvancedOrder[] memory advancedOrders,\n CriteriaResolver[] memory criteriaResolvers,\n bool revertOnInvalid,\n uint256 maximumFulfilled,\n address recipient\n ) internal {\n // Ensure this function cannot be triggered during a reentrant call.\n _setReentrancyGuard();\n\n // Read length of orders array and place on the stack.\n uint256 totalOrders = advancedOrders.length;\n\n // Track the order hash for each order being fulfilled.\n bytes32[] memory orderHashes = new bytes32[](totalOrders);\n\n // Override orderHashes length to zero after memory has been allocated.\n assembly {\n mstore(orderHashes, 0)\n }\n\n // Declare an error buffer indicating status of any native offer items.\n // {00} == 0 => In a match function, no native offer items: allow.\n // {01} == 1 => In a match function, some native offer items: allow.\n // {10} == 2 => Not in a match function, no native offer items: allow.\n // {11} == 3 => Not in a match function, some native offer items: THROW.\n uint256 invalidNativeOfferItemErrorBuffer;\n\n // Use assembly to set the value for the second bit of the error buffer.\n assembly {\n // Use the second bit of the error buffer to indicate whether the\n // current function is not matchAdvancedOrders or matchOrders.\n invalidNativeOfferItemErrorBuffer := shl(\n 1,\n gt(\n // Take the remainder of the selector modulo a magic value.\n mod(\n shr(NumBitsAfterSelector, calldataload(0)),\n NonMatchSelector_MagicModulus\n ),\n // Check if remainder is higher than the greatest remainder\n // of the two match selectors modulo the magic value.\n NonMatchSelector_MagicRemainder\n )\n )\n }\n\n // Skip overflow checks as all for loops are indexed starting at zero.\n unchecked {\n // Iterate over each order.\n for (uint256 i = 0; i < totalOrders; ++i) {\n // Retrieve the current order.\n AdvancedOrder memory advancedOrder = advancedOrders[i];\n\n // Determine if max number orders have already been fulfilled.\n if (maximumFulfilled == 0) {\n // Mark fill fraction as zero as the order will not be used.\n advancedOrder.numerator = 0;\n\n // Update the length of the orderHashes array.\n assembly {\n mstore(orderHashes, add(i, 1))\n }\n\n // Continue iterating through the remaining orders.\n continue;\n }\n\n // Validate it, update status, and determine fraction to fill.\n (\n bytes32 orderHash,\n uint256 numerator,\n uint256 denominator\n ) = _validateOrderAndUpdateStatus(\n advancedOrder,\n criteriaResolvers,\n revertOnInvalid,\n orderHashes\n );\n\n // Update the length of the orderHashes array.\n assembly {\n mstore(orderHashes, add(i, 1))\n }\n\n // Do not track hash or adjust prices if order is not fulfilled.\n if (numerator == 0) {\n // Mark fill fraction as zero if the order is not fulfilled.\n advancedOrder.numerator = 0;\n\n // Continue iterating through the remaining orders.\n continue;\n }\n\n // Otherwise, track the order hash in question.\n orderHashes[i] = orderHash;\n\n // Decrement the number of fulfilled orders.\n // Skip underflow check as the condition before\n // implies that maximumFulfilled > 0.\n maximumFulfilled--;\n\n // Place the start time for the order on the stack.\n uint256 startTime = advancedOrder.parameters.startTime;\n\n // Place the end time for the order on the stack.\n uint256 endTime = advancedOrder.parameters.endTime;\n\n // Retrieve array of offer items for the order in question.\n OfferItem[] memory offer = advancedOrder.parameters.offer;\n\n // Read length of offer array and place on the stack.\n uint256 totalOfferItems = offer.length;\n\n // Iterate over each offer item on the order.\n for (uint256 j = 0; j < totalOfferItems; ++j) {\n // Retrieve the offer item.\n OfferItem memory offerItem = offer[j];\n\n assembly {\n // If the offer item is for the native token, set the\n // first bit of the error buffer to true.\n invalidNativeOfferItemErrorBuffer := or(\n invalidNativeOfferItemErrorBuffer,\n iszero(mload(offerItem))\n )\n }\n\n // Apply order fill fraction to offer item end amount.\n uint256 endAmount = _getFraction(\n numerator,\n denominator,\n offerItem.endAmount\n );\n\n // Reuse same fraction if start and end amounts are equal.\n if (offerItem.startAmount == offerItem.endAmount) {\n // Apply derived amount to both start and end amount.\n offerItem.startAmount = endAmount;\n } else {\n // Apply order fill fraction to offer item start amount.\n offerItem.startAmount = _getFraction(\n numerator,\n denominator,\n offerItem.startAmount\n );\n }\n\n // Update end amount in memory to match the derived amount.\n offerItem.endAmount = endAmount;\n\n // Adjust offer amount using current time; round down.\n offerItem.startAmount = _locateCurrentAmount(\n offerItem.startAmount,\n offerItem.endAmount,\n startTime,\n endTime,\n false // round down\n );\n }\n\n // Retrieve array of consideration items for order in question.\n ConsiderationItem[] memory consideration = (\n advancedOrder.parameters.consideration\n );\n\n // Read length of consideration array and place on the stack.\n uint256 totalConsiderationItems = consideration.length;\n\n // Iterate over each consideration item on the order.\n for (uint256 j = 0; j < totalConsiderationItems; ++j) {\n // Retrieve the consideration item.\n ConsiderationItem memory considerationItem = (\n consideration[j]\n );\n\n // Apply fraction to consideration item end amount.\n uint256 endAmount = _getFraction(\n numerator,\n denominator,\n considerationItem.endAmount\n );\n\n // Reuse same fraction if start and end amounts are equal.\n if (\n considerationItem.startAmount ==\n considerationItem.endAmount\n ) {\n // Apply derived amount to both start and end amount.\n considerationItem.startAmount = endAmount;\n } else {\n // Apply fraction to consideration item start amount.\n considerationItem.startAmount = _getFraction(\n numerator,\n denominator,\n considerationItem.startAmount\n );\n }\n\n // Update end amount in memory to match the derived amount.\n considerationItem.endAmount = endAmount;\n\n // Adjust consideration amount using current time; round up.\n considerationItem.startAmount = (\n _locateCurrentAmount(\n considerationItem.startAmount,\n considerationItem.endAmount,\n startTime,\n endTime,\n true // round up\n )\n );\n\n // Utilize assembly to manually \"shift\" the recipient value.\n assembly {\n // Write recipient to endAmount, as endAmount is not\n // used from this point on and can be repurposed to fit\n // the layout of a ReceivedItem.\n mstore(\n add(\n considerationItem,\n ReceivedItem_recipient_offset // old endAmount\n ),\n mload(\n add(\n considerationItem,\n ConsiderationItem_recipient_offset\n )\n )\n )\n }\n }\n }\n }\n\n // If the first bit is set, a native offer item was encountered. If the\n // second bit is set in the error buffer, the current function is not\n // matchOrders or matchAdvancedOrders. If the value is three, both the\n // first and second bits were set; in that case, revert with an error.\n if (invalidNativeOfferItemErrorBuffer == 3) {\n revert InvalidNativeOfferItem();\n }\n\n // Apply criteria resolvers to each order as applicable.\n _applyCriteriaResolvers(advancedOrders, criteriaResolvers);\n\n // Emit an event for each order signifying that it has been fulfilled.\n // Skip overflow checks as all for loops are indexed starting at zero.\n unchecked {\n // Iterate over each order.\n for (uint256 i = 0; i < totalOrders; ++i) {\n // Do not emit an event if no order hash is present.\n if (orderHashes[i] == bytes32(0)) {\n continue;\n }\n\n // Retrieve parameters for the order in question.\n OrderParameters memory orderParameters = (\n advancedOrders[i].parameters\n );\n\n // Emit an OrderFulfilled event.\n _emitOrderFulfilledEvent(\n orderHashes[i],\n orderParameters.offerer,\n orderParameters.zone,\n recipient,\n orderParameters.offer,\n orderParameters.consideration\n );\n }\n }\n }\n\n /**\n * @dev Internal function to fulfill a group of validated orders, fully or\n * partially, with an arbitrary number of items for offer and\n * consideration per order and to execute transfers. Any order that is\n * not currently active, has already been fully filled, or has been\n * cancelled will be omitted. Remaining offer and consideration items\n * will then be aggregated where possible as indicated by the supplied\n * offer and consideration component arrays and aggregated items will\n * be transferred to the fulfiller or to each intended recipient,\n * respectively. Note that a failing item transfer or an issue with\n * order formatting will cause the entire batch to fail.\n *\n * @param advancedOrders The orders to fulfill along with the\n * fraction of those orders to attempt to\n * fill. Note that both the offerer and the\n * fulfiller must first approve this\n * contract (or the conduit if indicated by\n * the order) to transfer any relevant\n * tokens on their behalf and that\n * contracts must implement\n * `onERC1155Received` in order to receive\n * ERC1155 tokens as consideration. Also\n * note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount\n * with the supplied fraction for an\n * order's partial fill amount to be\n * considered valid.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used, with\n * direct approvals set on Consideration.\n * @param recipient The intended recipient for all received\n * items.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function _executeAvailableFulfillments(\n AdvancedOrder[] memory advancedOrders,\n FulfillmentComponent[][] memory offerFulfillments,\n FulfillmentComponent[][] memory considerationFulfillments,\n bytes32 fulfillerConduitKey,\n address recipient\n )\n internal\n returns (bool[] memory availableOrders, Execution[] memory executions)\n {\n // Retrieve length of offer fulfillments array and place on the stack.\n uint256 totalOfferFulfillments = offerFulfillments.length;\n\n // Retrieve length of consideration fulfillments array & place on stack.\n uint256 totalConsiderationFulfillments = (\n considerationFulfillments.length\n );\n\n // Allocate an execution for each offer and consideration fulfillment.\n executions = new Execution[](\n totalOfferFulfillments + totalConsiderationFulfillments\n );\n\n // Skip overflow checks as all for loops are indexed starting at zero.\n unchecked {\n // Track number of filtered executions.\n uint256 totalFilteredExecutions = 0;\n\n // Iterate over each offer fulfillment.\n for (uint256 i = 0; i < totalOfferFulfillments; ++i) {\n /// Retrieve the offer fulfillment components in question.\n FulfillmentComponent[] memory components = (\n offerFulfillments[i]\n );\n\n // Derive aggregated execution corresponding with fulfillment.\n Execution memory execution = _aggregateAvailable(\n advancedOrders,\n Side.OFFER,\n components,\n fulfillerConduitKey,\n recipient\n );\n\n // If offerer and recipient on the execution are the same...\n if (execution.item.recipient == execution.offerer) {\n // Increment total filtered executions.\n ++totalFilteredExecutions;\n } else {\n // Otherwise, assign the execution to the executions array.\n executions[i - totalFilteredExecutions] = execution;\n }\n }\n\n // Iterate over each consideration fulfillment.\n for (uint256 i = 0; i < totalConsiderationFulfillments; ++i) {\n /// Retrieve consideration fulfillment components in question.\n FulfillmentComponent[] memory components = (\n considerationFulfillments[i]\n );\n\n // Derive aggregated execution corresponding with fulfillment.\n Execution memory execution = _aggregateAvailable(\n advancedOrders,\n Side.CONSIDERATION,\n components,\n fulfillerConduitKey,\n address(0) // unused\n );\n\n // If offerer and recipient on the execution are the same...\n if (execution.item.recipient == execution.offerer) {\n // Increment total filtered executions.\n ++totalFilteredExecutions;\n } else {\n // Otherwise, assign the execution to the executions array.\n executions[\n i + totalOfferFulfillments - totalFilteredExecutions\n ] = execution;\n }\n }\n\n // If some number of executions have been filtered...\n if (totalFilteredExecutions != 0) {\n // reduce the total length of the executions array.\n assembly {\n mstore(\n executions,\n sub(mload(executions), totalFilteredExecutions)\n )\n }\n }\n }\n\n // Revert if no orders are available.\n if (executions.length == 0) {\n revert NoSpecifiedOrdersAvailable();\n }\n\n // Perform final checks and return.\n availableOrders = _performFinalChecksAndExecuteOrders(\n advancedOrders,\n executions\n );\n\n return (availableOrders, executions);\n }\n\n /**\n * @dev Internal function to perform a final check that each consideration\n * item for an arbitrary number of fulfilled orders has been met and to\n * trigger associated executions, transferring the respective items.\n *\n * @param advancedOrders The orders to check and perform executions for.\n * @param executions An array of elements indicating the sequence of\n * transfers to perform when fulfilling the given\n * orders.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n */\n function _performFinalChecksAndExecuteOrders(\n AdvancedOrder[] memory advancedOrders,\n Execution[] memory executions\n ) internal returns (bool[] memory availableOrders) {\n // Retrieve the length of the advanced orders array and place on stack.\n uint256 totalOrders = advancedOrders.length;\n\n // Initialize array for tracking available orders.\n availableOrders = new bool[](totalOrders);\n\n // Skip overflow checks as all for loops are indexed starting at zero.\n unchecked {\n // Iterate over orders to ensure all considerations are met.\n for (uint256 i = 0; i < totalOrders; ++i) {\n // Retrieve the order in question.\n AdvancedOrder memory advancedOrder = advancedOrders[i];\n\n // Skip consideration item checks for order if not fulfilled.\n if (advancedOrder.numerator == 0) {\n // Note: orders do not need to be marked as unavailable as a\n // new memory region has been allocated. Review carefully if\n // altering compiler version or managing memory manually.\n continue;\n }\n\n // Mark the order as available.\n availableOrders[i] = true;\n\n // Retrieve consideration items to ensure they are fulfilled.\n ConsiderationItem[] memory consideration = (\n advancedOrder.parameters.consideration\n );\n\n // Read length of consideration array and place on the stack.\n uint256 totalConsiderationItems = consideration.length;\n\n // Iterate over each consideration item to ensure it is met.\n for (uint256 j = 0; j < totalConsiderationItems; ++j) {\n // Retrieve remaining amount on the consideration item.\n uint256 unmetAmount = consideration[j].startAmount;\n\n // Revert if the remaining amount is not zero.\n if (unmetAmount != 0) {\n revert ConsiderationNotMet(i, j, unmetAmount);\n }\n }\n }\n }\n\n // Put ether value supplied by the caller on the stack.\n uint256 etherRemaining = msg.value;\n\n // Initialize an accumulator array. From this point forward, no new\n // memory regions can be safely allocated until the accumulator is no\n // longer being utilized, as the accumulator operates in an open-ended\n // fashion from this memory pointer; existing memory may still be\n // accessed and modified, however.\n bytes memory accumulator = new bytes(AccumulatorDisarmed);\n\n // Retrieve the length of the executions array and place on stack.\n uint256 totalExecutions = executions.length;\n\n // Iterate over each execution.\n for (uint256 i = 0; i < totalExecutions; ) {\n // Retrieve the execution and the associated received item.\n Execution memory execution = executions[i];\n ReceivedItem memory item = execution.item;\n\n // If execution transfers native tokens, reduce value available.\n if (item.itemType == ItemType.NATIVE) {\n // Ensure that sufficient native tokens are still available.\n if (item.amount > etherRemaining) {\n revert InsufficientEtherSupplied();\n }\n\n // Skip underflow check as amount is less than ether remaining.\n unchecked {\n etherRemaining -= item.amount;\n }\n }\n\n // Transfer the item specified by the execution.\n _transfer(\n item,\n execution.offerer,\n execution.conduitKey,\n accumulator\n );\n\n // Skip overflow check as for loop is indexed starting at zero.\n unchecked {\n ++i;\n }\n }\n\n // Trigger any remaining accumulated transfers via call to the conduit.\n _triggerIfArmed(accumulator);\n\n // If any ether remains after fulfillments, return it to the caller.\n if (etherRemaining != 0) {\n _transferEth(payable(msg.sender), etherRemaining);\n }\n\n // Clear the reentrancy guard.\n _clearReentrancyGuard();\n\n // Return the array containing available orders.\n return (availableOrders);\n }\n\n /**\n * @dev Internal function to match an arbitrary number of full or partial\n * orders, each with an arbitrary number of items for offer and\n * consideration, supplying criteria resolvers containing specific\n * token identifiers and associated proofs as well as fulfillments\n * allocating offer components to consideration components.\n *\n * @param advancedOrders The advanced orders to match. Note that both the\n * offerer and fulfiller on each order must first\n * approve this contract (or their conduit if\n * indicated by the order) to transfer any relevant\n * tokens on their behalf and each consideration\n * recipient must implement `onERC1155Received` in\n * order to receive ERC1155 tokens. Also note that\n * the offer and consideration components for each\n * order must have no remainder after multiplying\n * the respective amount with the supplied fraction\n * in order for the group of partial fills to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific order as well as that order's\n * offer or consideration, a token identifier, and\n * a proof that the supplied token identifier is\n * contained in the order's merkle root. Note that\n * an empty root indicates that any (transferable)\n * token identifier is valid and that no associated\n * proof needs to be supplied.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components. Note that each\n * consideration component must be fully met in\n * order for the match operation to be valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function _matchAdvancedOrders(\n AdvancedOrder[] memory advancedOrders,\n CriteriaResolver[] memory criteriaResolvers,\n Fulfillment[] calldata fulfillments\n ) internal returns (Execution[] memory executions) {\n // Validate orders, update order status, and determine item amounts.\n _validateOrdersAndPrepareToFulfill(\n advancedOrders,\n criteriaResolvers,\n true, // Signifies that invalid orders should revert.\n advancedOrders.length,\n address(0) // OrderFulfilled event has no recipient when matching.\n );\n\n // Fulfill the orders using the supplied fulfillments.\n return _fulfillAdvancedOrders(advancedOrders, fulfillments);\n }\n\n /**\n * @dev Internal function to fulfill an arbitrary number of orders, either\n * full or partial, after validating, adjusting amounts, and applying\n * criteria resolvers.\n *\n * @param advancedOrders The orders to match, including a fraction to\n * attempt to fill for each order.\n * @param fulfillments An array of elements allocating offer\n * components to consideration components. Note\n * that the final amount of each consideration\n * component must be zero for a match operation to\n * be considered valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function _fulfillAdvancedOrders(\n AdvancedOrder[] memory advancedOrders,\n Fulfillment[] calldata fulfillments\n ) internal returns (Execution[] memory executions) {\n // Retrieve fulfillments array length and place on the stack.\n uint256 totalFulfillments = fulfillments.length;\n\n // Allocate executions by fulfillment and apply them to each execution.\n executions = new Execution[](totalFulfillments);\n\n // Skip overflow checks as all for loops are indexed starting at zero.\n unchecked {\n // Track number of filtered executions.\n uint256 totalFilteredExecutions = 0;\n\n // Iterate over each fulfillment.\n for (uint256 i = 0; i < totalFulfillments; ++i) {\n /// Retrieve the fulfillment in question.\n Fulfillment calldata fulfillment = fulfillments[i];\n\n // Derive the execution corresponding with the fulfillment.\n Execution memory execution = _applyFulfillment(\n advancedOrders,\n fulfillment.offerComponents,\n fulfillment.considerationComponents\n );\n\n // If offerer and recipient on the execution are the same...\n if (execution.item.recipient == execution.offerer) {\n // Increment total filtered executions.\n ++totalFilteredExecutions;\n } else {\n // Otherwise, assign the execution to the executions array.\n executions[i - totalFilteredExecutions] = execution;\n }\n }\n\n // If some number of executions have been filtered...\n if (totalFilteredExecutions != 0) {\n // reduce the total length of the executions array.\n assembly {\n mstore(\n executions,\n sub(mload(executions), totalFilteredExecutions)\n )\n }\n }\n }\n\n // Perform final checks and execute orders.\n _performFinalChecksAndExecuteOrders(advancedOrders, executions);\n\n // Return the executions array.\n return (executions);\n }\n}\n" - }, - "seaport/contracts/lib/Consideration.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\n// prettier-ignore\nimport {\n ConsiderationInterface\n} from \"../interfaces/ConsiderationInterface.sol\";\n\n// prettier-ignore\nimport {\n OrderComponents,\n BasicOrderParameters,\n OrderParameters,\n Order,\n AdvancedOrder,\n OrderStatus,\n CriteriaResolver,\n Fulfillment,\n FulfillmentComponent,\n Execution\n} from \"./ConsiderationStructs.sol\";\n\nimport { OrderCombiner } from \"./OrderCombiner.sol\";\n\n/**\n * @title Consideration\n * @author 0age\n * @custom:coauthor d1ll0n\n * @custom:coauthor transmissions11\n * @custom:version 1.1\n * @notice Consideration is a generalized ETH/ERC20/ERC721/ERC1155 marketplace.\n * It minimizes external calls to the greatest extent possible and\n * provides lightweight methods for common routes as well as more\n * flexible methods for composing advanced orders or groups of orders.\n * Each order contains an arbitrary number of items that may be spent\n * (the \"offer\") along with an arbitrary number of items that must be\n * received back by the indicated recipients (the \"consideration\").\n */\ncontract Consideration is ConsiderationInterface, OrderCombiner {\n /**\n * @notice Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) OrderCombiner(conduitController) {}\n\n /**\n * @notice Fulfill an order offering an ERC20, ERC721, or ERC1155 item by\n * supplying Ether (or other native tokens), ERC20 tokens, an ERC721\n * item, or an ERC1155 item as consideration. Six permutations are\n * supported: Native token to ERC721, Native token to ERC1155, ERC20\n * to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and ERC1155 to\n * ERC20 (with native tokens supplied as msg.value). For an order to\n * be eligible for fulfillment via this method, it must contain a\n * single offer item (though that item may have a greater amount if\n * the item is not an ERC721). An arbitrary number of \"additional\n * recipients\" may also be supplied which will each receive native\n * tokens or ERC20 items from the fulfiller as consideration. Refer\n * to the documentation for a more comprehensive summary of how to\n * utilize this method and what orders are compatible with it.\n *\n * @param parameters Additional information on the fulfilled order. Note\n * that the offerer and the fulfiller must first approve\n * this contract (or their chosen conduit if indicated)\n * before any tokens can be transferred. Also note that\n * contract recipients of ERC1155 consideration items must\n * implement `onERC1155Received` in order to receive those\n * items.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillBasicOrder(BasicOrderParameters calldata parameters)\n external\n payable\n override\n returns (bool fulfilled)\n {\n // Validate and fulfill the basic order.\n fulfilled = _validateAndFulfillBasicOrder(parameters);\n }\n\n /**\n * @notice Fulfill an order with an arbitrary number of items for offer and\n * consideration. Note that this function does not support\n * criteria-based orders or partial filling of orders (though\n * filling the remainder of a partially-filled order is supported).\n *\n * @param order The order to fulfill. Note that both the\n * offerer and the fulfiller must first approve\n * this contract (or the corresponding conduit if\n * indicated) to transfer any relevant tokens on\n * their behalf and that contracts must implement\n * `onERC1155Received` to receive ERC1155 tokens\n * as consideration.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used (and direct approvals set on\n * Consideration).\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillOrder(Order calldata order, bytes32 fulfillerConduitKey)\n external\n payable\n override\n returns (bool fulfilled)\n {\n // Convert order to \"advanced\" order, then validate and fulfill it.\n fulfilled = _validateAndFulfillAdvancedOrder(\n _convertOrderToAdvanced(order),\n new CriteriaResolver[](0), // No criteria resolvers supplied.\n fulfillerConduitKey,\n msg.sender\n );\n }\n\n /**\n * @notice Fill an order, fully or partially, with an arbitrary number of\n * items for offer and consideration alongside criteria resolvers\n * containing specific token identifiers and associated proofs.\n *\n * @param advancedOrder The order to fulfill along with the fraction\n * of the order to attempt to fill. Note that\n * both the offerer and the fulfiller must first\n * approve this contract (or their conduit if\n * indicated by the order) to transfer any\n * relevant tokens on their behalf and that\n * contracts must implement `onERC1155Received`\n * to receive ERC1155 tokens as consideration.\n * Also note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount with\n * the supplied fraction for the partial fill to\n * be considered valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a proof\n * that the supplied token identifier is\n * contained in the merkle root held by the item\n * in question's criteria element. Note that an\n * empty criteria indicates that any\n * (transferable) token identifier on the token\n * in question is valid and that no associated\n * proof needs to be supplied.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used (and direct approvals set on\n * Consideration).\n * @param recipient The intended recipient for all received items,\n * with `address(0)` indicating that the caller\n * should receive the items.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillAdvancedOrder(\n AdvancedOrder calldata advancedOrder,\n CriteriaResolver[] calldata criteriaResolvers,\n bytes32 fulfillerConduitKey,\n address recipient\n ) external payable override returns (bool fulfilled) {\n // Validate and fulfill the order.\n fulfilled = _validateAndFulfillAdvancedOrder(\n advancedOrder,\n criteriaResolvers,\n fulfillerConduitKey,\n recipient == address(0) ? msg.sender : recipient\n );\n }\n\n /**\n * @notice Attempt to fill a group of orders, each with an arbitrary number\n * of items for offer and consideration. Any order that is not\n * currently active, has already been fully filled, or has been\n * cancelled will be omitted. Remaining offer and consideration\n * items will then be aggregated where possible as indicated by the\n * supplied offer and consideration component arrays and aggregated\n * items will be transferred to the fulfiller or to each intended\n * recipient, respectively. Note that a failing item transfer or an\n * issue with order formatting will cause the entire batch to fail.\n * Note that this function does not support criteria-based orders or\n * partial filling of orders (though filling the remainder of a\n * partially-filled order is supported).\n *\n * @param orders The orders to fulfill. Note that both\n * the offerer and the fulfiller must first\n * approve this contract (or the\n * corresponding conduit if indicated) to\n * transfer any relevant tokens on their\n * behalf and that contracts must implement\n * `onERC1155Received` to receive ERC1155\n * tokens as consideration.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used (and\n * direct approvals set on Consideration).\n * @param maximumFulfilled The maximum number of orders to fulfill.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function fulfillAvailableOrders(\n Order[] calldata orders,\n FulfillmentComponent[][] calldata offerFulfillments,\n FulfillmentComponent[][] calldata considerationFulfillments,\n bytes32 fulfillerConduitKey,\n uint256 maximumFulfilled\n )\n external\n payable\n override\n returns (bool[] memory availableOrders, Execution[] memory executions)\n {\n // Convert orders to \"advanced\" orders and fulfill all available orders.\n return\n _fulfillAvailableAdvancedOrders(\n _convertOrdersToAdvanced(orders), // Convert to advanced orders.\n new CriteriaResolver[](0), // No criteria resolvers supplied.\n offerFulfillments,\n considerationFulfillments,\n fulfillerConduitKey,\n msg.sender,\n maximumFulfilled\n );\n }\n\n /**\n * @notice Attempt to fill a group of orders, fully or partially, with an\n * arbitrary number of items for offer and consideration per order\n * alongside criteria resolvers containing specific token\n * identifiers and associated proofs. Any order that is not\n * currently active, has already been fully filled, or has been\n * cancelled will be omitted. Remaining offer and consideration\n * items will then be aggregated where possible as indicated by the\n * supplied offer and consideration component arrays and aggregated\n * items will be transferred to the fulfiller or to each intended\n * recipient, respectively. Note that a failing item transfer or an\n * issue with order formatting will cause the entire batch to fail.\n *\n * @param advancedOrders The orders to fulfill along with the\n * fraction of those orders to attempt to\n * fill. Note that both the offerer and the\n * fulfiller must first approve this\n * contract (or their conduit if indicated\n * by the order) to transfer any relevant\n * tokens on their behalf and that\n * contracts must implement\n * `onERC1155Received` in order to receive\n * ERC1155 tokens as consideration. Also\n * note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount\n * with the supplied fraction for an\n * order's partial fill amount to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a\n * proof that the supplied token identifier\n * is contained in the merkle root held by\n * the item in question's criteria element.\n * Note that an empty criteria indicates\n * that any (transferable) token\n * identifier on the token in question is\n * valid and that no associated proof needs\n * to be supplied.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used (and\n * direct approvals set on Consideration).\n * @param recipient The intended recipient for all received\n * items, with `address(0)` indicating that\n * the caller should receive the items.\n * @param maximumFulfilled The maximum number of orders to fulfill.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function fulfillAvailableAdvancedOrders(\n AdvancedOrder[] memory advancedOrders,\n CriteriaResolver[] calldata criteriaResolvers,\n FulfillmentComponent[][] calldata offerFulfillments,\n FulfillmentComponent[][] calldata considerationFulfillments,\n bytes32 fulfillerConduitKey,\n address recipient,\n uint256 maximumFulfilled\n )\n external\n payable\n override\n returns (bool[] memory availableOrders, Execution[] memory executions)\n {\n // Fulfill all available orders.\n return\n _fulfillAvailableAdvancedOrders(\n advancedOrders,\n criteriaResolvers,\n offerFulfillments,\n considerationFulfillments,\n fulfillerConduitKey,\n recipient == address(0) ? msg.sender : recipient,\n maximumFulfilled\n );\n }\n\n /**\n * @notice Match an arbitrary number of orders, each with an arbitrary\n * number of items for offer and consideration along with a set of\n * fulfillments allocating offer components to consideration\n * components. Note that this function does not support\n * criteria-based or partial filling of orders (though filling the\n * remainder of a partially-filled order is supported).\n *\n * @param orders The orders to match. Note that both the offerer\n * and fulfiller on each order must first approve\n * this contract (or their conduit if indicated by\n * the order) to transfer any relevant tokens on\n * their behalf and each consideration recipient\n * must implement `onERC1155Received` in order to\n * receive ERC1155 tokens.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components. Note that each\n * consideration component must be fully met in\n * order for the match operation to be valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function matchOrders(\n Order[] calldata orders,\n Fulfillment[] calldata fulfillments\n ) external payable override returns (Execution[] memory executions) {\n // Convert to advanced, validate, and match orders using fulfillments.\n return\n _matchAdvancedOrders(\n _convertOrdersToAdvanced(orders),\n new CriteriaResolver[](0), // No criteria resolvers supplied.\n fulfillments\n );\n }\n\n /**\n * @notice Match an arbitrary number of full or partial orders, each with an\n * arbitrary number of items for offer and consideration, supplying\n * criteria resolvers containing specific token identifiers and\n * associated proofs as well as fulfillments allocating offer\n * components to consideration components.\n *\n * @param advancedOrders The advanced orders to match. Note that both the\n * offerer and fulfiller on each order must first\n * approve this contract (or their conduit if\n * indicated by the order) to transfer any relevant\n * tokens on their behalf and each consideration\n * recipient must implement `onERC1155Received` in\n * order to receive ERC1155 tokens. Also note that\n * the offer and consideration components for each\n * order must have no remainder after multiplying\n * the respective amount with the supplied fraction\n * in order for the group of partial fills to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific order as well as that order's\n * offer or consideration, a token identifier, and\n * a proof that the supplied token identifier is\n * contained in the order's merkle root. Note that\n * an empty root indicates that any (transferable)\n * token identifier is valid and that no associated\n * proof needs to be supplied.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components. Note that each\n * consideration component must be fully met in\n * order for the match operation to be valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function matchAdvancedOrders(\n AdvancedOrder[] memory advancedOrders,\n CriteriaResolver[] calldata criteriaResolvers,\n Fulfillment[] calldata fulfillments\n ) external payable override returns (Execution[] memory executions) {\n // Validate and match the advanced orders using supplied fulfillments.\n return\n _matchAdvancedOrders(\n advancedOrders,\n criteriaResolvers,\n fulfillments\n );\n }\n\n /**\n * @notice Cancel an arbitrary number of orders. Note that only the offerer\n * or the zone of a given order may cancel it. Callers should ensure\n * that the intended order was cancelled by calling `getOrderStatus`\n * and confirming that `isCancelled` returns `true`.\n *\n * @param orders The orders to cancel.\n *\n * @return cancelled A boolean indicating whether the supplied orders have\n * been successfully cancelled.\n */\n function cancel(OrderComponents[] calldata orders)\n external\n override\n returns (bool cancelled)\n {\n // Cancel the orders.\n cancelled = _cancel(orders);\n }\n\n /**\n * @notice Validate an arbitrary number of orders, thereby registering their\n * signatures as valid and allowing the fulfiller to skip signature\n * verification on fulfillment. Note that validated orders may still\n * be unfulfillable due to invalid item amounts or other factors;\n * callers should determine whether validated orders are fulfillable\n * by simulating the fulfillment call prior to execution. Also note\n * that anyone can validate a signed order, but only the offerer can\n * validate an order without supplying a signature.\n *\n * @param orders The orders to validate.\n *\n * @return validated A boolean indicating whether the supplied orders have\n * been successfully validated.\n */\n function validate(Order[] calldata orders)\n external\n override\n returns (bool validated)\n {\n // Validate the orders.\n validated = _validate(orders);\n }\n\n /**\n * @notice Cancel all orders from a given offerer with a given zone in bulk\n * by incrementing a counter. Note that only the offerer may\n * increment the counter.\n *\n * @return newCounter The new counter.\n */\n function incrementCounter() external override returns (uint256 newCounter) {\n // Increment current counter for the supplied offerer.\n newCounter = _incrementCounter();\n }\n\n /**\n * @notice Retrieve the order hash for a given order.\n *\n * @param order The components of the order.\n *\n * @return orderHash The order hash.\n */\n function getOrderHash(OrderComponents calldata order)\n external\n view\n override\n returns (bytes32 orderHash)\n {\n // Derive order hash by supplying order parameters along with counter.\n orderHash = _deriveOrderHash(\n OrderParameters(\n order.offerer,\n order.zone,\n order.offer,\n order.consideration,\n order.orderType,\n order.startTime,\n order.endTime,\n order.zoneHash,\n order.salt,\n order.conduitKey,\n order.consideration.length\n ),\n order.counter\n );\n }\n\n /**\n * @notice Retrieve the status of a given order by hash, including whether\n * the order has been cancelled or validated and the fraction of the\n * order that has been filled.\n *\n * @param orderHash The order hash in question.\n *\n * @return isValidated A boolean indicating whether the order in question\n * has been validated (i.e. previously approved or\n * partially filled).\n * @return isCancelled A boolean indicating whether the order in question\n * has been cancelled.\n * @return totalFilled The total portion of the order that has been filled\n * (i.e. the \"numerator\").\n * @return totalSize The total size of the order that is either filled or\n * unfilled (i.e. the \"denominator\").\n */\n function getOrderStatus(bytes32 orderHash)\n external\n view\n override\n returns (\n bool isValidated,\n bool isCancelled,\n uint256 totalFilled,\n uint256 totalSize\n )\n {\n // Retrieve the order status using the order hash.\n return _getOrderStatus(orderHash);\n }\n\n /**\n * @notice Retrieve the current counter for a given offerer.\n *\n * @param offerer The offerer in question.\n *\n * @return counter The current counter.\n */\n function getCounter(address offerer)\n external\n view\n override\n returns (uint256 counter)\n {\n // Return the counter for the supplied offerer.\n counter = _getCounter(offerer);\n }\n\n /**\n * @notice Retrieve configuration information for this contract.\n *\n * @return version The contract version.\n * @return domainSeparator The domain separator for this contract.\n * @return conduitController The conduit Controller set for this contract.\n */\n function information()\n external\n view\n override\n returns (\n string memory version,\n bytes32 domainSeparator,\n address conduitController\n )\n {\n // Return the information for this contract.\n return _information();\n }\n\n /**\n * @notice Retrieve the name of this contract.\n *\n * @return contractName The name of this contract.\n */\n function name()\n external\n pure\n override\n returns (string memory contractName)\n {\n // Return the name of the contract.\n contractName = _name();\n }\n}\n" - }, - "seaport/contracts/interfaces/ConsiderationInterface.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.7;\n\n// prettier-ignore\nimport {\n BasicOrderParameters,\n OrderComponents,\n Fulfillment,\n FulfillmentComponent,\n Execution,\n Order,\n AdvancedOrder,\n OrderStatus,\n CriteriaResolver\n} from \"../lib/ConsiderationStructs.sol\";\n\n/**\n * @title ConsiderationInterface\n * @author 0age\n * @custom:version 1.1\n * @notice Consideration is a generalized ETH/ERC20/ERC721/ERC1155 marketplace.\n * It minimizes external calls to the greatest extent possible and\n * provides lightweight methods for common routes as well as more\n * flexible methods for composing advanced orders.\n *\n * @dev ConsiderationInterface contains all external function interfaces for\n * Consideration.\n */\ninterface ConsiderationInterface {\n /**\n * @notice Fulfill an order offering an ERC721 token by supplying Ether (or\n * the native token for the given chain) as consideration for the\n * order. An arbitrary number of \"additional recipients\" may also be\n * supplied which will each receive native tokens from the fulfiller\n * as consideration.\n *\n * @param parameters Additional information on the fulfilled order. Note\n * that the offerer must first approve this contract (or\n * their preferred conduit if indicated by the order) for\n * their offered ERC721 token to be transferred.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillBasicOrder(BasicOrderParameters calldata parameters)\n external\n payable\n returns (bool fulfilled);\n\n /**\n * @notice Fulfill an order with an arbitrary number of items for offer and\n * consideration. Note that this function does not support\n * criteria-based orders or partial filling of orders (though\n * filling the remainder of a partially-filled order is supported).\n *\n * @param order The order to fulfill. Note that both the\n * offerer and the fulfiller must first approve\n * this contract (or the corresponding conduit if\n * indicated) to transfer any relevant tokens on\n * their behalf and that contracts must implement\n * `onERC1155Received` to receive ERC1155 tokens\n * as consideration.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used, with direct approvals set on\n * Consideration.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillOrder(Order calldata order, bytes32 fulfillerConduitKey)\n external\n payable\n returns (bool fulfilled);\n\n /**\n * @notice Fill an order, fully or partially, with an arbitrary number of\n * items for offer and consideration alongside criteria resolvers\n * containing specific token identifiers and associated proofs.\n *\n * @param advancedOrder The order to fulfill along with the fraction\n * of the order to attempt to fill. Note that\n * both the offerer and the fulfiller must first\n * approve this contract (or their preferred\n * conduit if indicated by the order) to transfer\n * any relevant tokens on their behalf and that\n * contracts must implement `onERC1155Received`\n * to receive ERC1155 tokens as consideration.\n * Also note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount with\n * the supplied fraction for the partial fill to\n * be considered valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a proof\n * that the supplied token identifier is\n * contained in the merkle root held by the item\n * in question's criteria element. Note that an\n * empty criteria indicates that any\n * (transferable) token identifier on the token\n * in question is valid and that no associated\n * proof needs to be supplied.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit, if\n * any, to source the fulfiller's token approvals\n * from. The zero hash signifies that no conduit\n * should be used, with direct approvals set on\n * Consideration.\n * @param recipient The intended recipient for all received items,\n * with `address(0)` indicating that the caller\n * should receive the items.\n *\n * @return fulfilled A boolean indicating whether the order has been\n * successfully fulfilled.\n */\n function fulfillAdvancedOrder(\n AdvancedOrder calldata advancedOrder,\n CriteriaResolver[] calldata criteriaResolvers,\n bytes32 fulfillerConduitKey,\n address recipient\n ) external payable returns (bool fulfilled);\n\n /**\n * @notice Attempt to fill a group of orders, each with an arbitrary number\n * of items for offer and consideration. Any order that is not\n * currently active, has already been fully filled, or has been\n * cancelled will be omitted. Remaining offer and consideration\n * items will then be aggregated where possible as indicated by the\n * supplied offer and consideration component arrays and aggregated\n * items will be transferred to the fulfiller or to each intended\n * recipient, respectively. Note that a failing item transfer or an\n * issue with order formatting will cause the entire batch to fail.\n * Note that this function does not support criteria-based orders or\n * partial filling of orders (though filling the remainder of a\n * partially-filled order is supported).\n *\n * @param orders The orders to fulfill. Note that both\n * the offerer and the fulfiller must first\n * approve this contract (or the\n * corresponding conduit if indicated) to\n * transfer any relevant tokens on their\n * behalf and that contracts must implement\n * `onERC1155Received` to receive ERC1155\n * tokens as consideration.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used, with\n * direct approvals set on this contract.\n * @param maximumFulfilled The maximum number of orders to fulfill.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function fulfillAvailableOrders(\n Order[] calldata orders,\n FulfillmentComponent[][] calldata offerFulfillments,\n FulfillmentComponent[][] calldata considerationFulfillments,\n bytes32 fulfillerConduitKey,\n uint256 maximumFulfilled\n )\n external\n payable\n returns (bool[] memory availableOrders, Execution[] memory executions);\n\n /**\n * @notice Attempt to fill a group of orders, fully or partially, with an\n * arbitrary number of items for offer and consideration per order\n * alongside criteria resolvers containing specific token\n * identifiers and associated proofs. Any order that is not\n * currently active, has already been fully filled, or has been\n * cancelled will be omitted. Remaining offer and consideration\n * items will then be aggregated where possible as indicated by the\n * supplied offer and consideration component arrays and aggregated\n * items will be transferred to the fulfiller or to each intended\n * recipient, respectively. Note that a failing item transfer or an\n * issue with order formatting will cause the entire batch to fail.\n *\n * @param advancedOrders The orders to fulfill along with the\n * fraction of those orders to attempt to\n * fill. Note that both the offerer and the\n * fulfiller must first approve this\n * contract (or their preferred conduit if\n * indicated by the order) to transfer any\n * relevant tokens on their behalf and that\n * contracts must implement\n * `onERC1155Received` to enable receipt of\n * ERC1155 tokens as consideration. Also\n * note that all offer and consideration\n * components must have no remainder after\n * multiplication of the respective amount\n * with the supplied fraction for an\n * order's partial fill amount to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a\n * reference to a specific offer or\n * consideration, a token identifier, and a\n * proof that the supplied token identifier\n * is contained in the merkle root held by\n * the item in question's criteria element.\n * Note that an empty criteria indicates\n * that any (transferable) token\n * identifier on the token in question is\n * valid and that no associated proof needs\n * to be supplied.\n * @param offerFulfillments An array of FulfillmentComponent arrays\n * indicating which offer items to attempt\n * to aggregate when preparing executions.\n * @param considerationFulfillments An array of FulfillmentComponent arrays\n * indicating which consideration items to\n * attempt to aggregate when preparing\n * executions.\n * @param fulfillerConduitKey A bytes32 value indicating what conduit,\n * if any, to source the fulfiller's token\n * approvals from. The zero hash signifies\n * that no conduit should be used, with\n * direct approvals set on this contract.\n * @param recipient The intended recipient for all received\n * items, with `address(0)` indicating that\n * the caller should receive the items.\n * @param maximumFulfilled The maximum number of orders to fulfill.\n *\n * @return availableOrders An array of booleans indicating if each order\n * with an index corresponding to the index of the\n * returned boolean was fulfillable or not.\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function fulfillAvailableAdvancedOrders(\n AdvancedOrder[] calldata advancedOrders,\n CriteriaResolver[] calldata criteriaResolvers,\n FulfillmentComponent[][] calldata offerFulfillments,\n FulfillmentComponent[][] calldata considerationFulfillments,\n bytes32 fulfillerConduitKey,\n address recipient,\n uint256 maximumFulfilled\n )\n external\n payable\n returns (bool[] memory availableOrders, Execution[] memory executions);\n\n /**\n * @notice Match an arbitrary number of orders, each with an arbitrary\n * number of items for offer and consideration along with as set of\n * fulfillments allocating offer components to consideration\n * components. Note that this function does not support\n * criteria-based or partial filling of orders (though filling the\n * remainder of a partially-filled order is supported).\n *\n * @param orders The orders to match. Note that both the offerer and\n * fulfiller on each order must first approve this\n * contract (or their conduit if indicated by the order)\n * to transfer any relevant tokens on their behalf and\n * each consideration recipient must implement\n * `onERC1155Received` to enable ERC1155 token receipt.\n * @param fulfillments An array of elements allocating offer components to\n * consideration components. Note that each\n * consideration component must be fully met for the\n * match operation to be valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function matchOrders(\n Order[] calldata orders,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Match an arbitrary number of full or partial orders, each with an\n * arbitrary number of items for offer and consideration, supplying\n * criteria resolvers containing specific token identifiers and\n * associated proofs as well as fulfillments allocating offer\n * components to consideration components.\n *\n * @param orders The advanced orders to match. Note that both the\n * offerer and fulfiller on each order must first\n * approve this contract (or a preferred conduit if\n * indicated by the order) to transfer any relevant\n * tokens on their behalf and each consideration\n * recipient must implement `onERC1155Received` in\n * order to receive ERC1155 tokens. Also note that\n * the offer and consideration components for each\n * order must have no remainder after multiplying\n * the respective amount with the supplied fraction\n * in order for the group of partial fills to be\n * considered valid.\n * @param criteriaResolvers An array where each element contains a reference\n * to a specific order as well as that order's\n * offer or consideration, a token identifier, and\n * a proof that the supplied token identifier is\n * contained in the order's merkle root. Note that\n * an empty root indicates that any (transferable)\n * token identifier is valid and that no associated\n * proof needs to be supplied.\n * @param fulfillments An array of elements allocating offer components\n * to consideration components. Note that each\n * consideration component must be fully met in\n * order for the match operation to be valid.\n *\n * @return executions An array of elements indicating the sequence of\n * transfers performed as part of matching the given\n * orders.\n */\n function matchAdvancedOrders(\n AdvancedOrder[] calldata orders,\n CriteriaResolver[] calldata criteriaResolvers,\n Fulfillment[] calldata fulfillments\n ) external payable returns (Execution[] memory executions);\n\n /**\n * @notice Cancel an arbitrary number of orders. Note that only the offerer\n * or the zone of a given order may cancel it. Callers should ensure\n * that the intended order was cancelled by calling `getOrderStatus`\n * and confirming that `isCancelled` returns `true`.\n *\n * @param orders The orders to cancel.\n *\n * @return cancelled A boolean indicating whether the supplied orders have\n * been successfully cancelled.\n */\n function cancel(OrderComponents[] calldata orders)\n external\n returns (bool cancelled);\n\n /**\n * @notice Validate an arbitrary number of orders, thereby registering their\n * signatures as valid and allowing the fulfiller to skip signature\n * verification on fulfillment. Note that validated orders may still\n * be unfulfillable due to invalid item amounts or other factors;\n * callers should determine whether validated orders are fulfillable\n * by simulating the fulfillment call prior to execution. Also note\n * that anyone can validate a signed order, but only the offerer can\n * validate an order without supplying a signature.\n *\n * @param orders The orders to validate.\n *\n * @return validated A boolean indicating whether the supplied orders have\n * been successfully validated.\n */\n function validate(Order[] calldata orders)\n external\n returns (bool validated);\n\n /**\n * @notice Cancel all orders from a given offerer with a given zone in bulk\n * by incrementing a counter. Note that only the offerer may\n * increment the counter.\n *\n * @return newCounter The new counter.\n */\n function incrementCounter() external returns (uint256 newCounter);\n\n /**\n * @notice Retrieve the order hash for a given order.\n *\n * @param order The components of the order.\n *\n * @return orderHash The order hash.\n */\n function getOrderHash(OrderComponents calldata order)\n external\n view\n returns (bytes32 orderHash);\n\n /**\n * @notice Retrieve the status of a given order by hash, including whether\n * the order has been cancelled or validated and the fraction of the\n * order that has been filled.\n *\n * @param orderHash The order hash in question.\n *\n * @return isValidated A boolean indicating whether the order in question\n * has been validated (i.e. previously approved or\n * partially filled).\n * @return isCancelled A boolean indicating whether the order in question\n * has been cancelled.\n * @return totalFilled The total portion of the order that has been filled\n * (i.e. the \"numerator\").\n * @return totalSize The total size of the order that is either filled or\n * unfilled (i.e. the \"denominator\").\n */\n function getOrderStatus(bytes32 orderHash)\n external\n view\n returns (\n bool isValidated,\n bool isCancelled,\n uint256 totalFilled,\n uint256 totalSize\n );\n\n /**\n * @notice Retrieve the current counter for a given offerer.\n *\n * @param offerer The offerer in question.\n *\n * @return counter The current counter.\n */\n function getCounter(address offerer)\n external\n view\n returns (uint256 counter);\n\n /**\n * @notice Retrieve configuration information for this contract.\n *\n * @return version The contract version.\n * @return domainSeparator The domain separator for this contract.\n * @return conduitController The conduit Controller set for this contract.\n */\n function information()\n external\n view\n returns (\n string memory version,\n bytes32 domainSeparator,\n address conduitController\n );\n\n /**\n * @notice Retrieve the name of this contract.\n *\n * @return contractName The name of this contract.\n */\n function name() external view returns (string memory contractName);\n}\n" - }, - "seaport/contracts/Seaport.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport { Consideration } from \"./lib/Consideration.sol\";\n\n/**\n * @title Seaport\n * @custom:version 1.1\n * @author 0age (0age.eth)\n * @custom:coauthor d1ll0n (d1ll0n.eth)\n * @custom:coauthor transmissions11 (t11s.eth)\n * @custom:contributor Kartik (slokh.eth)\n * @custom:contributor LeFevre (lefevre.eth)\n * @custom:contributor Joseph Schiarizzi (CupOJoseph.eth)\n * @custom:contributor Aspyn Palatnick (stuckinaboot.eth)\n * @custom:contributor James Wenzel (emo.eth)\n * @custom:contributor Stephan Min (stephanm.eth)\n * @custom:contributor Ryan Ghods (ralxz.eth)\n * @custom:contributor hack3r-0m (hack3r-0m.eth)\n * @custom:contributor Diego Estevez (antidiego.eth)\n * @custom:contributor Chomtana (chomtana.eth)\n * @custom:contributor Saw-mon and Natalie (sawmonandnatalie.eth)\n * @custom:contributor 0xBeans (0xBeans.eth)\n * @custom:contributor 0x4non (punkdev.eth)\n * @custom:contributor Laurence E. Day (norsefire.eth)\n * @custom:contributor vectorized.eth (vectorized.eth)\n * @custom:contributor karmacoma (karmacoma.eth)\n * @custom:contributor horsefacts (horsefacts.eth)\n * @custom:contributor UncarvedBlock (uncarvedblock.eth)\n * @custom:contributor Zoraiz Mahmood (zorz.eth)\n * @custom:contributor William Poulin (wpoulin.eth)\n * @custom:contributor Rajiv Patel-O'Connor (rajivpoc.eth)\n * @custom:contributor tserg (tserg.eth)\n * @custom:contributor cygaar (cygaar.eth)\n * @custom:contributor Meta0xNull (meta0xnull.eth)\n * @custom:contributor gpersoon (gpersoon.eth)\n * @custom:contributor Matt Solomon (msolomon.eth)\n * @custom:contributor Weikang Song (weikangs.eth)\n * @custom:contributor zer0dot (zer0dot.eth)\n * @custom:contributor Mudit Gupta (mudit.eth)\n * @custom:contributor leonardoalt (leoalt.eth)\n * @custom:contributor cmichel (cmichel.eth)\n * @custom:contributor PraneshASP (pranesh.eth)\n * @custom:contributor JasperAlexander (jasperalexander.eth)\n * @custom:contributor Ellahi (ellahi.eth)\n * @custom:contributor zaz (1zaz1.eth)\n * @custom:contributor berndartmueller (berndartmueller.eth)\n * @custom:contributor dmfxyz (dmfxyz.eth)\n * @custom:contributor daltoncoder (dontkillrobots.eth)\n * @custom:contributor 0xf4ce (0xf4ce.eth)\n * @custom:contributor phaze (phaze.eth)\n * @custom:contributor hrkrshnn (hrkrshnn.eth)\n * @custom:contributor axic (axic.eth)\n * @custom:contributor leastwood (leastwood.eth)\n * @custom:contributor 0xsanson (sanson.eth)\n * @custom:contributor blockdev (blockd3v.eth)\n * @custom:contributor fiveoutofnine (fiveoutofnine.eth)\n * @custom:contributor shuklaayush (shuklaayush.eth)\n * @custom:contributor 0xPatissier\n * @custom:contributor pcaversaccio\n * @custom:contributor David Eiber\n * @custom:contributor csanuragjain\n * @custom:contributor sach1r0\n * @custom:contributor twojoy0\n * @custom:contributor ori_dabush\n * @custom:contributor Daniel Gelfand\n * @custom:contributor okkothejawa\n * @custom:contributor FlameHorizon\n * @custom:contributor vdrg\n * @custom:contributor dmitriia\n * @custom:contributor bokeh-eth\n * @custom:contributor asutorufos\n * @custom:contributor rfart(rfa)\n * @custom:contributor Riley Holterhus\n * @custom:contributor big-tech-sux\n * @notice Seaport is a generalized ETH/ERC20/ERC721/ERC1155 marketplace. It\n * minimizes external calls to the greatest extent possible and provides\n * lightweight methods for common routes as well as more flexible\n * methods for composing advanced orders or groups of orders. Each order\n * contains an arbitrary number of items that may be spent (the \"offer\")\n * along with an arbitrary number of items that must be received back by\n * the indicated recipients (the \"consideration\").\n */\ncontract Seaport is Consideration {\n /**\n * @notice Derive and set hashes, reference chainId, and associated domain\n * separator during deployment.\n *\n * @param conduitController A contract that deploys conduits, or proxies\n * that may optionally be used to transfer approved\n * ERC20/721/1155 tokens.\n */\n constructor(address conduitController) Consideration(conduitController) {}\n\n /**\n * @dev Internal pure function to retrieve and return the name of this\n * contract.\n *\n * @return The name of this contract.\n */\n function _name() internal pure override returns (string memory) {\n // Return the name of the contract.\n assembly {\n mstore(0x20, 0x20)\n mstore(0x47, 0x07536561706f7274)\n return(0x20, 0x60)\n }\n }\n\n /**\n * @dev Internal pure function to retrieve the name of this contract as a\n * string that will be used to derive the name hash in the constructor.\n *\n * @return The name of this contract as a string.\n */\n function _nameString() internal pure override returns (string memory) {\n // Return the name of the contract.\n return \"Seaport\";\n }\n}\n" - }, - "contracts/seaport/Seaport.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport \"seaport/contracts/Seaport.sol\";" - }, - "contracts/seaport/ConduitController.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport \"seaport/contracts/conduit/ConduitController.sol\";" - } - }, - "settings": { - "viaIR": true, - "optimizer": { - "enabled": true, - "runs": 19066 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "storageLayout", - "devdoc", - "userdoc", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index 6f758258..b0913f0e 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,6 +1,6 @@ import * as dotenv from "dotenv"; -import { HardhatUserConfig, subtask, task } from "hardhat/config"; +import { HardhatUserConfig, task } from "hardhat/config"; import "@openzeppelin/hardhat-upgrades"; import "@nomiclabs/hardhat-waffle"; import "@nomiclabs/hardhat-etherscan"; @@ -11,8 +11,6 @@ import "solidity-coverage"; import "hardhat-deploy"; import "hardhat-abi-exporter"; -import { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } from "hardhat/builtin-tasks/task-names"; - dotenv.config(); let accounts; @@ -57,7 +55,7 @@ const config: HardhatUserConfig = { solidity: { compilers: [ { - version: "0.8.14", + version: "0.8.17", settings: { viaIR: true, optimizer: { diff --git a/package.json b/package.json index caabb77c..0c22c2d6 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "prettier-plugin-solidity": "^1.0.0-beta.19", "readline-sync": "^1.4.10", "scuffed-abi": "^1.0.4", - "seaport": "git+https://github.com/ProjectOpenSea/seaport.git#5c6a628cb152d731e956682dd748d30e8bf1f1c9", + "seaport": "git+https://github.com/ProjectOpenSea/seaport.git#11c74c9af4020ff287fee8ca791798984bdbf8bd", "solhint": "^3.3.6", "solidity-coverage": "^0.7.21", "ts-node": "^10.4.0", diff --git a/test/utils/fixtures/marketplace.ts b/test/utils/fixtures/marketplace.ts index fa1527b7..9f635e1c 100644 --- a/test/utils/fixtures/marketplace.ts +++ b/test/utils/fixtures/marketplace.ts @@ -27,7 +27,7 @@ import { const { orderType } = require("../../../eip-712-types/order"); const deployConstants = require("../../../constants/constants"); -const VERSION = !process.env.REFERENCE ? "1.1" : "rc.1.1"; +const VERSION = !process.env.REFERENCE ? "1.2" : "rc.1.2"; export const marketplaceFixture = async ( create2Factory: ImmutableCreate2FactoryInterface, diff --git a/yarn.lock b/yarn.lock index 794d7691..3ef5c4e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -114,7 +114,7 @@ patch-package "^6.2.2" postinstall-postinstall "^2.1.0" -"@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.0", "@ethereumjs/block@^3.6.2", "@ethereumjs/block@^3.6.3": +"@ethereumjs/block@^3.5.0", "@ethereumjs/block@^3.6.2", "@ethereumjs/block@^3.6.3": version "3.6.3" resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.6.3.tgz#d96cbd7af38b92ebb3424223dbf773f5ccd27f84" integrity sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg== @@ -124,7 +124,7 @@ ethereumjs-util "^7.1.5" merkle-patricia-tree "^4.2.4" -"@ethereumjs/blockchain@^5.5.0", "@ethereumjs/blockchain@^5.5.2", "@ethereumjs/blockchain@^5.5.3": +"@ethereumjs/blockchain@^5.5.2", "@ethereumjs/blockchain@^5.5.3": version "5.5.3" resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz#aa49a6a04789da6b66b5bcbb0d0b98efc369f640" integrity sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw== @@ -138,7 +138,7 @@ lru-cache "^5.1.1" semaphore-async-await "^1.5.1" -"@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.0", "@ethereumjs/common@^2.6.4", "@ethereumjs/common@^2.6.5": +"@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.4", "@ethereumjs/common@^2.6.5": version "2.6.5" resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== @@ -157,7 +157,7 @@ ethereumjs-util "^7.1.1" miller-rabin "^4.0.0" -"@ethereumjs/tx@^3.3.2", "@ethereumjs/tx@^3.4.0", "@ethereumjs/tx@^3.5.1", "@ethereumjs/tx@^3.5.2": +"@ethereumjs/tx@^3.3.2", "@ethereumjs/tx@^3.5.1", "@ethereumjs/tx@^3.5.2": version "3.5.2" resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c" integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw== @@ -165,7 +165,7 @@ "@ethereumjs/common" "^2.6.4" ethereumjs-util "^7.1.5" -"@ethereumjs/vm@^5.6.0", "@ethereumjs/vm@^5.9.0": +"@ethereumjs/vm@^5.9.0": version "5.9.3" resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.9.3.tgz#6d69202e4c132a4a1e1628ac246e92062e230823" integrity sha512-Ha04TeF8goEglr8eL7hkkYyjhzdZS0PsoRURzYlTF6I0VVId5KjKb0N7MrA8GMgheN+UeTncfTgYx52D/WhEmg== @@ -960,6 +960,211 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@nomicfoundation/ethereumjs-block@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz#fdd5c045e7baa5169abeed0e1202bf94e4481c49" + integrity sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-blockchain@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz#1a8c243a46d4d3691631f139bfb3a4a157187b0c" + integrity sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw== + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-ethash" "^2.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + abstract-level "^1.0.3" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + level "^8.0.0" + lru-cache "^5.1.1" + memory-level "^1.0.0" + +"@nomicfoundation/ethereumjs-common@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz#f6bcc7753994555e49ab3aa517fc8bcf89c280b9" + integrity sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA== + dependencies: + "@nomicfoundation/ethereumjs-util" "^8.0.0" + crc-32 "^1.2.0" + +"@nomicfoundation/ethereumjs-ethash@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz#11539c32fe0990e1122ff987d1b84cfa34774e81" + integrity sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew== + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + abstract-level "^1.0.3" + bigint-crypto-utils "^3.0.23" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-evm@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz#99cd173c03b59107c156a69c5e215409098a370b" + integrity sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/ethereumjs-rlp@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz#d9a9c5f0f10310c8849b6525101de455a53e771d" + integrity sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw== + +"@nomicfoundation/ethereumjs-statemanager@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz#14a9d4e1c828230368f7ab520c144c34d8721e4b" + integrity sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + +"@nomicfoundation/ethereumjs-trie@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz#dcfbe3be53a94bc061c9767a396c16702bc2f5b7" + integrity sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + ethereum-cryptography "0.1.3" + readable-stream "^3.6.0" + +"@nomicfoundation/ethereumjs-tx@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz#59dc7452b0862b30342966f7052ab9a1f7802f52" + integrity sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w== + dependencies: + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-util@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz#deb2b15d2c308a731e82977aefc4e61ca0ece6c5" + integrity sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A== + dependencies: + "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2" + ethereum-cryptography "0.1.3" + +"@nomicfoundation/ethereumjs-vm@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz#2bb50d332bf41790b01a3767ffec3987585d1de6" + integrity sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w== + dependencies: + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-blockchain" "^6.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-evm" "^1.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-statemanager" "^1.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@types/async-eventemitter" "^0.2.1" + async-eventemitter "^0.2.4" + debug "^4.3.3" + ethereum-cryptography "0.1.3" + functional-red-black-tree "^1.0.1" + mcl-wasm "^0.7.1" + rustbn.js "~0.2.0" + +"@nomicfoundation/hardhat-network-helpers@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.7.tgz#9103be2b359899a8b7996f54df12a1b7977367e3" + integrity sha512-X+3mNvn8B7BY5hpIaLO+TrfzWq12bpux+ajGGdmdcfC78NXmYmOZkAtiz1QZx1YIZGMS1LaXzPXyBExxKFpCaw== + dependencies: + ethereumjs-util "^7.1.4" + +"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz#83a7367342bd053a76d04bbcf4f373fef07cf760" + integrity sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw== + +"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz#1225f7da647ae1ad25a87125664704ecc0af6ccc" + integrity sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA== + +"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz#dbc052dcdfd50ae50fd5ae1788b69b4e0fa40040" + integrity sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg== + +"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz#e6b2eea633995b557e74e881d2a43eab4760903d" + integrity sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ== + +"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz#af81107f5afa794f19988a368647727806e18dc4" + integrity sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w== + +"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz#6877e1da1a06a9f08446070ab6e0a5347109f868" + integrity sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw== + +"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz#bb6cd83a0c259eccef4183796b6329a66cf7ebd9" + integrity sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg== + +"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz#9d4bca1cc9a1333fde985675083b0b7d165f6076" + integrity sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw== + +"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz#0db5bfc6aa952bea4098d8d2c8947b4e5c4337ee" + integrity sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw== + +"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz#2e0f39a2924dcd77db6b419828595e984fabcb33" + integrity sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA== + +"@nomicfoundation/solidity-analyzer@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz#e5ddc43ad5c0aab96e5054520d8e16212e125f50" + integrity sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg== + optionalDependencies: + "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.0" + "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.0" + "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.0" + "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.0" + "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.0" + "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.0" + "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.0" + "@nomiclabs/hardhat-ethers@npm:hardhat-deploy-ethers": version "0.3.0-beta.13" resolved "https://registry.yarnpkg.com/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.3.0-beta.13.tgz#b96086ff768ddf69928984d5eb0a8d78cfca9366" @@ -1266,6 +1471,11 @@ resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz#f055979a99f7654e84d6b8e6267419e9c4cfff87" integrity sha512-q5veSX6zjUy/DlDhR4Y4cU0k2Ar+DT2LUraP00T19WLmTO6Se1djepCCaqU6nQrwcJ5Hyo/CWqxTzrrFg8eqbQ== +"@types/async-eventemitter@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz#f8e6280e87e8c60b2b938624b0a3530fb3e24712" + integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg== + "@types/bn.js@*", "@types/bn.js@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" @@ -1562,6 +1772,19 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" + integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + abstract-leveldown@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" @@ -2581,6 +2804,18 @@ big.js@^6.1.1: resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== +bigint-crypto-utils@^3.0.23: + version "3.1.8" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d" + integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw== + dependencies: + bigint-mod-arith "^3.1.0" + +bigint-mod-arith@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz#658e416bc593a463d97b59766226d0a3021a76b1" + integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ== + bignumber.js@^9.0.0, bignumber.js@^9.0.1: version "9.0.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" @@ -2688,6 +2923,16 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +browser-level@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" + integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.1" + module-error "^1.0.2" + run-parallel-limit "^1.1.0" + browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -2776,6 +3021,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-reverse@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-reverse/-/buffer-reverse-1.0.1.tgz#49283c8efa6f901bc01fa3304d06027971ae2f60" + integrity sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg== + buffer-to-arraybuffer@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" @@ -2801,6 +3051,14 @@ buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + bufferutil@^4.0.1: version "4.0.6" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" @@ -2815,6 +3073,13 @@ builtins@^5.0.1: dependencies: semver "^7.0.0" +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -2918,6 +3183,11 @@ caseless@^0.12.0, caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +catering@^2.1.0, catering@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" + integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== + cbor@^5.0.2: version "5.2.0" resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" @@ -3070,6 +3340,17 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classic-level@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" + integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg== + dependencies: + abstract-level "^1.0.2" + catering "^2.1.0" + module-error "^1.0.1" + napi-macros "~2.0.0" + node-gyp-build "^4.3.0" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -3468,6 +3749,11 @@ crypto-browserify@3.12.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-js@^3.1.9-1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" + integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== + d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" @@ -3514,13 +3800,6 @@ debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, de dependencies: ms "2.1.2" -debug@4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -4442,7 +4721,7 @@ ethereum-common@^0.0.18: resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" integrity sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ== -ethereum-cryptography@^0.1.2, ethereum-cryptography@^0.1.3: +ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== @@ -4626,7 +4905,7 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum rlp "^2.0.0" safe-buffer "^5.1.1" -ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.2, ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.3, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: +ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.2, ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: version "7.1.5" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== @@ -5789,19 +6068,25 @@ hardhat@^2.10.2: uuid "^8.3.2" ws "^7.4.6" -"hardhat@https://github.com/0age/hardhat/releases/download/viaIR-2.9.3/hardhat-v2.9.3.tgz": - version "2.9.3" - resolved "https://github.com/0age/hardhat/releases/download/viaIR-2.9.3/hardhat-v2.9.3.tgz#7edfa6a4e000851ecf37194e33c1d62c80a54c98" +hardhat@^2.12.1-ir.0: + version "2.12.6" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.6.tgz#ea3c058bbd81850867389d10f76037cfa52a0019" + integrity sha512-0Ent1O5DsPgvaVb5sxEgsQ3bJRt/Ex92tsoO+xjoNH2Qc4bFmhI5/CHVlFikulalxOPjNmw5XQ2vJFuVQFESAA== dependencies: - "@ethereumjs/block" "^3.6.0" - "@ethereumjs/blockchain" "^5.5.0" - "@ethereumjs/common" "^2.6.0" - "@ethereumjs/tx" "^3.4.0" - "@ethereumjs/vm" "^5.6.0" "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/ethereumjs-block" "^4.0.0" + "@nomicfoundation/ethereumjs-blockchain" "^6.0.0" + "@nomicfoundation/ethereumjs-common" "^3.0.0" + "@nomicfoundation/ethereumjs-evm" "^1.0.0" + "@nomicfoundation/ethereumjs-rlp" "^4.0.0" + "@nomicfoundation/ethereumjs-statemanager" "^1.0.0" + "@nomicfoundation/ethereumjs-trie" "^5.0.0" + "@nomicfoundation/ethereumjs-tx" "^4.0.0" + "@nomicfoundation/ethereumjs-util" "^8.0.0" + "@nomicfoundation/ethereumjs-vm" "^6.0.0" + "@nomicfoundation/solidity-analyzer" "^0.1.0" "@sentry/node" "^5.18.1" - "@solidity-parser/parser" "^0.14.1" "@types/bn.js" "^5.1.0" "@types/lru-cache" "^5.1.0" abort-controller "^3.0.0" @@ -5814,31 +6099,28 @@ hardhat@^2.10.2: debug "^4.1.1" enquirer "^2.3.0" env-paths "^2.2.0" - ethereum-cryptography "^0.1.2" + ethereum-cryptography "^1.0.3" ethereumjs-abi "^0.6.8" - ethereumjs-util "^7.1.3" find-up "^2.1.0" fp-ts "1.19.3" fs-extra "^7.0.1" - glob "^7.1.3" + glob "7.2.0" immutable "^4.0.0-rc.12" io-ts "1.10.4" + keccak "^3.0.2" lodash "^4.17.11" - merkle-patricia-tree "^4.2.2" mnemonist "^0.38.0" - mocha "^9.2.0" + mocha "^10.0.0" p-map "^4.0.0" qs "^6.7.0" raw-body "^2.4.1" resolve "1.17.0" semver "^6.3.0" - slash "^3.0.0" solc "0.7.3" source-map-support "^0.5.13" stacktrace-parser "^0.1.10" - "true-case-path" "^2.2.1" tsort "0.0.1" - undici "^4.14.1" + undici "^5.14.0" uuid "^8.3.2" ws "^7.4.6" @@ -6069,7 +6351,7 @@ idna-uts46-hx@^2.3.1: dependencies: punycode "2.1.0" -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -6259,7 +6541,7 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@~2.0.3: +is-buffer@^2.0.5, is-buffer@~2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== @@ -6786,6 +7068,15 @@ keccak@^3.0.0: node-gyp-build "^4.2.0" readable-stream "^3.6.0" +keccak@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" + integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" + keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -6968,6 +7259,11 @@ level-sublevel@6.6.4: typewiselite "~1.0.0" xtend "~4.0.0" +level-supports@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" + integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== + level-supports@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" @@ -6975,6 +7271,14 @@ level-supports@~1.0.0: dependencies: xtend "^4.0.2" +level-transcoder@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" + integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== + dependencies: + buffer "^6.0.3" + module-error "^1.0.1" + level-ws@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" @@ -7001,6 +7305,14 @@ level-ws@^2.0.0: readable-stream "^3.1.0" xtend "^4.0.1" +level@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" + integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== + dependencies: + browser-level "^1.0.1" + classic-level "^1.2.0" + levelup@3.1.1, levelup@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189" @@ -7325,6 +7637,15 @@ memdown@~3.0.0: ltgt "~2.2.0" safe-buffer "~5.1.1" +memory-level@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" + integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== + dependencies: + abstract-level "^1.0.0" + functional-red-black-tree "^1.0.1" + module-error "^1.0.1" + memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -7372,7 +7693,7 @@ merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: rlp "^2.0.0" semaphore ">=1.0.1" -merkle-patricia-tree@^4.2.2, merkle-patricia-tree@^4.2.4: +merkle-patricia-tree@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz#ff988d045e2bf3dfa2239f7fabe2d59618d57413" integrity sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w== @@ -7384,6 +7705,17 @@ merkle-patricia-tree@^4.2.2, merkle-patricia-tree@^4.2.4: readable-stream "^3.6.0" semaphore-async-await "^1.5.1" +merkletreejs@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.3.9.tgz#cdb364a3b974a44f4eff3446522d7066e0cf95de" + integrity sha512-NjlATjJr4NEn9s8v/VEHhgwRWaE1eA/Une07d9SEqKzULJi1Wsh0Y3svwJdP2bYLMmgSBHzOrNydMWM1NN9VeQ== + dependencies: + bignumber.js "^9.0.1" + buffer-reverse "^1.0.1" + crypto-js "^3.1.9-1" + treeify "^1.1.0" + web3-utils "^1.3.4" + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -7492,13 +7824,6 @@ minimatch@3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== - dependencies: - brace-expansion "^1.1.7" - minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -7625,41 +7950,16 @@ mocha@^7.1.1: yargs-parser "13.1.2" yargs-unparser "1.6.0" -mocha@^9.2.0: - version "9.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" - integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.3" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "4.2.1" - ms "2.1.3" - nanoid "3.3.1" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - mock-fs@^4.1.0: version "4.14.0" resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== +module-error@^1.0.1, module-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" + integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -7739,11 +8039,6 @@ nano-json-stream-parser@^0.1.2: resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== -nanoid@3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== - nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -7766,6 +8061,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +napi-macros@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" + integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -8632,7 +8932,7 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== -queue-microtask@^1.2.2: +queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== @@ -9056,6 +9356,13 @@ run-async@^2.2.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-parallel-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" + integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== + dependencies: + queue-microtask "^1.2.2" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -9153,13 +9460,15 @@ scuffed-abi@^1.0.4: resolved "https://registry.yarnpkg.com/scuffed-abi/-/scuffed-abi-1.0.4.tgz#bc88129877856de5026d8afaea49de9a1972b6cf" integrity sha512-1NN2L1j+TMF6+/J2jHcAnhPH8Lwaqu5dlgknZPqejEVFQ8+cvcnXYNbaHtGEXTjSNrQLBGePXicD4oFGqecOnQ== -"seaport@git+https://github.com/ProjectOpenSea/seaport.git#5c6a628cb152d731e956682dd748d30e8bf1f1c9": - version "1.1.0" - resolved "git+https://github.com/ProjectOpenSea/seaport.git#5c6a628cb152d731e956682dd748d30e8bf1f1c9" +"seaport@git+https://github.com/ProjectOpenSea/seaport.git#11c74c9af4020ff287fee8ca791798984bdbf8bd": + version "1.2.0" + resolved "git+https://github.com/ProjectOpenSea/seaport.git#11c74c9af4020ff287fee8ca791798984bdbf8bd" dependencies: + "@nomicfoundation/hardhat-network-helpers" "^1.0.7" ethers "^5.5.3" ethers-eip712 "^0.2.0" - hardhat "https://github.com/0age/hardhat/releases/download/viaIR-2.9.3/hardhat-v2.9.3.tgz" + hardhat "^2.12.1-ir.0" + merkletreejs "^0.3.9" secp256k1@^4.0.1: version "4.0.3" @@ -9684,6 +9993,11 @@ stream-to-pull-stream@^1.7.1: looper "^3.0.0" pull-stream "^3.2.3" +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -10138,6 +10452,11 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +treeify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" + integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -10416,10 +10735,12 @@ underscore@1.9.1, underscore@>=1.12.1: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee" integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ== -undici@^4.14.1: - version "4.16.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-4.16.0.tgz#469bb87b3b918818d3d7843d91a1d08da357d5ff" - integrity sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw== +undici@^5.14.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.15.0.tgz#cb8437c43718673a8be59df0fdd4856ff6689283" + integrity sha512-wCAZJDyjw9Myv+Ay62LAoB+hZLPW9SmKbQkbHIhMw/acKSlpn7WohdMUc/Vd4j1iSMBO0hWwU8mjB7a5p5bl8g== + dependencies: + busboy "^1.6.0" undici@^5.4.0: version "5.7.0" @@ -11087,6 +11408,19 @@ web3-utils@1.7.4, web3-utils@^1.0.0-beta.31, web3-utils@^1.3.0: randombytes "^2.1.0" utf8 "3.0.0" +web3-utils@^1.3.4: + version "1.8.1" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.1.tgz#f2f7ca7eb65e6feb9f3d61056d0de6bbd57125ff" + integrity sha512-LgnM9p6V7rHHUGfpMZod+NST8cRfGzJ1BTXAyNo7A9cJX9LczBfSRxJp+U/GInYe9mby40t3v22AJdlELibnsQ== + dependencies: + bn.js "^5.2.1" + ethereum-bloom-filters "^1.0.6" + ethereumjs-util "^7.1.0" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + web3@1.2.11: version "1.2.11" resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975" @@ -11177,7 +11511,7 @@ which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -which@2.0.2, which@^2.0.1: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -11214,11 +11548,6 @@ wordwrapjs@^4.0.0: reduce-flatten "^2.0.0" typical "^5.2.0" -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== - workerpool@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"