Overview
ETH Balance
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
4140146 | 358 days ago | 0.0001 ETH | ||||
4140132 | 358 days ago | 0.00008 ETH | ||||
4140131 | 358 days ago | 0.0001 ETH | ||||
4140128 | 358 days ago | 0.0001 ETH | ||||
4140116 | 358 days ago | 0.0001 ETH | ||||
4140097 | 358 days ago | 0.0001 ETH | ||||
4140086 | 358 days ago | 0.0001 ETH | ||||
4140080 | 358 days ago | 0.0001 ETH | ||||
4140075 | 358 days ago | 0.000094 ETH | ||||
4140072 | 358 days ago | 0.00008 ETH | ||||
4140068 | 358 days ago | 0.0001999 ETH | ||||
4140057 | 358 days ago | 0.0001 ETH | ||||
4140042 | 358 days ago | 0.0001 ETH | ||||
4140023 | 358 days ago | 0.0001 ETH | ||||
4140002 | 358 days ago | 0.0001 ETH | ||||
4139984 | 358 days ago | 0.00008 ETH | ||||
4139983 | 358 days ago | 0.0001 ETH | ||||
4139967 | 358 days ago | 0.0001 ETH | ||||
4139966 | 358 days ago | 0.0001 ETH | ||||
4139948 | 358 days ago | 0.0001 ETH | ||||
4139930 | 358 days ago | 0.0001 ETH | ||||
4139898 | 358 days ago | 0.0003499 ETH | ||||
4139897 | 358 days ago | 0.0001 ETH | ||||
4139881 | 358 days ago | 0.0001 ETH | ||||
4139880 | 358 days ago | 0.0000355 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
BatchSignedERC721OrdersFeature
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 /* Copyright 2022 Element.Market Intl. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity ^0.8.17; import "../../storage/LibCommonNftOrdersStorage.sol"; import "../../storage/LibERC721OrdersStorage.sol"; import "../interfaces/IBatchSignedERC721OrdersFeature.sol"; contract BatchSignedERC721OrdersFeature is IBatchSignedERC721OrdersFeature { uint256 internal constant MASK_192 = (1 << 192) - 1; uint256 internal constant MASK_160 = (1 << 160) - 1; uint256 internal constant MASK_64 = (1 << 64) - 1; uint256 internal constant MASK_40 = (1 << 40) - 1; uint256 internal constant MASK_32 = (1 << 32) - 1; uint256 internal constant MASK_16 = (1 << 16) - 1; uint256 internal constant MASK_INDEX_LIST_PART1 = ((1 << 96) - 1) << 160; uint256 internal constant MASK_INDEX_LIST_PART2 = ((1 << 32) - 1) << 128; uint256 internal constant NONCE_RANGE_LIMIT = 1 << 248; uint256 internal constant MAX_ERC20_AMOUNT = (1 << 224) - 1; // Storage ID. uint256 constant STORAGE_ID_COMMON_NFT_ORDERS = 4 << 128; uint256 constant STORAGE_ID_ERC721_ORDERS = 5 << 128; // Topic for ERC721SellOrderFilled. bytes32 internal constant _TOPIC_SELL_ORDER_FILLED = 0x9c248aa1a265aa616f707b979d57f4529bb63a4fc34dc7fc61fdddc18410f74e; // keccak256("") bytes32 internal constant _EMPTY_ARRAY_KECCAK256 = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // keccak256(abi.encodePacked( // "BatchSignedERC721Orders(address maker,uint256 listingTime,uint256 expiryTime,uint256 startNonce,address erc20Token,address platformFeeRecipient,BasicCollection[] basicCollections,Collection[] collections,uint256 hashNonce)", // "BasicCollection(address nftAddress,bytes32 fee,bytes32[] items)", // "Collection(address nftAddress,bytes32 fee,OrderItem[] items)", // "OrderItem(uint256 erc20TokenAmount,uint256 nftId)" // )) bytes32 internal constant _BATCH_SIGNED_ERC721_ORDERS_TYPE_HASH = 0x2d8cbbbc696e7292c3b5beb38e1363d34ff11beb8c3456c14cb938854597b9ed; // keccak256("BasicCollection(address nftAddress,bytes32 fee,bytes32[] items)") bytes32 internal constant _BASIC_COLLECTION_TYPE_HASH = 0x12ad29288fd70022f26997a9958d9eceb6e840ceaa79b72ea5945ba87e4d33b0; // keccak256(abi.encodePacked( // "Collection(address nftAddress,bytes32 fee,OrderItem[] items)", // "OrderItem(uint256 erc20TokenAmount,uint256 nftId)" // )) bytes32 internal constant _COLLECTION_TYPE_HASH = 0xb9f488d48cec782be9ecdb74330c9c6a33c236a8022d8a91a4e4df4e81b51620; // keccak256("OrderItem(uint256 erc20TokenAmount,uint256 nftId)") bytes32 internal constant _ORDER_ITEM_TYPE_HASH = 0x5f93394997caa49a9382d44a75e3ce6a460f32b39870464866ac994f8be97afe; // keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)") bytes32 internal constant DOMAIN = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; // keccak256("ElementEx") bytes32 internal constant NAME = 0x27b14c20196091d9cd90ca9c473d3ad1523b00ddf487a9b7452a8a119a16b98c; // keccak256("1.0.0") bytes32 internal constant VERSION = 0x06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c; /// @dev The implementation address of this feature. address internal immutable _IMPL; /// @dev The WETH token contract. address internal immutable _WETH; constructor(address weth) { require(address(weth) != address(0), "INVALID_WETH_ADDRESS"); _WETH = weth; _IMPL = address(this); } function fillBatchSignedERC721Order(BatchSignedERC721OrderParameter calldata /* parameter */, bytes calldata collections) external override payable { uint256 ethBalanceBefore = address(this).balance - msg.value; uint256 offsetCollectionsBytes; assembly { offsetCollectionsBytes := collections.offset } // Validate order. bytes32 orderHash = _validateOrder(offsetCollectionsBytes); assembly { // memory[0x0 - 0x20] orderHash mstore(0, orderHash) /////////////////////////// memory[0x380 - 0x420] for delegateCall /////////// // memory[0x380 - 0x3a0] erc20TokenFromDelegateCall // memory[0x3a0 - 0x3c0] platformFeeRecipientFromDelegateCall // memory[0x3c0 - 0x3e0] royaltyFeeRecipientFromDelegateCall mstore(0x380, 0) mstore(0x3a0, 0) mstore(0x3c0, 0) } // Fill order. _fillBatchSignedERC721Order(offsetCollectionsBytes); // Refund ETH. assembly { if eq(selfbalance(), ethBalanceBefore) { return(0, 0) } if gt(selfbalance(), ethBalanceBefore) { if iszero(call(gas(), caller(), sub(selfbalance(), ethBalanceBefore), 0, 0, 0, 0)) { _revertRefundETHFailed() } return(0, 0) } _revertRefundETHFailed() function _revertRefundETHFailed() { // revert("fillBatchSignedERC721Order: failed to refund ETH.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003166696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x6661696c656420746f20726566756e64204554482e0000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } } } /// @param additional1 [96 bits(withdrawETHAmount) + 160 bits(erc20Token)] /// @param additional2 [8 bits(revertIfIncomplete) + 88 bits(unused) + 160 bits(royaltyFeeRecipient)] function fillBatchSignedERC721Orders( BatchSignedERC721OrderParameters[] calldata parameters, uint256 additional1, uint256 additional2 ) external override payable { require(parameters.length > 0, "fillBatchSignedERC721Orders: invalid parameters."); uint256 ethBalanceBefore = address(this).balance - msg.value; uint256 platformFeeRecipient = parameters[0].data3 & MASK_160; address impl = _IMPL; address weth = _WETH; assembly { let withdrawETHAmount := shr(160, additional1) let erc20Token := and(additional1, MASK_160) let royaltyFeeRecipient := and(additional2, MASK_160) let platformFeeGlobalAccum let royaltyFeeGlobalAccum let someSuccess // Withdraw ETH if needed. if withdrawETHAmount { // Step1: transfer WETH from msg.sender to address(this). _transferERC20(weth, address(), withdrawETHAmount) // Step2: withdraw ETH. // selector for `withdraw(uint256)`. mstore(0, 0x2e1a7d4d) mstore(0x20, withdrawETHAmount) if iszero(call(gas(), weth, 0, 0x1c, 0x24, 0, 0)) { _revertWithdrawETHFailed() } } /////////////////////////// memory[0 - 0x40] for delegatecall output ///////////// // memory[0 - 0x20] output [platformFeeGlobal] // memory[0x20 - 0x40] output [royaltyFeeGlobal] /////////////////////////// memory[0x40 - ] for delegatecall input ///////////// // memory[0x40 - 0x60] selector for `delegateCallFillBatchSignedERC721Order(BatchSignedERC721OrderParameter,address,address,address,bytes)` mstore(0x40, 0xdc055ecc) // memory[0x60 - 0x100] parameter // memory[0x100 - 0x120] erc20Token mstore(0x100, erc20Token) // memory[0x120 - 0x140] platformFeeRecipient mstore(0x120, platformFeeRecipient) // memory[0x140 - 0x160] royaltyFeeRecipient mstore(0x140, royaltyFeeRecipient) // memory[0x160 - 0x180] collections.offset mstore(0x160, 0x120) // memory[0x180 - 0x1a0] collections.length // memory[0x1a0 - ] collections.data let ptrEnd := add(parameters.offset, mul(parameters.length, 0x20)) for { let ptr := parameters.offset } lt(ptr, ptrEnd) { ptr := add(ptr, 0x20) } { let ptrData := add(parameters.offset, calldataload(ptr)) // memory[0x40 - 0x60] selector for `delegateCallFillBatchSignedERC721Order` // memory[0x60 - 0x100] parameter calldatacopy(0x60, ptrData, 0xa0 /* 5 * 32*/) // memory[0x100 - 0x120] erc20Token // memory[0x120 - 0x140] platformFeeRecipient // memory[0x140 - 0x160] royaltyFeeRecipient // memory[0x160 - 0x180] collections.offset // memory[0x180 - 0x1a0] collections.length let collectionsLength := calldataload(add(ptrData, 0xc0)) if mod(collectionsLength, 0x20) { _revertInvalidCollectionsBytes() } mstore(0x180, collectionsLength) // memory[0x1a0 - ] collections.data calldatacopy(0x1a0, add(ptrData, 0xe0), collectionsLength) // 0x144 = 0x4(selector) + 0xa0(parameter) + 0x20(erc20Token) + 0x20(platformFeeRecipient) + 0x20(royaltyFeeRecipient) + 0x20(collections.offset) + 0x20(collections.length) switch delegatecall(gas(), impl, 0x5c, add(0x144, collectionsLength), 0, 0x40) case 0 { // Check revertIfIncomplete flag if failed. if byte(0, additional2) { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } default { // Success. someSuccess := 1 // memory[0 - 0x20] output [platformFeeGlobal] // memory[0x20 - 0x40] output [royaltyFeeGlobal] platformFeeGlobalAccum := add(platformFeeGlobalAccum, mload(0)) royaltyFeeGlobalAccum := add(royaltyFeeGlobalAccum, mload(0x20)) } } // end for if platformFeeGlobalAccum { _transferERC20(erc20Token, platformFeeRecipient, platformFeeGlobalAccum) } if royaltyFeeGlobalAccum { _transferERC20(erc20Token, royaltyFeeRecipient, royaltyFeeGlobalAccum) } if iszero(someSuccess) { _revertNoOrderFilled() } // Refund ETH. if eq(selfbalance(), ethBalanceBefore) { return(0, 0) } if gt(selfbalance(), ethBalanceBefore) { if iszero(call(gas(), caller(), sub(selfbalance(), ethBalanceBefore), 0, 0, 0, 0)) { _revertRefundETHFailed() } return(0, 0) } _revertRefundETHFailed() ///////////////////////////////// functions ///////////////////////////////// function _transferERC20(_erc20Token, _to, _amount) { switch _erc20Token case 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE { if iszero(call(gas(), _to, _amount, 0, 0, 0, 0)) { _revertTransferETHFailed() } } default { if iszero(extcodesize(_erc20Token)) { _revertInvalidERC20Token() } // selector for `transferFrom(address,address,uint256)` mstore(0, 0x23b872dd) mstore(0x20, caller()) mstore(0x40, _to) mstore(0x60, _amount) if iszero(call(gas(), _erc20Token, 0, 0x1c, 0x64, 0, 0x20)) { _revertTransferERC20Failed() } // Check for ERC20 success. ERC20 tokens should return a boolean, but some don't. // We accept 0-length return data as success, or at least 32 bytes that starts with // a 32-byte boolean true. if returndatasize() { if lt(returndatasize(), 0x20) { _revertTransferERC20Failed() } if iszero(eq(mload(0), 1)) { _revertTransferERC20Failed() } } } } function _revertTransferETHFailed() { // revert("fillBatchSignedERC721Orders: failed to transfer ETH.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003466696c6c42617463685369676e65644552433732314f72646572733a) mstore(0x60, 0x206661696c656420746f207472616e73666572204554482e0000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertTransferERC20Failed() { // revert("fillBatchSignedERC721Orders: failed to transfer ERC20.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003666696c6c42617463685369676e65644552433732314f72646572733a) mstore(0x60, 0x206661696c656420746f207472616e736665722045524332302e000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertWithdrawETHFailed() { // revert("fillBatchSignedERC721Orders: failed to withdraw ETH.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003466696c6c42617463685369676e65644552433732314f72646572733a) mstore(0x60, 0x206661696c656420746f207769746864726177204554482e0000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertInvalidCollectionsBytes() { // revert("fillBatchSignedERC721Orders: invalid collectionsBytes.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003666696c6c42617463685369676e65644552433732314f72646572733a) mstore(0x60, 0x20696e76616c696420636f6c6c656374696f6e7342797465732e000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertNoOrderFilled() { // revert("fillBatchSignedERC721Orders: no order filled.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002d66696c6c42617463685369676e65644552433732314f72646572733a) mstore(0x60, 0x206e6f206f726465722066696c6c65642e000000000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertRefundETHFailed() { // revert("fillBatchSignedERC721Orders: failed to refund ETH.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003266696c6c42617463685369676e65644552433732314f72646572733a) mstore(0x60, 0x206661696c656420746f20726566756e64204554482e00000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertInvalidERC20Token() { // revert("invalid erc20 token") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x00000013696e76616c696420657263323020746f6b656e000000000000000000) mstore(0x60, 0) revert(0, 0x64) } } } // @Note `delegateCallFillBatchSignedERC721Order` is a external function, but must delegatecall from an external exchange, // and should not be registered in the external exchange. function delegateCallFillBatchSignedERC721Order( BatchSignedERC721OrderParameter calldata /* parameter */, address erc20TokenFromDelegateCall, address platformFeeRecipientFromDelegateCall, address royaltyFeeRecipientFromDelegateCall, bytes calldata collections ) external payable { address impl = _IMPL; uint256 offsetCollectionsBytes; assembly { if eq(impl, address()) { // revert("delegateCallFillBatchSignedERC721Order: must delegateCall from an external exchange.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000005464656c656761746543616c6c46696c6c42617463685369676e656445) mstore(0x60, 0x52433732314f726465723a206d7573742064656c656761746543616c6c206672) mstore(0x80, 0x6f6d20616e2065787465726e616c2065786368616e67652e0000000000000000) mstore(0xa0, 0) revert(0, 0xa4) } offsetCollectionsBytes := collections.offset } // Validate order. bytes32 orderHash = _validateOrder(offsetCollectionsBytes); assembly { // memory[0x0 - 0x20] orderHash mstore(0, orderHash) /////////////////////////// memory[0x380 - 0x420] for delegateCall /////////// // memory[0x380 - 0x3a0] erc20TokenFromDelegateCall // memory[0x3a0 - 0x3c0] platformFeeRecipientFromDelegateCall // memory[0x3c0 - 0x3e0] royaltyFeeRecipientFromDelegateCall mstore(0x380, erc20TokenFromDelegateCall) mstore(0x3a0, platformFeeRecipientFromDelegateCall) mstore(0x3c0, royaltyFeeRecipientFromDelegateCall) } // Fill order. _fillBatchSignedERC721Order(offsetCollectionsBytes); assembly { // Return platformFeeGlobal and royaltyFeeGlobal. // memory[0x3e0 - 0x400] platformFeeGlobal // memory[0x400 - 0x420] royaltyFeeGlobal return(0x3e0, 0x40) } } /// data1 [[8 bits(signatureType) + 8 bits(reserved) + 40 bits(startNonce) + 8 bits(v) + 32 bits(listingTime) + 160 bits(maker)] /// data2 [64 bits(taker part1) + 32 bits(expiryTime) + 160 bits(erc20Token)] /// data3 [96 bits(taker part2) + 160 bits(platformFeeRecipient)] function _fillBatchSignedERC721Order(uint256 offsetCollectionsBytes) internal { assembly { /////////////////////////// memory[0x0 - 0x1c0] for emitEvent data //////////////////////// // memory[0x0 - 0x20] orderHash // memory[0x20 - 0x40] maker mstore(0x20, and(calldataload(0x4), MASK_160)) // maker = data1 & MASK_160 // memory[0x40 - 0x60] taker mstore(0x40, or(shl(96, shr(192, calldataload(0x24))), shr(160, calldataload(0x44)))) // taker = ((data2 >> 192) << 96) | (data3 >> 160) if iszero(mload(0x40)) { mstore(0x40, caller()) } // memory[0x60 - 0x80] nonce // memory[0x80 - 0xa0] erc20Token mstore(0x80, and(calldataload(0x24), MASK_160)) // erc20Token = data2 & MASK_160 // memory[0xa0 - 0xc0] erc20TokenAmount // memory[0xc0 - 0xe0] fees.offset mstore(0xc0, 0x120 /* 9 * 32 */) // memory[0xe0 - 0x100] nftAddress // memory[0x100 - 0x120] nftId // memory[0x120 - 0x140] fees.length // memory[0x140 - 0x1c0] fees.data /////////////////////////// memory[0x1c0 - 0x240] for transferERC721 ////////// // memory[0x1c0 - 0x1e0] selector for `transferFrom(address,address,uint256)` mstore(0x1c0, 0x23b872dd) // memory[0x1e0 - 0x200] maker mstore(0x1e0, mload(0x20)) // memory[0x200 - 0x220] taker mstore(0x200, mload(0x40)) // memory[0x220 - 0x240] nftId /////////////////////////// memory[0x240 - 0x300] for nonceVector ///////////// // Note: nonceRange = nonce >> 8 // Note: nonceVector = LibERC721OrdersStorage.orderStatusByMaker[maker][nonceRange] // Note: nonceVector.slot = keccak256(nonceRange, keccak256(maker, LibERC721OrdersStorage.storageId)) // memory[0x240 - 0x260] shouldStoreNonceVectorToStorage flag mstore(0x240, 0) // memory[0x260 - 0x280] nonceMask // memory[0x280 - 0x2a0] nonceVector.slot // memory[0x2a0 - 0x2c0] nonceVector // memory[0x2c0 - 0x2e0] nonceRange mstore(0x2c0, NONCE_RANGE_LIMIT) // memory[0x2e0 - 0x300] keccak256(maker, LibERC721OrdersStorage.storageId) mstore(0x2e0, mload(0x20)) mstore(0x300, STORAGE_ID_ERC721_ORDERS) mstore(0x2e0, keccak256(0x2e0, 0x40)) /////////////////////////// memory[0x300 - 0x380] for collection ////////////// // memory[0x300 - 0x320] collection.head2 // memory[0x320 - 0x340] collection.platformFeePercentage // memory[0x340 - 0x360] collection.royaltyFeePercentage // memory[0x360 - 0x380] someSuccess flag mstore(0x360, 0) /////////////////////////// memory[0x380 - 0x420] for delegateCall /////////// // memory[0x380 - 0x3a0] erc20TokenFromDelegateCall // memory[0x3a0 - 0x3c0] platformFeeRecipientFromDelegateCall // memory[0x3c0 - 0x3e0] royaltyFeeRecipientFromDelegateCall // memory[0x3e0 - 0x400] platformFeeGlobal mstore(0x3e0, 0) // memory[0x400 - 0x420] royaltyFeeGlobal mstore(0x400, 0) /////////////////////////// memory[0x420 - 0x4a0] for transferERC20 /////////// // memory[0x420 - 0x440] selector for `transferFrom(address,address,uint256)` mstore(0x420, 0x23b872dd) // memory[0x440 - 0x460] msg.sender mstore(0x440, caller()) // memory[0x460 - 0x480] to // memory[0x480 - 0x4a0] amount /////////////////////////// global variables ///////////////////////////////// let nonceVectorForCheckingNonReentrant // collectionStartNonce = (data1 >> 200) & MASK_40 let collectionStartNonce := and(shr(200, calldataload(0x4)), MASK_40) // platformFeeRecipient = data3 & MASK_160 let platformFeeRecipient := and(calldataload(0x44), MASK_160) // Total erc20 amount. let totalERC20AmountToPlatform let totalERC20AmountToMaker let ptrEnd := add(offsetCollectionsBytes, calldataload(sub(offsetCollectionsBytes, 0x20))) for { let offsetCollection := offsetCollectionsBytes } lt(offsetCollection, ptrEnd) {} { // memory[0xe0 - 0x100] nftAddress // head1 [96 bits(filledIndexList part1) + 160 bits(nftAddress)] mstore(0xe0, and(calldataload(offsetCollection), MASK_160)) // nftAddress = head1 & MASK_160 // memory[0x300 - 0x320] collection.head2 // collectionType: 0 - basicCollection, 1 - collection // head2 [8 bits(collectionType) + 8 bits(itemsCount) + 8 bits(filledCount) + 8 bits(unused) + 32 bits(filledIndexList part2) // + 16 bits(platformFeePercentage) + 16 bits(royaltyFeePercentage) + 160 bits(royaltyFeeRecipient)] mstore(0x300, calldataload(add(offsetCollection, 0x20))) // filledIndexList [96 bits(filledIndexList part1) + 32 bits(filledIndexList part2) + 128 bits(unused)] // filledIndexList = (head1 & MASK_INDEX_LIST_PART1) | ((head2 >> 64) & MASK_INDEX_LIST_PART2) let filledIndexList := or(and(calldataload(offsetCollection), MASK_INDEX_LIST_PART1), and(shr(64, mload(0x300)), MASK_INDEX_LIST_PART2)) let filledCount := byte(2, mload(0x300)) let itemsCount := byte(1, mload(0x300)) if filledCount { if gt(filledCount, itemsCount) { _revertInvalidFilledIndex() } if gt(filledCount, 128) { _revertInvalidFilledIndex() } if iszero(extcodesize(mload(0xe0))) { _revertInvalidERC721Token() } } // memory[0x140 - 0x160] platformFeeRecipient mstore(0x140, platformFeeRecipient) // memory[0x320 - 0x340] collection.platformFeePercentage switch platformFeeRecipient // if (platformFeeRecipient == address(0) platformFeePercentage = 0 case 0 { mstore(0x320, 0) } // else platformFeePercentage = collection.platformFeePercentage default { mstore(0x320, and(shr(176, mload(0x300)), MASK_16)) } // memory[0x180 - 0x1a0] royaltyFeeRecipient mstore(0x180, and(mload(0x300), MASK_160)) // memory[0x340 - 0x360] collection.royaltyFeePercentage switch mload(0x180) // if (royaltyFeeRecipient == address(0) royaltyFeePercentage = 0 case 0 { mstore(0x340, 0) } // else royaltyFeePercentage = collection.royaltyFeePercentage default { mstore(0x340, and(shr(160, mload(0x300)), MASK_16)) } // Check fees. if gt(add(mload(0x320), mload(0x340)), 10000) { revertFeesPercentageExceedsLimit() } let totalERC20AmountToRoyalty // switch collectionType switch byte(0, mload(0x300)) // basicCollection case 0 { for { } filledCount { } { filledCount := sub(filledCount, 1) let filledIndex := byte(filledCount, filledIndexList) if iszero(lt(filledIndex, itemsCount)) { _revertInvalidFilledIndex() } // memory[0x60 - 0x80] nonce // memory[0x240 - 0x260] shouldStoreNonceVectorToStorage flag // memory[0x260 - 0x280] nonceMask // memory[0x280 - 0x2a0] nonceVector.slot // memory[0x2a0 - 0x2c0] nonceVector // memory[0x2c0 - 0x2e0] nonceRange // memory[0x2e0 - 0x300] keccak256(maker, LibERC721OrdersStorage.storageId) // nonce = add(collectionStartNonce, filledIndex) mstore(0x60, add(collectionStartNonce, filledIndex)) // if (nonceRange != newNonceRange) if iszero(eq(mload(0x2c0), shr(8, mload(0x60)))) { // Store nonce to storage if needed. if mload(0x240) { // Revert if reentrant. if iszero(eq(nonceVectorForCheckingNonReentrant, sload(mload(0x280)))) { _revertReentrantCall() } // Store nonce to storage at one time. sstore(mload(0x280), mload(0x2a0)) // Clear store nonceVector flag. mstore(0x240, 0) } // nonceRange = nonce >> 8 mstore(0x2c0, shr(8, mload(0x60))) // Calculate nonceVector.slot and store to memory. mstore(0x280, keccak256(0x2c0, 0x40)) // Load nonceVector from storage. nonceVectorForCheckingNonReentrant := sload(mload(0x280)) // Store nonceVector to memory. mstore(0x2a0, nonceVectorForCheckingNonReentrant) } // memory[0x260 - 0x280] nonceMask // nonceMask = 1 << (nonce & 0xff) mstore(0x260, shl(and(mload(0x60), 0xff), 1)) // if order is not filled. // if (nonceVector & nonceMask == 0) if iszero(and(mload(0x2a0), mload(0x260))) { // orderItem [96 bits(erc20TokenAmount) + 160 bits(nftId)] let orderItem := calldataload(add(add(offsetCollection, 0x40), mul(filledIndex, 0x20))) // memory[0xe0 - 0x100] nftAddress // memory[0x1c0 - 0x1e0] selector for `transferFrom(address,address,uint256)` // memory[0x1e0 - 0x200] maker // memory[0x200 - 0x220] taker // memory[0x220 - 0x240] nftId mstore(0x220, and(orderItem, MASK_160)) // transferERC721 // 0x1dc = 0x1c0 + 28 if call(gas(), mload(0xe0), 0, 0x1dc, 0x64, 0, 0) { // Set store nonceVector flag. mstore(0x240, 1) // Update nonceVector. // nonceVector |= nonceMask mstore(0x2a0, or(mload(0x2a0), mload(0x260))) // Calculate fees. // memory[0xa0 - 0xc0] erc20TokenAmount mstore(0xa0, shr(160, orderItem)) // erc20TokenAmount = orderItem >> 160 // memory[0x140 - 0x1c0] fees.data // memory[0x140 - 0x160] platformFeeRecipient // memory[0x160 - 0x180] platformFeeAmount // memory[0x180 - 0x1a0] royaltyFeeRecipient // memory[0x1a0 - 0x1c0] royaltyFeeAmount // memory[0x320 - 0x340] platformFeePercentage // platformFeeAmount = erc20TokenAmount * platformFeePercentage / 10000 mstore(0x160, div(mul(mload(0xa0), mload(0x320)), 10000)) // memory[0x340 - 0x360] royaltyFeePercentage // royaltyFeeAmount = erc20TokenAmount * royaltyFeePercentage / 10000 mstore(0x1a0, div(mul(mload(0xa0), mload(0x340)), 10000)) // Update total erc20 amount. // totalERC20AmountToMaker += erc20TokenAmount - (platformFeeAmount + royaltyFeeAmount) totalERC20AmountToMaker := add(totalERC20AmountToMaker, sub(mload(0xa0), add(mload(0x160), mload(0x1a0)))) // totalERC20AmountToPlatform += platformFeeAmount totalERC20AmountToPlatform := add(totalERC20AmountToPlatform, mload(0x160)) // totalERC20AmountToRoyalty += royaltyFeeAmount totalERC20AmountToRoyalty := add(totalERC20AmountToRoyalty, mload(0x1a0)) // Emit event // memory[0 - 0x20] orderHash // memory[0x20 - 0x40] maker // memory[0x40 - 0x60] taker // memory[0x60 - 0x80] nonce // memory[0x80 - 0xa0] erc20Token // memory[0xa0 - 0xc0] erc20TokenAmount // memory[0xc0 - 0xe0] fees.offset // memory[0xe0 - 0x100] nftAddress // memory[0x100 - 0x120] nftId mstore(0x100, mload(0x220)) // fees switch platformFeeRecipient case 0 { // memory[0x180 - 0x1a0] royaltyFeeRecipient switch mload(0x180) case 0 { // memory[0x120 - 0x140] fees.length mstore(0x120, 0) // emit event log1(0, 320 /* 10 * 32 */, _TOPIC_SELL_ORDER_FILLED) } default { // memory[0x120 - 0x140] fees.length mstore(0x120, 1) // Copy royaltyFeeRecipient to memory[0x140 - 0x160] mstore(0x140, mload(0x180)) // Copy royaltyFeeAmount to memory[0x160 - 0x180] mstore(0x160, mload(0x1a0)) // emit event log1(0, 384 /* 12 * 32 */, _TOPIC_SELL_ORDER_FILLED) } } default { // memory[0x180 - 0x1a0] royaltyFeeRecipient switch mload(0x180) case 0 { // memory[0x120 - 0x140] fees.length mstore(0x120, 1) // emit event log1(0, 384 /* 12 * 32 */, _TOPIC_SELL_ORDER_FILLED) } default { // memory[0x120 - 0x140] fees.length mstore(0x120, 2) // emit event log1(0, 448 /* 14 * 32 */, _TOPIC_SELL_ORDER_FILLED) } } // Set someSuccess flag. mstore(0x360, 1) } } } // end for // Update offsetCollection. offsetCollection := add(add(offsetCollection, 0x40), mul(itemsCount, 0x20)) } // end basicCollection // collection default { for { } filledCount { } { filledCount := sub(filledCount, 1) let filledIndex := byte(filledCount, filledIndexList) if iszero(lt(filledIndex, itemsCount)) { _revertInvalidFilledIndex() } // memory[0x60 - 0x80] nonce // memory[0x240 - 0x260] shouldStoreNonceVectorToStorage flag // memory[0x260 - 0x280] nonceMask // memory[0x280 - 0x2a0] nonceVector.slot // memory[0x2a0 - 0x2c0] nonceVector // memory[0x2c0 - 0x2e0] nonceRange // memory[0x2e0 - 0x300] keccak256(maker, LibERC721OrdersStorage.storageId) // nonce = add(collectionStartNonce, filledIndex) mstore(0x60, add(collectionStartNonce, filledIndex)) // if (nonceRange != newNonceRange) if iszero(eq(mload(0x2c0), shr(8, mload(0x60)))) { // Store nonce to storage if needed. if mload(0x240) { // Revert if reentrant. if iszero(eq(nonceVectorForCheckingNonReentrant, sload(mload(0x280)))) { _revertReentrantCall() } // Store nonce to storage at one time. sstore(mload(0x280), mload(0x2a0)) // Clear store nonceVector flag. mstore(0x240, 0) } // nonceRange = nonce >> 8 mstore(0x2c0, shr(8, mload(0x60))) // Calculate nonceVector.slot and store to memory. mstore(0x280, keccak256(0x2c0, 0x40)) // Load nonceVector from storage. nonceVectorForCheckingNonReentrant := sload(mload(0x280)) // Store nonceVector to memory. mstore(0x2a0, nonceVectorForCheckingNonReentrant) } // memory[0x260 - 0x280] nonceMask // nonceMask = 1 << (nonce & 0xff) mstore(0x260, shl(and(mload(0x60), 0xff), 1)) // if order is not filled. // if (nonceVector & nonceMask == 0) if iszero(and(mload(0x2a0), mload(0x260))) { // struct OrderItem { // uint256 erc20TokenAmount; // uint256 nftId; // } let offsetOrderItem := add(add(offsetCollection, 0x40), mul(filledIndex, 0x40)) if gt(calldataload(offsetOrderItem), MAX_ERC20_AMOUNT) { _revertERC20AmountExceedsLimit() } // memory[0xe0 - 0x100] nftAddress // memory[0x1c0 - 0x1e0] selector for `transferFrom(address,address,uint256)` // memory[0x1e0 - 0x200] maker // memory[0x200 - 0x220] taker // memory[0x220 - 0x240] nftId mstore(0x220, calldataload(add(offsetOrderItem, 0x20))) // transferERC721 // 0x1dc = 0x1c0 + 28 if call(gas(), mload(0xe0), 0, 0x1dc, 0x64, 0, 0) { // Set store nonceVector flag. mstore(0x240, 1) // Update nonceVector. // nonceVector |= nonceMask mstore(0x2a0, or(mload(0x2a0), mload(0x260))) // Calculate fees. // memory[0xa0 - 0xc0] erc20TokenAmount mstore(0xa0, calldataload(offsetOrderItem)) // memory[0x140 - 0x1c0] fees.data // memory[0x140 - 0x160] platformFeeRecipient // memory[0x160 - 0x180] platformFeeAmount // memory[0x180 - 0x1a0] royaltyFeeRecipient // memory[0x1a0 - 0x1c0] royaltyFeeAmount // memory[0x320 - 0x340] platformFeePercentage // platformFeeAmount = erc20TokenAmount * platformFeePercentage / 10000 mstore(0x160, div(mul(mload(0xa0), mload(0x320)), 10000)) // memory[0x340 - 0x360] royaltyFeePercentage // royaltyFeeAmount = erc20TokenAmount * royaltyFeePercentage / 10000 mstore(0x1a0, div(mul(mload(0xa0), mload(0x340)), 10000)) // Update total erc20 amount. // totalERC20AmountToMaker += erc20TokenAmount - (platformFeeAmount + royaltyFeeAmount) totalERC20AmountToMaker := add(totalERC20AmountToMaker, sub(mload(0xa0), add(mload(0x160), mload(0x1a0)))) // totalERC20AmountToPlatform += platformFeeAmount totalERC20AmountToPlatform := add(totalERC20AmountToPlatform, mload(0x160)) // totalERC20AmountToRoyalty += royaltyFeeAmount totalERC20AmountToRoyalty := add(totalERC20AmountToRoyalty, mload(0x1a0)) // Emit event // memory[0 - 0x20] orderHash // memory[0x20 - 0x40] maker // memory[0x40 - 0x60] taker // memory[0x60 - 0x80] nonce // memory[0x80 - 0xa0] erc20Token // memory[0xa0 - 0xc0] erc20TokenAmount // memory[0xc0 - 0xe0] fees.offset // memory[0xe0 - 0x100] nftAddress // memory[0x100 - 0x120] nftId mstore(0x100, mload(0x220)) // fees switch platformFeeRecipient case 0 { // memory[0x180 - 0x1a0] royaltyFeeRecipient switch mload(0x180) case 0 { // memory[0x120 - 0x140] fees.length mstore(0x120, 0) // emit event log1(0, 320 /* 10 * 32 */, _TOPIC_SELL_ORDER_FILLED) } default { // memory[0x120 - 0x140] fees.length mstore(0x120, 1) // Copy royaltyFeeRecipient to memory[0x140 - 0x160] mstore(0x140, mload(0x180)) // Copy royaltyFeeAmount to memory[0x160 - 0x180] mstore(0x160, mload(0x1a0)) // emit event log1(0, 384 /* 12 * 32 */, _TOPIC_SELL_ORDER_FILLED) } } default { // memory[0x180 - 0x1a0] royaltyFeeRecipient switch mload(0x180) case 0 { // memory[0x120 - 0x140] fees.length mstore(0x120, 1) // emit event log1(0, 384 /* 12 * 32 */, _TOPIC_SELL_ORDER_FILLED) } default { // memory[0x120 - 0x140] fees.length mstore(0x120, 2) // emit event log1(0, 448 /* 14 * 32 */, _TOPIC_SELL_ORDER_FILLED) } } // Set someSuccess flag. mstore(0x360, 1) } } } // end for // Update offsetCollection. offsetCollection := add(add(offsetCollection, 0x40), mul(itemsCount, 0x40)) } // end collection // Update collectionStartNonce. // collectionStartNonce += itemsCount // memory[0x300 - 0x320] collection.head2 collectionStartNonce := add(collectionStartNonce, itemsCount) // Pay royaltyFee together. if totalERC20AmountToRoyalty { // memory[0x80 - 0xa0] erc20Token // memory[0x180 - 0x1a0] royaltyFeeRecipient // memory[0x380 - 0x3a0] erc20TokenFromDelegateCall // memory[0x3c0 - 0x3e0] royaltyFeeRecipientFromDelegateCall switch and(eq(mload(0x80), mload(0x380)), eq(mload(0x180), mload(0x3c0))) case 1 { // memory[0x400 - 0x420] royaltyFeeGlobal mstore(0x400, add(mload(0x400), totalERC20AmountToRoyalty)) } default { _transferERC20(mload(0x180), totalERC20AmountToRoyalty) } } } // end for // Store nonce to storage if needed. if mload(0x240) { // Revert if reentrant. if iszero(eq(nonceVectorForCheckingNonReentrant, sload(mload(0x280)))) { _revertReentrantCall() } // Store nonce to storage at one time. // memory[0x280 - 0x2a0] nonceVector.slot // memory[0x2a0 - 0x2c0] nonceVector sstore(mload(0x280), mload(0x2a0)) } // Pay to maker at one time. if totalERC20AmountToMaker { // memory[0x20 - 0x40] maker _transferERC20(mload(0x20), totalERC20AmountToMaker) } // Pay to platform at one time. if totalERC20AmountToPlatform { // memory[0x80 - 0xa0] erc20Token // memory[0x380 - 0x3a0] erc20TokenFromDelegateCall // memory[0x3a0 - 0x3c0] platformFeeRecipientFromDelegateCall switch and(eq(mload(0x80), mload(0x380)), eq(platformFeeRecipient, mload(0x3a0))) case 1 { // memory[0x3e0 - 0x400] platformFeeGlobal mstore(0x3e0, add(mload(0x3e0), totalERC20AmountToPlatform)) } default { _transferERC20(platformFeeRecipient, totalERC20AmountToPlatform) } } // Revert if none of the orders is filled. // memory[0x360 - 0x380] someSuccess flag if iszero(mload(0x360)) { _revertNoOrderFilled() } ///////////////////////////////// functions ///////////////////////////////// function _transferERC20(_to, _amount) { // memory[0x80 - 0xa0] erc20Token switch mload(0x80) case 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE { if iszero(call(gas(), _to, _amount, 0, 0, 0, 0)) { _revertTransferETHFailed() } } default { if iszero(extcodesize(mload(0x80))) { _revertInvalidERC20Token() } // memory[0x420 - 0x440] selector for `transferFrom(address,address,uint256)` // memory[0x440 - 0x460] msg.sender // memory[0x460 - 0x480] to mstore(0x460, _to) // memory[0x480 - 0x4a0] amount mstore(0x480, _amount) // memory[0x80 - 0xa0] erc20Token // 0x43c = 0x420 + 28 if iszero(call(gas(), mload(0x80), 0, 0x43c, 0x64, 0x480, 0x20)) { _revertTransferERC20Failed() } // Check for ERC20 success. ERC20 tokens should return a boolean, but some don't. // We accept 0-length return data as success, or at least 32 bytes that starts with // a 32-byte boolean true. if returndatasize() { if lt(returndatasize(), 0x20) { _revertTransferERC20Failed() } if iszero(eq(mload(0x480), 1)) { _revertTransferERC20Failed() } } } } function revertFeesPercentageExceedsLimit() { // revert("fillBatchSignedERC721Order: total fees percentage exceeds the limit.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000004466696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x746f74616c20666565732070657263656e746167652065786365656473207468) mstore(0x80, 0x65206c696d69742e000000000000000000000000000000000000000000000000) mstore(0xa0, 0) revert(0, 0xa4) } function _revertInvalidFilledIndex() { // revert("fillBatchSignedERC721Order: invalid filledIndex.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003066696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c69642066696c6c6564496e6465782e000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertReentrantCall() { // revert("fillBatchSignedERC721Order: reentrant call.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002b66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x7265656e7472616e742063616c6c2e0000000000000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertERC20AmountExceedsLimit() { // revert("fillBatchSignedERC721Order: erc20TokenAmount exceeds limit.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003b66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x6572633230546f6b656e416d6f756e742065786365656473206c696d69742e00) mstore(0x80, 0) revert(0, 0x84) } function _revertNoOrderFilled() { // revert("fillBatchSignedERC721Order: no order filled.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002c66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x6e6f206f726465722066696c6c65642e00000000000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertTransferETHFailed() { // revert("fillBatchSignedERC721Order: failed to transfer ETH.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003366696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x6661696c656420746f207472616e73666572204554482e000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertTransferERC20Failed() { // revert("fillBatchSignedERC721Order: failed to transfer ERC20.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003566696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x6661696c656420746f207472616e736665722045524332302e00000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertInvalidERC20Token() { // revert("invalid erc20 token") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x00000013696e76616c696420657263323020746f6b656e000000000000000000) mstore(0x60, 0) revert(0, 0x64) } function _revertInvalidERC721Token() { // revert("invalid erc271 token") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x00000014696e76616c69642065726337323120746f6b656e0000000000000000) mstore(0x60, 0) revert(0, 0x64) } } } /// data1 [8 bits(signatureType) + 8 bits(reserved) + 40 bits(startNonce) + 8 bits(v) + 32 bits(listingTime) + 160 bits(maker)] /// data2 [64 bits(taker part1) + 32 bits(expiryTime) + 160 bits(erc20Token)] function _validateOrder(uint256 offsetCollectionsBytes) internal view returns (bytes32 orderHash) { address maker; uint8 signatureType; uint8 v; assembly { let data1 := calldataload(0x4) let data2 := calldataload(0x24) signatureType := byte(0, data1) v := byte(7, data1) // Check for listingTime. // if ((data1 >> 160) & MASK_32 > block.timestamp) if gt(and(shr(160, data1), MASK_32), timestamp()) { // revert("fillBatchSignedERC721Order: failed to check for listingTime.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003c66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x6661696c656420746f20636865636b20666f72206c697374696e6754696d652e) mstore(0x80, 0) revert(0, 0x84) } // Check for expiryTime. // if ((data2 >> 160) & MASK_32 <= block.timestamp) if iszero(gt(and(shr(160, data2), MASK_32), timestamp())) { // revert("fillBatchSignedERC721Order: failed to check for expiryTime.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003b66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x6661696c656420746f20636865636b20666f722065787069727954696d652e00) mstore(0x80, 0) revert(0, 0x84) } // Check for erc20Token. if iszero(and(data2, MASK_160)) { // revert("fillBatchSignedERC721Order: invalid erc20Token.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002f66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c6964206572633230546f6b656e2e00000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } // Check maker. maker := and(data1, MASK_160) if iszero(maker) { // revert("fillBatchSignedERC721Order: invalid maker.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002a66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c6964206d616b65722e000000000000000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } } // Get order hash. orderHash = _getEIP712Hash(_getStructHash(offsetCollectionsBytes)); if (signatureType == 0) { bytes32 r; bytes32 s; assembly { // Must reset memory status before the `require` sentence. mstore(0x40, 0x80) mstore(0x60, 0) // Get r and v. r := calldataload(0x64) s := calldataload(0x84) } require(maker == ecrecover(orderHash, v, r, s), "fillBatchSignedERC721Order: failed to validate signature."); } else if (signatureType == 3) { assembly { // selector for `isValidSignature(bytes32,bytes)` mstore(0, 0x1626ba7e) mstore(0x20, orderHash) mstore(0x40, 0x40) mstore(0x60, 0x41) calldatacopy(0x80, 0x64, 64) mstore(0xc0, shl(248, v)) if iszero(extcodesize(maker)) { _revertInvalidMaker() } // Call signer with `isValidSignature` to validate signature. if iszero(staticcall(gas(), maker, 0x1c, 0xa5, 0, 0x20)) { _revertInvalidSignature() } // Check for returnData. if iszero(eq(mload(0), 0x1626ba7e00000000000000000000000000000000000000000000000000000000)) { _revertInvalidSignature() } function _revertInvalidMaker() { // revert("fillBatchSignedERC721Order: invalid maker.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002a66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c6964206d616b65722e000000000000000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertInvalidSignature() { // revert("fillBatchSignedERC721Order: invalid signature.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003266696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c6964207369676e61747572652e0000000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } } } else { assembly { // revert("fillBatchSignedERC721Order: invalid signatureType.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003266696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c6964207369676e6174757265547970652e00000000000000000000) mstore(0x80, 0) revert(0, 0x84) } } } function _getEIP712Hash(bytes32 structHash) internal view returns (bytes32 eip712Hash) { assembly { // EIP712_DOMAIN_SEPARATOR = keccak256(abi.encode( // DOMAIN, // NAME, // VERSION, // block.chainid, // address(this) // )); mstore(0, DOMAIN) mstore(0x20, NAME) mstore(0x40, VERSION) mstore(0x60, chainid()) mstore(0x80, address()) // eip712Hash = keccak256(abi.encodePacked( // hex"1901", // EIP712_DOMAIN_SEPARATOR, // structHash // )); mstore(0xa0, 0x1901000000000000000000000000000000000000000000000000000000000000) mstore(0xa2, keccak256(0, 0xa0)) mstore(0xc2, structHash) eip712Hash := keccak256(0xa0, 0x42) } } /// data1 [[8 bits(signatureType) + 8 bits(reserved) + 40 bits(startNonce) + 8 bits(v) + 32 bits(listingTime) + 160 bits(maker)] /// data2 [64 bits(taker part1) + 32 bits(expiryTime) + 160 bits(erc20Token)] /// data3 [96 bits(taker part2) + 160 bits(platformFeeRecipient)] function _getStructHash(uint256 offsetCollectionsBytes) internal view returns (bytes32 structHash) { // structHash = keccak256(abi.encode( // _BATCH_SIGNED_ERC721_ORDERS_TYPE_HASH, // offset: 0x0 // maker, // offset: 0x20 // listingTime, // offset: 0x40 // expiryTime, // offset: 0x60 // startNonce, // offset: 0x80 // erc20Token, // offset: 0xa0 // platformFeeRecipient, // offset: 0xc0 // basicCollectionsHash, // offset: 0xe0 // collectionsHash, // offset: 0x100 // hashNonce // offset: 0x120 // )); // Store basicCollectionsHash to memory[0xe0] and store collectionsHash to memory[0x100]. _storeCollectionsHashToMemory(offsetCollectionsBytes); assembly { let data1 := calldataload(0x4) let data2 := calldataload(0x24) let data3 := calldataload(0x44) let maker := and(data1, MASK_160) // _BATCH_SIGNED_ERC721_ORDERS_TYPE_HASH mstore(0, _BATCH_SIGNED_ERC721_ORDERS_TYPE_HASH) // maker mstore(0x20, maker) // listingTime = (data1 >> 160) & MASK_32 mstore(0x40, and(shr(160, data1), MASK_32)) // expiryTime = (data2 >> 160) & MASK_32 mstore(0x60, and(shr(160, data2), MASK_32)) // startNonce = (data1 >> 200) & MASK_40 mstore(0x80, and(shr(200, data1), MASK_40)) // erc20Token = data2 & MASK_160 mstore(0xa0, and(data2, MASK_160)) // platformFeeRecipient = data3 & MASK_160 mstore(0xc0, and(data3, MASK_160)) // 0xe0 basicCollectionsHash // 0x100 collectionsHash // 0x120 hashNonce // hashNonce.slot = keccak256(abi.encode(maker, STORAGE_ID_COMMON_NFT_ORDERS)) // hashNonce = sload(hashNonce.slot) mstore(0x120, maker) mstore(0x140, STORAGE_ID_COMMON_NFT_ORDERS) mstore(0x120, sload(keccak256(0x120, 0x40))) structHash := keccak256(0, 0x140 /* 10 * 32 */) } } function _storeCollectionsHashToMemory(uint256 offsetCollectionsBytes) internal pure { assembly { let isBasicCollectionsEnded let basicCollectionsHash let ptrCollectionHash let offsetCollection := offsetCollectionsBytes let ptrEnd := add(offsetCollectionsBytes, calldataload(sub(offsetCollectionsBytes, 0x20))) for {} lt(offsetCollection, ptrEnd) {} { // head1 [96 bits(filledIndexList part1) + 160 bits(nftAddress)] // nftAddress = head1 & MASK_160 let nftAddress := and(calldataload(offsetCollection), MASK_160) if iszero(nftAddress) { _revertInvalidNftAddress() } // collectionType: 0 - basicCollection, 1 - collection // head2 [8 bits(collectionType) + 8 bits(itemsCount) + 8 bits(filledCount) + 8 bits(unused) + 32 bits(filledIndexList part2) // + 16 bits(platformFeePercentage) + 16 bits(royaltyFeePercentage) + 160 bits(royaltyFeeRecipient)] let head2 := calldataload(add(offsetCollection, 0x20)) let itemsCount := byte(1, head2) if iszero(itemsCount) { _revertInvalidItemCount() } let filledCount := byte(2, head2) if or(gt(filledCount, itemsCount), gt(filledCount, 16)) { _revertInvalidFilledCount() } // basicCollection if iszero(byte(0, head2)) { if isBasicCollectionsEnded { _revertInvalidCollectionsBytes() } // typeHash = _BASIC_COLLECTION_TYPE_HASH mstore(ptrCollectionHash, _BASIC_COLLECTION_TYPE_HASH) // nftAddress mstore(add(ptrCollectionHash, 0x20), nftAddress) // fee = head2 & MASK_192 mstore(add(ptrCollectionHash, 0x40), and(head2, MASK_192)) // itemsHash let ptrItemsHash := add(ptrCollectionHash, 0x60) let itemsBytesLength := mul(itemsCount, 0x20) // offset: 0x0 - head1 // 0x20 - head2 // 0x40 - items.data let offsetItems := add(offsetCollection, 0x40) calldatacopy(ptrItemsHash, offsetItems, itemsBytesLength) // Calculate and store itemsHash. mstore(ptrItemsHash, keccak256(ptrItemsHash, itemsBytesLength)) // keccak256(abi.encode(_BASIC_COLLECTION_TYPE_HASH, nftAddress, fee, itemsHash)) mstore(ptrCollectionHash, keccak256(ptrCollectionHash, 0x80)) // Update offset. ptrCollectionHash := add(ptrCollectionHash, 0x20) offsetCollection := add(offsetItems, itemsBytesLength) continue } // Get basicCollectionsHash. if iszero(isBasicCollectionsEnded) { // Set flag. isBasicCollectionsEnded := 1 switch ptrCollectionHash case 0 { // basicCollections is empty. basicCollectionsHash := _EMPTY_ARRAY_KECCAK256 } default { // Calculate basicCollectionsHash. basicCollectionsHash := keccak256(0, ptrCollectionHash) ptrCollectionHash := 0 } } // collection // typeHash = _COLLECTION_TYPE_HASH mstore(ptrCollectionHash, _COLLECTION_TYPE_HASH) // nftAddress mstore(add(ptrCollectionHash, 0x20), nftAddress) // fee = head2 & MASK_192 mstore(add(ptrCollectionHash, 0x40), and(head2, MASK_192)) // itemsHash let ptrItemsHash := add(ptrCollectionHash, 0x60) let itemsBytesLength := mul(itemsCount, 0x40) // offset: 0x0 - head1 // 0x20 - head2 // 0x40 - items.data let offsetItems := add(offsetCollection, 0x40) // Copy items to memory [ptrItemsHash + 0x20]. // Reserve a slot(0x20) to store _ORDER_ITEM_TYPE_HASH. calldatacopy(add(ptrItemsHash, 0x20), offsetItems, itemsBytesLength) let ptrItemHashData := ptrItemsHash let ptrItemEnd := add(ptrItemsHash, mul(itemsCount, 0x20)) for { let ptrItem := ptrItemsHash } lt(ptrItem, ptrItemEnd) {} { mstore(ptrItemHashData, _ORDER_ITEM_TYPE_HASH) mstore(ptrItem, keccak256(ptrItemHashData, 0x60)) ptrItem := add(ptrItem, 0x20) ptrItemHashData := add(ptrItemHashData, 0x40) } // Calculate and store itemsHash. mstore(ptrItemsHash, keccak256(ptrItemsHash, mul(itemsCount, 0x20))) // keccak256(abi.encode(_COLLECTION_TYPE_HASH, nftAddress, fee, itemsHash)) mstore(ptrCollectionHash, keccak256(ptrCollectionHash, 0x80)) // Update offset. ptrCollectionHash := add(ptrCollectionHash, 0x20) offsetCollection := add(offsetItems, itemsBytesLength) } // if (offsetCollection != ptrEnd) revert() if iszero(eq(offsetCollection, ptrEnd)) { _revertInvalidCollectionsBytes() } switch isBasicCollectionsEnded // Order.collections is empty. case 0 { // Order.basicCollections is empty. if iszero(ptrCollectionHash) { _revertInvalidCollectionsBytes() } // Store basicCollectionsHash to memory[0xe0]. mstore(0xe0, keccak256(0, ptrCollectionHash)) // Store collectionsHash to memory[0x100]. mstore(0x100, _EMPTY_ARRAY_KECCAK256) } // Order.collections is not empty. default { // Store basicCollectionsHash to memory[0xe0]. mstore(0xe0, basicCollectionsHash) // Store collectionsHash to memory[0x100]. mstore(0x100, keccak256(0, ptrCollectionHash)) } ///////////////////////////////// functions ///////////////////////////////// function _revertInvalidNftAddress() { // revert("fillBatchSignedERC721Order: invalid nftAddress.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002f66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c6964206e6674416464726573732e00000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertInvalidItemCount() { // revert("fillBatchSignedERC721Order: invalid itemCount.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000002e66696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c6964206974656d436f756e742e0000000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertInvalidFilledCount() { // revert("fillBatchSignedERC721Order: invalid filledCount.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003066696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c69642066696c6c6564436f756e742e000000000000000000000000) mstore(0x80, 0) revert(0, 0x84) } function _revertInvalidCollectionsBytes() { // revert("fillBatchSignedERC721Order: invalid collectionsBytes.") mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) mstore(0x20, 0x0000002000000000000000000000000000000000000000000000000000000000) mstore(0x40, 0x0000003566696c6c42617463685369676e65644552433732314f726465723a20) mstore(0x60, 0x696e76616c696420636f6c6c656374696f6e7342797465732e00000000000000) mstore(0x80, 0) revert(0, 0x84) } } } }
// SPDX-License-Identifier: Apache-2.0 /* Copyright 2022 Element.Market Intl. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity ^0.8.17; interface IBatchSignedERC721OrdersFeature { /// @param fee [16 bits(platformFeePercentage) + 16 bits(royaltyFeePercentage) + 160 bits(royaltyFeeRecipient)]. /// @param items [96 bits(erc20TokenAmount) + 160 bits(nftId)]. /// struct BasicCollection { /// address nftAddress; /// bytes32 fee; /// bytes32[] items; /// } /// /// struct OrderItem { /// uint256 erc20TokenAmount; /// uint256 nftId; /// } /// /// @param fee [16 bits(platformFeePercentage) + 16 bits(royaltyFeePercentage) + 160 bits(royaltyFeeRecipient)]. /// struct Collection { /// address nftAddress; /// bytes32 fee; /// OrderItem[] items; /// } /// /// struct BatchSignedERC721Orders { /// address maker; /// uint256 listingTime; /// uint256 expiryTime; /// uint256 startNonce; /// address erc20Token; /// address platformFeeRecipient; /// BasicCollection[] basicCollections; /// Collection[] collections; /// uint256 hashNonce; /// } /// @param data1 [8 bits(signatureType) + 8 bits(reserved) + 40 bits(startNonce) + 8 bits(v) + 32 bits(listingTime) + 160 bits(maker)] /// @param data2 [64 bits(taker part1) + 32 bits(expiryTime) + 160 bits(erc20Token)] /// @param data3 [96 bits(taker part2) + 160 bits(platformFeeRecipient)] struct BatchSignedERC721OrderParameter { uint256 data1; uint256 data2; uint256 data3; bytes32 r; bytes32 s; } function fillBatchSignedERC721Order(BatchSignedERC721OrderParameter calldata parameter, bytes calldata collections) external payable; /// @param data1 [8 bits(signatureType) + 8 bits(reserved) + 40 bits(startNonce) + 8 bits(v) + 32 bits(listingTime) + 160 bits(maker)] /// @param data2 [64 bits(taker part1) + 32 bits(expiryTime) + 160 bits(erc20Token)] /// @param data3 [96 bits(taker part2) + 160 bits(platformFeeRecipient)] struct BatchSignedERC721OrderParameters { uint256 data1; uint256 data2; uint256 data3; bytes32 r; bytes32 s; bytes collections; } /// @param additional1 [96 bits(withdrawETHAmount) + 160 bits(erc20Token)] /// @param additional2 [8 bits(revertIfIncomplete) + 88 bits(unused) + 160 bits(royaltyFeeRecipient)] function fillBatchSignedERC721Orders( BatchSignedERC721OrderParameters[] calldata parameters, uint256 additional1, uint256 additional2 ) external payable; }
// SPDX-License-Identifier: Apache-2.0 /* Copyright 2022 Element.Market Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity ^0.8.17; import "./LibStorage.sol"; library LibCommonNftOrdersStorage { /// @dev Storage bucket for this feature. struct Storage { /* Track per-maker nonces that can be incremented by the maker to cancel orders in bulk. */ // The current nonce for the maker represents the only valid nonce that can be signed by the maker // If a signature was signed with a nonce that's different from the one stored in nonces, it // will fail validation. mapping(address => uint256) hashNonces; } /// @dev Get the storage bucket for this contract. function getStorage() internal pure returns (Storage storage stor) { uint256 storageSlot = LibStorage.STORAGE_ID_COMMON_NFT_ORDERS; // Dip into assembly to change the slot pointed to by the local // variable `stor`. // See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries assembly { stor.slot := storageSlot } } }
// SPDX-License-Identifier: Apache-2.0 /* Modifications Copyright 2022 Element.Market Copyright 2020 ZeroEx Intl. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity ^0.8.17; import "./LibStorage.sol"; /// @dev Storage helpers for `ERC721OrdersFeature`. library LibERC721OrdersStorage { /// @dev Storage bucket for this feature. struct Storage { // maker => nonce range => order status bit vector mapping(address => mapping(uint248 => uint256)) orderStatusByMaker; // order hash => preSigned mapping(bytes32 => uint256) preSigned; // order hash => filledAmount mapping(bytes32 => uint128) filledAmount; } /// @dev Get the storage bucket for this contract. function getStorage() internal pure returns (Storage storage stor) { uint256 storageSlot = LibStorage.STORAGE_ID_ERC721_ORDERS; // Dip into assembly to change the slot pointed to by the local // variable `stor`. // See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries assembly { stor.slot := storageSlot } } }
// SPDX-License-Identifier: Apache-2.0 /* Modifications Copyright 2022 Element.Market Copyright 2020 ZeroEx Intl. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ pragma solidity ^0.8.17; /// @dev Common storage helpers library LibStorage { /// @dev What to bit-shift a storage ID by to get its slot. /// This gives us a maximum of 2**128 inline fields in each bucket. uint256 constant STORAGE_ID_PROXY = 1 << 128; uint256 constant STORAGE_ID_SIMPLE_FUNCTION_REGISTRY = 2 << 128; uint256 constant STORAGE_ID_OWNABLE = 3 << 128; uint256 constant STORAGE_ID_COMMON_NFT_ORDERS = 4 << 128; uint256 constant STORAGE_ID_ERC721_ORDERS = 5 << 128; uint256 constant STORAGE_ID_ERC1155_ORDERS = 6 << 128; uint256 constant STORAGE_ID_REENTRANCY_GUARD = 7 << 128; }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"components":[{"internalType":"uint256","name":"data1","type":"uint256"},{"internalType":"uint256","name":"data2","type":"uint256"},{"internalType":"uint256","name":"data3","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IBatchSignedERC721OrdersFeature.BatchSignedERC721OrderParameter","name":"","type":"tuple"},{"internalType":"address","name":"erc20TokenFromDelegateCall","type":"address"},{"internalType":"address","name":"platformFeeRecipientFromDelegateCall","type":"address"},{"internalType":"address","name":"royaltyFeeRecipientFromDelegateCall","type":"address"},{"internalType":"bytes","name":"collections","type":"bytes"}],"name":"delegateCallFillBatchSignedERC721Order","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"data1","type":"uint256"},{"internalType":"uint256","name":"data2","type":"uint256"},{"internalType":"uint256","name":"data3","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IBatchSignedERC721OrdersFeature.BatchSignedERC721OrderParameter","name":"","type":"tuple"},{"internalType":"bytes","name":"collections","type":"bytes"}],"name":"fillBatchSignedERC721Order","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"data1","type":"uint256"},{"internalType":"uint256","name":"data2","type":"uint256"},{"internalType":"uint256","name":"data3","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"collections","type":"bytes"}],"internalType":"struct IBatchSignedERC721OrdersFeature.BatchSignedERC721OrderParameters[]","name":"parameters","type":"tuple[]"},{"internalType":"uint256","name":"additional1","type":"uint256"},{"internalType":"uint256","name":"additional2","type":"uint256"}],"name":"fillBatchSignedERC721Orders","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60c060405234801561001057600080fd5b5060405162001e7438038062001e74833981016040819052610031916100a0565b6001600160a01b03811661008b5760405162461bcd60e51b815260206004820152601460248201527f494e56414c49445f574554485f41444452455353000000000000000000000000604482015260640160405180910390fd5b6001600160a01b031660a052306080526100d0565b6000602082840312156100b257600080fd5b81516001600160a01b03811681146100c957600080fd5b9392505050565b60805160a051611d77620000fd600039600061014601526000818161012501526106bb0152611d776000f3fe6080604052600436106100345760003560e01c8063149b8ce614610039578063a4d730411461004e578063dc055ecc14610061575b600080fd5b61004c610047366004611ae8565b610074565b005b61004c61005c366004611bcb565b6105e6565b61004c61006f366004611c3b565b6106b9565b826100df5760405162461bcd60e51b815260206004820152603060248201527f66696c6c42617463685369676e65644552433732314f72646572733a20696e7660448201526f30b634b2103830b930b6b2ba32b9399760811b60648201526084015b60405180910390fd5b60006100eb3447611cc4565b905060006001600160a01b038686600081811061010a5761010a611ceb565b905060200281019061011c9190611d01565b604001351690507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060a086901c6001600160a01b038088169087166000808085156101b15761018d8630896102c4565b632e1a7d4d600052856020526000806024601c60008b5af16101b1576101b1610429565b63dc055ecc6040528461010052886101205283610140526101206101605260208d028e0195508d5b868110156102585780358f0160a08160603760c081013560208106156102015761020161048b565b80610180528060e083016101a037604060008261014401605c8e5af4801561023a5760019450600051870196506020518601955061024d565b8e60001a1561024d573d6000803e3d6000fd5b5050506020016101d9565b50821561026a5761026a838a876102c4565b811561027b5761027b8285876102c4565b80610288576102886104ed565b50505050505083470361029757005b834711156102b757600080600080874703335af161004c5761004c610543565b6102bf610543565b6105dc565b8073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee811461034957813b6102ee576102ee61059e565b6323b872dd600052336020528260405283606052602060006064601c6000865af161031b5761031b6103c7565b3d156103445760203d1015610332576103326103c7565b600160005114610344576103446103c7565b61035f565b60008060008087875af161035f5761035f610365565b50505050565b62461bcd60e51b600052600160e51b6020527c3466696c6c42617463685369676e65644552433732314f72646572733a6040527f206661696c656420746f207472616e73666572204554482e0000000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3666696c6c42617463685369676e65644552433732314f72646572733a6040527f206661696c656420746f207472616e736665722045524332302e000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3466696c6c42617463685369676e65644552433732314f72646572733a6040527f206661696c656420746f207769746864726177204554482e0000000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3666696c6c42617463685369676e65644552433732314f72646572733a6040527f20696e76616c696420636f6c6c656374696f6e7342797465732e000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2d66696c6c42617463685369676e65644552433732314f72646572733a604052701037379037b93232b9103334b63632b21760791b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3266696c6c42617463685369676e65644552433732314f72646572733a60405275103330b4b632b2103a37903932b33ab7321022aa241760511b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c13696e76616c696420657263323020746f6b656e000000000000000000604052600060605260646000fd5b5050505050505050565b60006105f23447611cc4565b90508260006106008261079b565b90508060005260006103805260006103a05260006103c05261062182610c76565b82470361062a57005b8247111561064a57600080600080864703335af161004c5761004c610657565b610652610657565b6106b1565b62461bcd60e51b600052600160e51b6020527c3166696c6c42617463685369676e65644552433732314f726465723a20604052743330b4b632b2103a37903932b33ab7321022aa241760591b606052600060805260846000fd5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000060003082036107695762461bcd60e51b600052600160e51b6020527c5464656c656761746543616c6c46696c6c42617463685369676e6564456040527f52433732314f726465723a206d7573742064656c656761746543616c6c2066726060527f6f6d20616e2065787465726e616c2065786368616e67652e0000000000000000608052600060a05260a46000fd5b508260006107768261079b565b9050806000528761038052866103a052856103c05261079482610c76565b60406103e0f35b60008060043580821a90600781901a906024354260a083901c63ffffffff1611156108225762461bcd60e51b600052600160e51b6020527c3c66696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f20636865636b20666f72206c697374696e6754696d652e606052600060805260846000fd5b4263ffffffff8260a01c16116108945762461bcd60e51b600052600160e51b6020527c3b66696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f20636865636b20666f722065787069727954696d652e00606052600060805260846000fd5b6001600160a01b0381166108fa5762461bcd60e51b600052600160e51b6020527c2f66696c6c42617463685369676e65644552433732314f726465723a206040527234b73b30b634b21032b93199182a37b5b2b71760691b606052600060805260846000fd5b506001600160a01b031692508261095e5762461bcd60e51b600052600160e51b6020527c2a66696c6c42617463685369676e65644552433732314f726465723a206040526d34b73b30b634b21036b0b5b2b91760911b606052600060805260846000fd5b610a0161096a8661168d565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000527f27b14c20196091d9cd90ca9c473d3ad1523b00ddf487a9b7452a8a119a16b98c6020527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c604052466060523060805261190160f01b60a05260a060002060a2528160c252604260a0209050919050565b93508160ff16600003610af8576000606081905260805260a0604081905284905260ff811660c05260643560e081905260843561010081905260016101206020604051602081039080840390855afa158015610a61573d6000803e3d6000fd5b505050602060405103516001600160a01b0316856001600160a01b031614610af15760405162461bcd60e51b815260206004820152603960248201527f66696c6c42617463685369676e65644552433732314f726465723a206661696c60448201527f656420746f2076616c6964617465207369676e61747572652e0000000000000060648201526084016100d6565b5050610c6e565b8160ff16600303610c1257631626ba7e60005283602052604080526041606052604060646080378060f81b60c052823b610b3457610b34610b68565b6020600060a5601c865afa610b4b57610b4b610bbb565b630b135d3f60e11b60005114610b6357610b63610bbb565b610c6e565b62461bcd60e51b600052600160e51b6020527c2a66696c6c42617463685369676e65644552433732314f726465723a206040526d34b73b30b634b21036b0b5b2b91760911b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3266696c6c42617463685369676e65644552433732314f726465723a206040527134b73b30b634b21039b4b3b730ba3ab9329760711b606052600060805260846000fd5b62461bcd60e51b6000908152600160e51b6020527c3266696c6c42617463685369676e65644552433732314f726465723a206040527534b73b30b634b21039b4b3b730ba3ab932aa3cb8329760511b6060526080819052608490fd5b505050919050565b6001600160a01b036004351660205260443560a01c60243560c01c60601b17604052604051610ca457336040525b6001600160a01b036024351660805261012060c0526323b872dd6101c0526020516101e05260405161020052600061024052600160f81b6102c0526020516102e052600560801b6103005260406102e0206102e05260006103605260006103e0526000610400526323b872dd610420523361044052600064ffffffffff60043560c81c166001600160a01b036044351660008060208603358601865b81811015611291576001600160a01b0381351660e05260208101356103005263ffffffff60801b6103005160401c166001600160a01b0319823516176103005160021a6103005160011a8115610dc15780821115610da057610da0611427565b6080821115610db157610db1611427565b60e0513b610dc157610dc161164f565b87610140528760008114610de35761ffff6103005160b01c1661032052610dea565b6000610320525b50610300516001600160a01b03166101808190528015610e185761ffff6103005160a01c1661034052610e1f565b6000610340525b506127106103405161032051011115610e3a57610e3a6113b6565b60006103005160001a60008114611052575b83156110425760018403935084841a838110610e6a57610e6a611427565b808c0160605260605160081c6102c05114610ecc576102405115610eab5761028051548d14610e9b57610e9b611480565b6102a05161028051556000610240525b60605160081c6102c05260406102c0206102805261028051549c508c6102a0525b600160ff606051161b61026052610260516102a0511661103c576040810260408801016001600160e01b0381351115610f0757610f076114d4565b60208101356102205260008060646101dc600060e0515af11561103a57600161024052610260516102a051176102a052803560a0526127106103205160a0510204610160526127106103405160a05102046101a0526101a051610160510160a051038a019950610160518b019a506101a0518401935061022051610100528b60008114610fda57610180518015610fb857600261012052600080516020611d228339815191526101c06000a1610fd4565b600161012052600080516020611d228339815191526101806000a15b50611032565b6101805180156110145760016101205261018051610140526101a05161016052600080516020611d228339815191526101806000a1611030565b600061012052600080516020611d228339815191526101406000a15b505b506001610360525b505b50610e4c565b6040830260408701019550611244565b83156112385760018403935084841a83811061107057611070611427565b808c0160605260605160081c6102c051146110d25761024051156110b15761028051548d146110a1576110a1611480565b6102a05161028051556000610240525b60605160081c6102c05260406102c0206102805261028051549c508c6102a0525b600160ff606051161b61026052610260516102a0511661123257602081026040880101356001600160a01b0381166102205260008060646101dc600060e0515af11561123057600161024052610260516102a051176102a0528060a01c60a0526127106103205160a0510204610160526127106103405160a05102046101a0526101a051610160510160a051038a019950610160518b019a506101a0518401935061022051610100528b600081146111d0576101805180156111ae57600261012052600080516020611d228339815191526101c06000a16111ca565b600161012052600080516020611d228339815191526101806000a15b50611228565b61018051801561120a5760016101205261018051610140526101a05161016052600080516020611d228339815191526101806000a1611226565b600061012052600080516020611d228339815191526101406000a15b505b506001610360525b505b50611052565b60208302604087010195505b50988101988015611288576103c05161018051146103805160805114166001811461127b57611276826101805161131c565b611286565b816104005101610400525b505b50505050610d40565b505061024051156112b957610280515485146112af576112af611480565b6102a05161028051555b80156112cb576112cb8160205161131c565b508015611305576103a0518214610380516080511416600181146112f8576112f3828461131c565b611303565b816103e051016103e0525b505b505050506103605161131957611319611536565b50565b60805173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81146113a0576080513b61134a5761134a61059e565b816104605282610480526020610480606461043c60006080515af1611371576113716115ed565b3d1561139b5760203d1015611388576113886115ed565b6001610480511461139b5761139b6115ed565b505050565b60008060008086865af161139b5761139b61158b565b62461bcd60e51b600052600160e51b6020527c4466696c6c42617463685369676e65644552433732314f726465723a206040527f746f74616c20666565732070657263656e7461676520657863656564732074686060526732903634b6b4ba1760c11b608052600060a05260a46000fd5b62461bcd60e51b600052600160e51b6020527c3066696c6c42617463685369676e65644552433732314f726465723a206040527334b73b30b634b2103334b63632b224b73232bc1760611b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2b66696c6c42617463685369676e65644552433732314f726465723a206040526e3932b2b73a3930b73a1031b0b6361760891b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3b66696c6c42617463685369676e65644552433732314f726465723a206040527f6572633230546f6b656e416d6f756e742065786365656473206c696d69742e00606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2c66696c6c42617463685369676e65644552433732314f726465723a206040526f37379037b93232b9103334b63632b21760811b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3366696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f207472616e73666572204554482e000000000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3566696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f207472616e736665722045524332302e00000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c14696e76616c69642065726337323120746f6b656e0000000000000000604052600060605260646000fd5b60006116988261173f565b6004356024356044356001600160a01b0383167f2d8cbbbc696e7292c3b5beb38e1363d34ff11beb8c3456c14cb938854597b9ed6000528060205263ffffffff8460a01c1660405263ffffffff8360a01c1660605264ffffffffff8460c81c166080526001600160a01b03831660a0526001600160a01b03821660c052806101205250505050600160821b6101405260406101202054610120526101406000209050919050565b600080600083602085033585015b80821015611912576001600160a01b038235168061176d5761176d61197e565b60208301358060011a80611783576117836119d6565b8160021a60108111828211171561179c5761179c611a2d565b508160001a6118195787156117b3576117b3611a86565b7f12ad29288fd70022f26997a9958d9eceb6e840ceaa79b72ea5945ba87e4d33b086528260208701526001600160c01b03821660408701526060860160208202604087018181843781832090925260808820885260209097019601945061174d92505050565b8761185b57600197508580156118355760009687209750611859565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47097505b505b7fb9f488d48cec782be9ecdb74330c9c6a33c236a8022d8a91a4e4df4e81b5162086528260208701526001600160c01b0382166040870152606086019250604081029150604085018281602086013783602083028501855b818110156118f2577f5f93394997caa49a9382d44a75e3ce6a460f32b39870464866ac994f8be97afe83526060832081526040909201916020016118b3565b50505060209182028420909352608086208652949094019301915061174d565b80821461192157611921611a86565b5050826000811461193d578260e0528160002061010052611977565b8161194a5761194a611a86565b8160002060e0527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470610100525b5050505050565b62461bcd60e51b600052600160e51b6020527c2f66696c6c42617463685369676e65644552433732314f726465723a206040527234b73b30b634b21037333a20b2323932b9b99760691b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2e66696c6c42617463685369676e65644552433732314f726465723a206040527134b73b30b634b21034ba32b6a1b7bab73a1760711b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3066696c6c42617463685369676e65644552433732314f726465723a206040527334b73b30b634b2103334b63632b221b7bab73a1760611b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3566696c6c42617463685369676e65644552433732314f726465723a206040527f696e76616c696420636f6c6c656374696f6e7342797465732e00000000000000606052600060805260846000fd5b60008060008060608587031215611afe57600080fd5b843567ffffffffffffffff80821115611b1657600080fd5b818701915087601f830112611b2a57600080fd5b813581811115611b3957600080fd5b8860208260051b8501011115611b4e57600080fd5b6020928301999098509187013596604001359550909350505050565b600060a08284031215611b7c57600080fd5b50919050565b60008083601f840112611b9457600080fd5b50813567ffffffffffffffff811115611bac57600080fd5b602083019150836020828501011115611bc457600080fd5b9250929050565b600080600060c08486031215611be057600080fd5b611bea8585611b6a565b925060a084013567ffffffffffffffff811115611c0657600080fd5b611c1286828701611b82565b9497909650939450505050565b80356001600160a01b0381168114611c3657600080fd5b919050565b6000806000806000806101208789031215611c5557600080fd5b611c5f8888611b6a565b9550611c6d60a08801611c1f565b9450611c7b60c08801611c1f565b9350611c8960e08801611c1f565b925061010087013567ffffffffffffffff811115611ca657600080fd5b611cb289828a01611b82565b979a9699509497509295939492505050565b81810381811115611ce557634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052603260045260246000fd5b6000823560be19833603018112611d1757600080fd5b919091019291505056fe9c248aa1a265aa616f707b979d57f4529bb63a4fc34dc7fc61fdddc18410f74ea26469706673582212207e6d7da2e62429583e7fb05fc6c74592fddb9eeaca0eda3b830e4aa3be0884c964736f6c63430008110033000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f
Deployed Bytecode
0x6080604052600436106100345760003560e01c8063149b8ce614610039578063a4d730411461004e578063dc055ecc14610061575b600080fd5b61004c610047366004611ae8565b610074565b005b61004c61005c366004611bcb565b6105e6565b61004c61006f366004611c3b565b6106b9565b826100df5760405162461bcd60e51b815260206004820152603060248201527f66696c6c42617463685369676e65644552433732314f72646572733a20696e7660448201526f30b634b2103830b930b6b2ba32b9399760811b60648201526084015b60405180910390fd5b60006100eb3447611cc4565b905060006001600160a01b038686600081811061010a5761010a611ceb565b905060200281019061011c9190611d01565b604001351690507f0000000000000000000000002d4fb6f3f9dc2ec67676be55d5301b2be21930327f000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f60a086901c6001600160a01b038088169087166000808085156101b15761018d8630896102c4565b632e1a7d4d600052856020526000806024601c60008b5af16101b1576101b1610429565b63dc055ecc6040528461010052886101205283610140526101206101605260208d028e0195508d5b868110156102585780358f0160a08160603760c081013560208106156102015761020161048b565b80610180528060e083016101a037604060008261014401605c8e5af4801561023a5760019450600051870196506020518601955061024d565b8e60001a1561024d573d6000803e3d6000fd5b5050506020016101d9565b50821561026a5761026a838a876102c4565b811561027b5761027b8285876102c4565b80610288576102886104ed565b50505050505083470361029757005b834711156102b757600080600080874703335af161004c5761004c610543565b6102bf610543565b6105dc565b8073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee811461034957813b6102ee576102ee61059e565b6323b872dd600052336020528260405283606052602060006064601c6000865af161031b5761031b6103c7565b3d156103445760203d1015610332576103326103c7565b600160005114610344576103446103c7565b61035f565b60008060008087875af161035f5761035f610365565b50505050565b62461bcd60e51b600052600160e51b6020527c3466696c6c42617463685369676e65644552433732314f72646572733a6040527f206661696c656420746f207472616e73666572204554482e0000000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3666696c6c42617463685369676e65644552433732314f72646572733a6040527f206661696c656420746f207472616e736665722045524332302e000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3466696c6c42617463685369676e65644552433732314f72646572733a6040527f206661696c656420746f207769746864726177204554482e0000000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3666696c6c42617463685369676e65644552433732314f72646572733a6040527f20696e76616c696420636f6c6c656374696f6e7342797465732e000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2d66696c6c42617463685369676e65644552433732314f72646572733a604052701037379037b93232b9103334b63632b21760791b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3266696c6c42617463685369676e65644552433732314f72646572733a60405275103330b4b632b2103a37903932b33ab7321022aa241760511b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c13696e76616c696420657263323020746f6b656e000000000000000000604052600060605260646000fd5b5050505050505050565b60006105f23447611cc4565b90508260006106008261079b565b90508060005260006103805260006103a05260006103c05261062182610c76565b82470361062a57005b8247111561064a57600080600080864703335af161004c5761004c610657565b610652610657565b6106b1565b62461bcd60e51b600052600160e51b6020527c3166696c6c42617463685369676e65644552433732314f726465723a20604052743330b4b632b2103a37903932b33ab7321022aa241760591b606052600060805260846000fd5b505050505050565b7f0000000000000000000000002d4fb6f3f9dc2ec67676be55d5301b2be219303260003082036107695762461bcd60e51b600052600160e51b6020527c5464656c656761746543616c6c46696c6c42617463685369676e6564456040527f52433732314f726465723a206d7573742064656c656761746543616c6c2066726060527f6f6d20616e2065787465726e616c2065786368616e67652e0000000000000000608052600060a05260a46000fd5b508260006107768261079b565b9050806000528761038052866103a052856103c05261079482610c76565b60406103e0f35b60008060043580821a90600781901a906024354260a083901c63ffffffff1611156108225762461bcd60e51b600052600160e51b6020527c3c66696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f20636865636b20666f72206c697374696e6754696d652e606052600060805260846000fd5b4263ffffffff8260a01c16116108945762461bcd60e51b600052600160e51b6020527c3b66696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f20636865636b20666f722065787069727954696d652e00606052600060805260846000fd5b6001600160a01b0381166108fa5762461bcd60e51b600052600160e51b6020527c2f66696c6c42617463685369676e65644552433732314f726465723a206040527234b73b30b634b21032b93199182a37b5b2b71760691b606052600060805260846000fd5b506001600160a01b031692508261095e5762461bcd60e51b600052600160e51b6020527c2a66696c6c42617463685369676e65644552433732314f726465723a206040526d34b73b30b634b21036b0b5b2b91760911b606052600060805260846000fd5b610a0161096a8661168d565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000527f27b14c20196091d9cd90ca9c473d3ad1523b00ddf487a9b7452a8a119a16b98c6020527f06c015bd22b4c69690933c1058878ebdfef31f9aaae40bbe86d8a09fe1b2972c604052466060523060805261190160f01b60a05260a060002060a2528160c252604260a0209050919050565b93508160ff16600003610af8576000606081905260805260a0604081905284905260ff811660c05260643560e081905260843561010081905260016101206020604051602081039080840390855afa158015610a61573d6000803e3d6000fd5b505050602060405103516001600160a01b0316856001600160a01b031614610af15760405162461bcd60e51b815260206004820152603960248201527f66696c6c42617463685369676e65644552433732314f726465723a206661696c60448201527f656420746f2076616c6964617465207369676e61747572652e0000000000000060648201526084016100d6565b5050610c6e565b8160ff16600303610c1257631626ba7e60005283602052604080526041606052604060646080378060f81b60c052823b610b3457610b34610b68565b6020600060a5601c865afa610b4b57610b4b610bbb565b630b135d3f60e11b60005114610b6357610b63610bbb565b610c6e565b62461bcd60e51b600052600160e51b6020527c2a66696c6c42617463685369676e65644552433732314f726465723a206040526d34b73b30b634b21036b0b5b2b91760911b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3266696c6c42617463685369676e65644552433732314f726465723a206040527134b73b30b634b21039b4b3b730ba3ab9329760711b606052600060805260846000fd5b62461bcd60e51b6000908152600160e51b6020527c3266696c6c42617463685369676e65644552433732314f726465723a206040527534b73b30b634b21039b4b3b730ba3ab932aa3cb8329760511b6060526080819052608490fd5b505050919050565b6001600160a01b036004351660205260443560a01c60243560c01c60601b17604052604051610ca457336040525b6001600160a01b036024351660805261012060c0526323b872dd6101c0526020516101e05260405161020052600061024052600160f81b6102c0526020516102e052600560801b6103005260406102e0206102e05260006103605260006103e0526000610400526323b872dd610420523361044052600064ffffffffff60043560c81c166001600160a01b036044351660008060208603358601865b81811015611291576001600160a01b0381351660e05260208101356103005263ffffffff60801b6103005160401c166001600160a01b0319823516176103005160021a6103005160011a8115610dc15780821115610da057610da0611427565b6080821115610db157610db1611427565b60e0513b610dc157610dc161164f565b87610140528760008114610de35761ffff6103005160b01c1661032052610dea565b6000610320525b50610300516001600160a01b03166101808190528015610e185761ffff6103005160a01c1661034052610e1f565b6000610340525b506127106103405161032051011115610e3a57610e3a6113b6565b60006103005160001a60008114611052575b83156110425760018403935084841a838110610e6a57610e6a611427565b808c0160605260605160081c6102c05114610ecc576102405115610eab5761028051548d14610e9b57610e9b611480565b6102a05161028051556000610240525b60605160081c6102c05260406102c0206102805261028051549c508c6102a0525b600160ff606051161b61026052610260516102a0511661103c576040810260408801016001600160e01b0381351115610f0757610f076114d4565b60208101356102205260008060646101dc600060e0515af11561103a57600161024052610260516102a051176102a052803560a0526127106103205160a0510204610160526127106103405160a05102046101a0526101a051610160510160a051038a019950610160518b019a506101a0518401935061022051610100528b60008114610fda57610180518015610fb857600261012052600080516020611d228339815191526101c06000a1610fd4565b600161012052600080516020611d228339815191526101806000a15b50611032565b6101805180156110145760016101205261018051610140526101a05161016052600080516020611d228339815191526101806000a1611030565b600061012052600080516020611d228339815191526101406000a15b505b506001610360525b505b50610e4c565b6040830260408701019550611244565b83156112385760018403935084841a83811061107057611070611427565b808c0160605260605160081c6102c051146110d25761024051156110b15761028051548d146110a1576110a1611480565b6102a05161028051556000610240525b60605160081c6102c05260406102c0206102805261028051549c508c6102a0525b600160ff606051161b61026052610260516102a0511661123257602081026040880101356001600160a01b0381166102205260008060646101dc600060e0515af11561123057600161024052610260516102a051176102a0528060a01c60a0526127106103205160a0510204610160526127106103405160a05102046101a0526101a051610160510160a051038a019950610160518b019a506101a0518401935061022051610100528b600081146111d0576101805180156111ae57600261012052600080516020611d228339815191526101c06000a16111ca565b600161012052600080516020611d228339815191526101806000a15b50611228565b61018051801561120a5760016101205261018051610140526101a05161016052600080516020611d228339815191526101806000a1611226565b600061012052600080516020611d228339815191526101406000a15b505b506001610360525b505b50611052565b60208302604087010195505b50988101988015611288576103c05161018051146103805160805114166001811461127b57611276826101805161131c565b611286565b816104005101610400525b505b50505050610d40565b505061024051156112b957610280515485146112af576112af611480565b6102a05161028051555b80156112cb576112cb8160205161131c565b508015611305576103a0518214610380516080511416600181146112f8576112f3828461131c565b611303565b816103e051016103e0525b505b505050506103605161131957611319611536565b50565b60805173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81146113a0576080513b61134a5761134a61059e565b816104605282610480526020610480606461043c60006080515af1611371576113716115ed565b3d1561139b5760203d1015611388576113886115ed565b6001610480511461139b5761139b6115ed565b505050565b60008060008086865af161139b5761139b61158b565b62461bcd60e51b600052600160e51b6020527c4466696c6c42617463685369676e65644552433732314f726465723a206040527f746f74616c20666565732070657263656e7461676520657863656564732074686060526732903634b6b4ba1760c11b608052600060a05260a46000fd5b62461bcd60e51b600052600160e51b6020527c3066696c6c42617463685369676e65644552433732314f726465723a206040527334b73b30b634b2103334b63632b224b73232bc1760611b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2b66696c6c42617463685369676e65644552433732314f726465723a206040526e3932b2b73a3930b73a1031b0b6361760891b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3b66696c6c42617463685369676e65644552433732314f726465723a206040527f6572633230546f6b656e416d6f756e742065786365656473206c696d69742e00606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2c66696c6c42617463685369676e65644552433732314f726465723a206040526f37379037b93232b9103334b63632b21760811b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3366696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f207472616e73666572204554482e000000000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3566696c6c42617463685369676e65644552433732314f726465723a206040527f6661696c656420746f207472616e736665722045524332302e00000000000000606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c14696e76616c69642065726337323120746f6b656e0000000000000000604052600060605260646000fd5b60006116988261173f565b6004356024356044356001600160a01b0383167f2d8cbbbc696e7292c3b5beb38e1363d34ff11beb8c3456c14cb938854597b9ed6000528060205263ffffffff8460a01c1660405263ffffffff8360a01c1660605264ffffffffff8460c81c166080526001600160a01b03831660a0526001600160a01b03821660c052806101205250505050600160821b6101405260406101202054610120526101406000209050919050565b600080600083602085033585015b80821015611912576001600160a01b038235168061176d5761176d61197e565b60208301358060011a80611783576117836119d6565b8160021a60108111828211171561179c5761179c611a2d565b508160001a6118195787156117b3576117b3611a86565b7f12ad29288fd70022f26997a9958d9eceb6e840ceaa79b72ea5945ba87e4d33b086528260208701526001600160c01b03821660408701526060860160208202604087018181843781832090925260808820885260209097019601945061174d92505050565b8761185b57600197508580156118355760009687209750611859565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47097505b505b7fb9f488d48cec782be9ecdb74330c9c6a33c236a8022d8a91a4e4df4e81b5162086528260208701526001600160c01b0382166040870152606086019250604081029150604085018281602086013783602083028501855b818110156118f2577f5f93394997caa49a9382d44a75e3ce6a460f32b39870464866ac994f8be97afe83526060832081526040909201916020016118b3565b50505060209182028420909352608086208652949094019301915061174d565b80821461192157611921611a86565b5050826000811461193d578260e0528160002061010052611977565b8161194a5761194a611a86565b8160002060e0527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470610100525b5050505050565b62461bcd60e51b600052600160e51b6020527c2f66696c6c42617463685369676e65644552433732314f726465723a206040527234b73b30b634b21037333a20b2323932b9b99760691b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c2e66696c6c42617463685369676e65644552433732314f726465723a206040527134b73b30b634b21034ba32b6a1b7bab73a1760711b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3066696c6c42617463685369676e65644552433732314f726465723a206040527334b73b30b634b2103334b63632b221b7bab73a1760611b606052600060805260846000fd5b62461bcd60e51b600052600160e51b6020527c3566696c6c42617463685369676e65644552433732314f726465723a206040527f696e76616c696420636f6c6c656374696f6e7342797465732e00000000000000606052600060805260846000fd5b60008060008060608587031215611afe57600080fd5b843567ffffffffffffffff80821115611b1657600080fd5b818701915087601f830112611b2a57600080fd5b813581811115611b3957600080fd5b8860208260051b8501011115611b4e57600080fd5b6020928301999098509187013596604001359550909350505050565b600060a08284031215611b7c57600080fd5b50919050565b60008083601f840112611b9457600080fd5b50813567ffffffffffffffff811115611bac57600080fd5b602083019150836020828501011115611bc457600080fd5b9250929050565b600080600060c08486031215611be057600080fd5b611bea8585611b6a565b925060a084013567ffffffffffffffff811115611c0657600080fd5b611c1286828701611b82565b9497909650939450505050565b80356001600160a01b0381168114611c3657600080fd5b919050565b6000806000806000806101208789031215611c5557600080fd5b611c5f8888611b6a565b9550611c6d60a08801611c1f565b9450611c7b60c08801611c1f565b9350611c8960e08801611c1f565b925061010087013567ffffffffffffffff811115611ca657600080fd5b611cb289828a01611b82565b979a9699509497509295939492505050565b81810381811115611ce557634e487b7160e01b600052601160045260246000fd5b92915050565b634e487b7160e01b600052603260045260246000fd5b6000823560be19833603018112611d1757600080fd5b919091019291505056fe9c248aa1a265aa616f707b979d57f4529bb63a4fc34dc7fc61fdddc18410f74ea26469706673582212207e6d7da2e62429583e7fb05fc6c74592fddb9eeaca0eda3b830e4aa3be0884c964736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f
-----Decoded View---------------
Arg [0] : weth (address): 0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000e5d7c2a44ffddf6b295a15c148167daaaf5cf34f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.