Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
20312826 | 1 hr ago | 0.145 ETH | ||||
20312826 | 1 hr ago | 0.145 ETH | ||||
20311199 | 6 hrs ago | 0.03 ETH | ||||
20311199 | 6 hrs ago | 0.03 ETH | ||||
20310147 | 10 hrs ago | 0.0685 ETH | ||||
20310147 | 10 hrs ago | 0.0685 ETH | ||||
20309963 | 11 hrs ago | 0.001 ETH | ||||
20309963 | 11 hrs ago | 0.001 ETH | ||||
20309896 | 11 hrs ago | 0.001 ETH | ||||
20309896 | 11 hrs ago | 0.001 ETH | ||||
20309745 | 11 hrs ago | 0.001 ETH | ||||
20309745 | 11 hrs ago | 0.001 ETH | ||||
20308259 | 16 hrs ago | 0.014 ETH | ||||
20308259 | 16 hrs ago | 0.014 ETH | ||||
20307688 | 18 hrs ago | 0.0189 ETH | ||||
20307688 | 18 hrs ago | 0.0189 ETH | ||||
20307354 | 19 hrs ago | 0.0142 ETH | ||||
20307354 | 19 hrs ago | 0.0142 ETH | ||||
20304486 | 29 hrs ago | 0.000054 ETH | ||||
20304486 | 29 hrs ago | 0.0018 ETH | ||||
20304486 | 29 hrs ago | 0.001854 ETH | ||||
20303335 | 33 hrs ago | 0.089 ETH | ||||
20303335 | 33 hrs ago | 0.089 ETH | ||||
20303330 | 33 hrs ago | 0.085 ETH | ||||
20303330 | 33 hrs ago | 0.085 ETH |
Loading...
Loading
Contract Name:
ElementModule
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import {BaseExchangeModule} from "./BaseExchangeModule.sol"; import {BaseModule} from "../BaseModule.sol"; import {IElement} from "../../../interfaces/IElement.sol"; // Notes: // - supports filling listings (both ERC721/ERC1155) // - supports filling offers (both ERC721/ERC1155) contract ElementModule is BaseExchangeModule { using SafeERC20 for IERC20; // --- Fields --- IElement public immutable EXCHANGE; // --- Constructor --- constructor( address owner, address router, address exchange ) BaseModule(owner) BaseExchangeModule(router) { EXCHANGE = IElement(exchange); } // --- Fallback --- receive() external payable {} // --- [ERC721] Single ETH listing --- function acceptETHListingERC721( IElement.NFTSellOrder calldata order, IElement.Signature calldata signature, ETHListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundETHLeftover(params.refundTo) chargeETHFees(fees, params.amount) { // Execute fill _buyERC721Ex(order, signature, params.fillTo, params.revertIfIncomplete, params.amount); } // --- [ERC721] Single ERC20 listing --- function acceptERC20ListingERC721( IElement.NFTSellOrder calldata order, IElement.Signature calldata signature, ERC20ListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundERC20Leftover(params.refundTo, params.token) chargeERC20Fees(fees, params.token, params.amount) { // Approve the exchange if needed _approveERC20IfNeeded(params.token, address(EXCHANGE), params.amount); // Execute fill _buyERC721Ex(order, signature, params.fillTo, params.revertIfIncomplete, 0); } // --- [ERC721] Multiple ETH listings --- function acceptETHListingsERC721( IElement.NFTSellOrder[] calldata orders, IElement.Signature[] calldata signatures, ETHListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundETHLeftover(params.refundTo) chargeETHFees(fees, params.amount) { // Execute fill _buyERC721sEx(orders, signatures, params.fillTo, params.revertIfIncomplete, params.amount); } // --- [ERC721] Multiple ERC20 listings --- function acceptERC20ListingsERC721( IElement.NFTSellOrder[] calldata orders, IElement.Signature[] calldata signatures, ERC20ListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundERC20Leftover(params.refundTo, params.token) chargeERC20Fees(fees, params.token, params.amount) { // Approve the exchange if needed _approveERC20IfNeeded(params.token, address(EXCHANGE), params.amount); // Execute fill _buyERC721sEx(orders, signatures, params.fillTo, params.revertIfIncomplete, 0); } // --- [ERC721] Single ETH listing V2 --- function acceptETHListingERC721V2( IElement.BatchSignedOrder calldata order, ETHListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundETHLeftover(params.refundTo) chargeETHFees(fees, params.amount) { // Execute fill _fillBatchSignedOrder(order, params.fillTo, params.revertIfIncomplete, params.amount); } // --- [ERC721] Single ERC20 listing V2 --- function acceptERC20ListingERC721V2( IElement.BatchSignedOrder calldata order, ERC20ListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundERC20Leftover(params.refundTo, params.token) chargeERC20Fees(fees, params.token, params.amount) { // Approve the exchange if needed _approveERC20IfNeeded(params.token, address(EXCHANGE), params.amount); // Execute fill _fillBatchSignedOrder(order, params.fillTo, params.revertIfIncomplete, 0); } // --- [ERC721] Multiple ETH listings V2 --- function acceptETHListingsERC721V2( IElement.BatchSignedOrder[] calldata orders, ETHListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundETHLeftover(params.refundTo) chargeETHFees(fees, params.amount) { // Execute fill _fillBatchSignedOrders(orders, params.fillTo, params.revertIfIncomplete, params.amount); } // --- [ERC721] Multiple ERC20 listings V2 --- function acceptERC20ListingsERC721V2( IElement.BatchSignedOrder[] calldata orders, ERC20ListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundERC20Leftover(params.refundTo, params.token) chargeERC20Fees(fees, params.token, params.amount) { // Approve the exchange if needed _approveERC20IfNeeded(params.token, address(EXCHANGE), params.amount); // Execute fill _fillBatchSignedOrders(orders, params.fillTo, params.revertIfIncomplete, 0); } // --- [ERC1155] Single ETH listing --- function acceptETHListingERC1155( IElement.ERC1155SellOrder calldata order, IElement.Signature calldata signature, uint128 amount, ETHListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundETHLeftover(params.refundTo) chargeETHFees(fees, params.amount) { // Execute fill _buyERC1155Ex( order, signature, amount, params.fillTo, params.revertIfIncomplete, params.amount ); } // --- [ERC1155] Single ERC20 listing --- function acceptERC20ListingERC1155( IElement.ERC1155SellOrder calldata order, IElement.Signature calldata signature, uint128 amount, ERC20ListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundERC20Leftover(params.refundTo, params.token) chargeERC20Fees(fees, params.token, params.amount) { // Approve the exchange if needed _approveERC20IfNeeded(params.token, address(EXCHANGE), params.amount); // Execute fill _buyERC1155Ex(order, signature, amount, params.fillTo, params.revertIfIncomplete, 0); } // --- [ERC1155] Multiple ETH listings --- function acceptETHListingsERC1155( IElement.ERC1155SellOrder[] calldata orders, IElement.Signature[] calldata signatures, uint128[] calldata amounts, ETHListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundETHLeftover(params.refundTo) chargeETHFees(fees, params.amount) { // Execute fill _buyERC1155sEx( orders, signatures, amounts, params.fillTo, params.revertIfIncomplete, params.amount ); } // --- [ERC1155] Multiple ERC20 listings --- function acceptERC20ListingsERC1155( IElement.ERC1155SellOrder[] calldata orders, IElement.Signature[] calldata signatures, uint128[] calldata amounts, ERC20ListingParams calldata params, Fee[] calldata fees ) external payable nonReentrant refundERC20Leftover(params.refundTo, params.token) chargeERC20Fees(fees, params.token, params.amount) { // Approve the exchange if needed _approveERC20IfNeeded(params.token, address(EXCHANGE), params.amount); // Execute fill _buyERC1155sEx(orders, signatures, amounts, params.fillTo, params.revertIfIncomplete, 0); } // --- [ERC721] Single offer --- function acceptERC721Offer( IElement.NFTBuyOrder calldata order, IElement.Signature calldata signature, OfferParams calldata params, uint256 tokenId, Fee[] calldata fees ) external nonReentrant { // Approve the exchange if needed _approveERC721IfNeeded(IERC721(order.nft), address(EXCHANGE)); // Execute fill try EXCHANGE.sellERC721(order, signature, tokenId, false, "") { // Pay fees uint256 feesLength = fees.length; for (uint256 i; i < feesLength; ) { Fee memory fee = fees[i]; _sendERC20(fee.recipient, fee.amount, order.erc20Token); unchecked { ++i; } } // Forward any left payment to the specified receiver _sendAllERC20(params.fillTo, order.erc20Token); } catch { // Revert if specified if (params.revertIfIncomplete) { revert UnsuccessfulFill(); } } // Refund any ERC721 leftover _sendAllERC721(params.refundTo, IERC721(order.nft), tokenId); } // --- [ERC1155] Single offer --- function acceptERC1155Offer( IElement.ERC1155BuyOrder calldata order, IElement.Signature calldata signature, uint128 amount, OfferParams calldata params, uint256 tokenId, Fee[] calldata fees ) external nonReentrant { // Approve the exchange if needed _approveERC1155IfNeeded(IERC1155(order.erc1155Token), address(EXCHANGE)); // Execute fill try EXCHANGE.sellERC1155(order, signature, tokenId, amount, false, "") { // Pay fees uint256 feesLength = fees.length; for (uint256 i; i < feesLength; ) { Fee memory fee = fees[i]; _sendERC20(fee.recipient, fee.amount, order.erc20Token); unchecked { ++i; } } // Forward any left payment to the specified receiver _sendAllERC20(params.fillTo, order.erc20Token); } catch { // Revert if specified if (params.revertIfIncomplete) { revert UnsuccessfulFill(); } } // Refund any ERC1155 leftover _sendAllERC1155(params.refundTo, IERC1155(order.erc1155Token), tokenId); } // --- ERC721 / ERC1155 hooks --- // Single token offer acceptance can be done approval-less by using the // standard `safeTransferFrom` method together with specifying data for // further contract calls. An example: // `safeTransferFrom( // 0xWALLET, // 0xMODULE, // TOKEN_ID, // 0xABI_ENCODED_ROUTER_EXECUTION_CALLDATA_FOR_OFFER_ACCEPTANCE // )` function onERC721Received( address, // operator, address, // from uint256, // tokenId, bytes calldata data ) external returns (bytes4) { if (data.length > 0) { _makeCall(router, data, 0); } return this.onERC721Received.selector; } function onERC1155Received( address, // operator address, // from uint256, // tokenId uint256, // amount bytes calldata data ) external returns (bytes4) { if (data.length > 0) { _makeCall(router, data, 0); } return this.onERC1155Received.selector; } // --- Internal --- function _buyERC721Ex( IElement.NFTSellOrder calldata order, IElement.Signature calldata signature, address receiver, bool revertIfIncomplete, uint256 value ) internal { // Execute fill try EXCHANGE.buyERC721Ex{value: value}(order, signature, receiver, "") {} catch { // Revert if specified if (revertIfIncomplete) { revert UnsuccessfulFill(); } } } function _buyERC721sEx( IElement.NFTSellOrder[] calldata orders, IElement.Signature[] calldata signatures, address receiver, bool revertIfIncomplete, uint256 value ) internal { uint256 length = orders.length; address[] memory takers = new address[](length); for (uint256 i; i < length; ) { takers[i] = receiver; unchecked { ++i; } } // Execute fill try EXCHANGE.batchBuyERC721sEx{value: value}( orders, signatures, takers, new bytes[](length), revertIfIncomplete ) {} catch { // Revert if specified if (revertIfIncomplete) { revert UnsuccessfulFill(); } } } function _fillBatchSignedOrder( IElement.BatchSignedOrder calldata order, address receiver, bool revertIfIncomplete, uint256 value ) internal { IElement.Parameter memory parameter; parameter.r = order.r; parameter.s = order.s; // data1 [56 bits(startNonce) + 8 bits(v) + 32 bits(listingTime) + 160 bits(maker)] parameter.data1 = (order.startNonce << 200) | (uint256(order.v) << 192) | (order.listingTime << 160) | uint256(uint160(order.maker)); // data2 [64 bits(taker part1) + 32 bits(expiryTime) + 160 bits(erc20Token)] uint256 taker = uint256(uint160(receiver)); parameter.data2 = ((taker >> 96) << 192) | (order.expirationTime << 160) | uint256(uint160(order.erc20Token)); // data3 [96 bits(taker part2) + 160 bits(platformFeeRecipient)] parameter.data3 = (taker << 160) | uint256(uint160(order.platformFeeRecipient)); // Execute fill try EXCHANGE.fillBatchSignedERC721Order{value: value}(parameter, order.collectionsBytes) {} catch { // Revert if specified if (revertIfIncomplete) { revert UnsuccessfulFill(); } } } function _fillBatchSignedOrders( IElement.BatchSignedOrder[] calldata orders, address receiver, bool revertIfIncomplete, uint256 value ) internal { uint256 length = orders.length; uint256 taker = uint256(uint160(receiver)); IElement.Parameters[] memory parameters = new IElement.Parameters[](length); for (uint256 i; i < length; ) { IElement.BatchSignedOrder calldata order = orders[i]; IElement.Parameters memory parameter; parameter.r = order.r; parameter.s = order.s; parameter.collections = order.collectionsBytes; // data1 [56 bits(startNonce) + 8 bits(v) + 32 bits(listingTime) + 160 bits(maker)] parameter.data1 = (order.startNonce << 200) | (uint256(order.v) << 192) | (order.listingTime << 160) | uint256(uint160(order.maker)); // data2 [64 bits(taker part1) + 32 bits(expiryTime) + 160 bits(erc20Token)] parameter.data2 = ((taker >> 96) << 192) | (order.expirationTime << 160) | uint256(uint160(order.erc20Token)); // data3 [96 bits(taker part2) + 160 bits(platformFeeRecipient)] parameter.data3 = (taker << 160) | uint256(uint160(order.platformFeeRecipient)); parameters[i] = parameter; unchecked { ++i; } } // Execute fill uint256 additional2 = revertIfIncomplete ? (1 << 248) : 0; try EXCHANGE.fillBatchSignedERC721Orders{value: value}(parameters, 0, additional2) {} catch { // Revert if specified if (revertIfIncomplete) { revert UnsuccessfulFill(); } } } function _buyERC1155Ex( IElement.ERC1155SellOrder calldata order, IElement.Signature calldata signature, uint128 amount, address receiver, bool revertIfIncomplete, uint256 value ) internal { try EXCHANGE.buyERC1155Ex{value: value}(order, signature, receiver, amount, "") {} catch { // Revert if specified if (revertIfIncomplete) { revert UnsuccessfulFill(); } } } function _buyERC1155sEx( IElement.ERC1155SellOrder[] calldata orders, IElement.Signature[] calldata signatures, uint128[] calldata amounts, address receiver, bool revertIfIncomplete, uint256 value ) internal { uint256 length = orders.length; address[] memory takers = new address[](length); for (uint256 i; i < length; ) { takers[i] = receiver; unchecked { ++i; } } // Execute fill try EXCHANGE.batchBuyERC1155sEx{value: value}( orders, signatures, takers, amounts, new bytes[](length), revertIfIncomplete ) {} catch { // Revert if specified if (revertIfIncomplete) { revert UnsuccessfulFill(); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IElement { struct Signature { uint8 signatureType; uint8 v; bytes32 r; bytes32 s; } struct Property { address propertyValidator; bytes propertyData; } struct Fee { address recipient; uint256 amount; bytes feeData; } struct NFTSellOrder { address maker; address taker; uint256 expiry; uint256 nonce; IERC20 erc20Token; uint256 erc20TokenAmount; Fee[] fees; address nft; uint256 nftId; } struct NFTBuyOrder { address maker; address taker; uint256 expiry; uint256 nonce; IERC20 erc20Token; uint256 erc20TokenAmount; Fee[] fees; address nft; uint256 nftId; Property[] nftProperties; } struct ERC1155SellOrder { address maker; address taker; uint256 expiry; uint256 nonce; IERC20 erc20Token; uint256 erc20TokenAmount; Fee[] fees; address erc1155Token; uint256 erc1155TokenId; // End of fields shared with NFTOrder uint128 erc1155TokenAmount; } struct ERC1155BuyOrder { address maker; address taker; uint256 expiry; uint256 nonce; IERC20 erc20Token; uint256 erc20TokenAmount; Fee[] fees; address erc1155Token; uint256 erc1155TokenId; Property[] erc1155TokenProperties; // End of fields shared with NFTOrder uint128 erc1155TokenAmount; } struct BatchSignedOrder { address maker; uint256 listingTime; uint256 expirationTime; uint256 startNonce; address erc20Token; address platformFeeRecipient; uint8 v; bytes32 r; bytes32 s; bytes collectionsBytes; } /// @param data1 [56 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 Parameter { uint256 data1; uint256 data2; uint256 data3; bytes32 r; bytes32 s; } /// @param data1 [56 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 Parameters { uint256 data1; uint256 data2; uint256 data3; bytes32 r; bytes32 s; bytes collections; } function buyERC721Ex( NFTSellOrder calldata sellOrder, Signature calldata signature, address taker, bytes calldata takerData ) external payable; function batchBuyERC721sEx( NFTSellOrder[] calldata sellOrders, Signature[] calldata signatures, address[] calldata takers, bytes[] calldata takerDatas, bool revertIfIncomplete ) external payable returns (bool[] memory successes); function buyERC1155Ex( ERC1155SellOrder calldata sellOrder, Signature calldata signature, address taker, uint128 erc1155BuyAmount, bytes calldata takerData ) external payable; function batchBuyERC1155sEx( ERC1155SellOrder[] calldata sellOrders, Signature[] calldata signatures, address[] calldata takers, uint128[] calldata erc1155TokenAmounts, bytes[] calldata takerDatas, bool revertIfIncomplete ) external payable returns (bool[] memory successes); function sellERC721( NFTBuyOrder calldata buyOrder, Signature calldata signature, uint256 erc721TokenId, bool unwrapNativeToken, bytes calldata takerData ) external; function sellERC1155( ERC1155BuyOrder calldata buyOrder, Signature calldata signature, uint256 erc1155TokenId, uint128 erc1155SellAmount, bool unwrapNativeToken, bytes calldata takerData ) external; function fillBatchSignedERC721Order(Parameter calldata parameter, bytes calldata collections) external payable; /// @param additional1 [96 bits(withdrawETHAmount) + 160 bits(erc20Token)] /// @param additional2 [8 bits(revertIfIncomplete) + 88 bits(unused) + 160 bits(royaltyFeeRecipient)] function fillBatchSignedERC721Orders( Parameters[] calldata parameters, uint256 additional1, uint256 additional2 ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; // Adapted from: // https://github.com/boringcrypto/BoringSolidity/blob/e74c5b22a61bfbadd645e51a64aa1d33734d577a/contracts/BoringOwnable.sol contract TwoStepOwnable { // --- Fields --- address public owner; address public pendingOwner; // --- Events --- event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // --- Errors --- error InvalidParams(); error Unauthorized(); // --- Modifiers --- modifier onlyOwner() { if (msg.sender != owner) { revert Unauthorized(); } _; } // --- Constructor --- constructor(address initialOwner) { owner = initialOwner; emit OwnershipTransferred(address(0), initialOwner); } // --- Methods --- function transferOwnership(address newOwner) public onlyOwner { pendingOwner = newOwner; } function claimOwnership() public { address _pendingOwner = pendingOwner; if (msg.sender != _pendingOwner) { revert Unauthorized(); } owner = _pendingOwner; pendingOwner = address(0); emit OwnershipTransferred(owner, _pendingOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {TwoStepOwnable} from "../../misc/TwoStepOwnable.sol"; // Notes: // - includes common helpers useful for all modules abstract contract BaseModule is TwoStepOwnable, ReentrancyGuard { using SafeERC20 for IERC20; // --- Events --- event CallExecuted(address target, bytes data, uint256 value); // --- Errors --- error UnsuccessfulCall(); error UnsuccessfulPayment(); error WrongParams(); // --- Constructor --- constructor(address owner) TwoStepOwnable(owner) {} // --- Owner --- // To be able to recover anything that gets stucked by mistake in the module, // we allow the owner to perform any arbitrary call. Since the goal is to be // stateless, this should only happen in case of mistakes. In addition, this // method is also useful for withdrawing any earned trading rewards. function makeCalls( address[] calldata targets, bytes[] calldata data, uint256[] calldata values ) external payable onlyOwner nonReentrant { uint256 length = targets.length; for (uint256 i = 0; i < length; ) { _makeCall(targets[i], data[i], values[i]); emit CallExecuted(targets[i], data[i], values[i]); unchecked { ++i; } } } // --- Helpers --- function _sendETH(address to, uint256 amount) internal { if (amount > 0) { (bool success, ) = payable(to).call{value: amount}(""); if (!success) { revert UnsuccessfulPayment(); } } } function _sendERC20( address to, uint256 amount, IERC20 token ) internal { if (amount > 0) { token.safeTransfer(to, amount); } } function _makeCall( address target, bytes memory data, uint256 value ) internal { (bool success, ) = payable(target).call{value: value}(data); if (!success) { revert UnsuccessfulCall(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import {BaseModule} from "../BaseModule.sol"; // Notes: // - includes common helpers useful for all marketplace/exchange modules abstract contract BaseExchangeModule is BaseModule { using SafeERC20 for IERC20; // --- Structs --- // Every fill execution has the following parameters: // - `fillTo`: the recipient of the received items // - `refundTo`: the recipient of any refunds // - `revertIfIncomplete`: whether to revert or skip unsuccessful fills // The below `ETHListingParams` and `ERC20ListingParams` rely on the // off-chain execution encoder to ensure that the orders filled with // the passed in listing parameters exactly match (eg. order amounts // and payment tokens match). struct ETHListingParams { address fillTo; address refundTo; bool revertIfIncomplete; // The total amount of ETH to be provided when filling uint256 amount; } struct ERC20ListingParams { address fillTo; address refundTo; bool revertIfIncomplete; // The ERC20 payment token for the listings IERC20 token; // The total amount of `token` to be provided when filling uint256 amount; } struct OfferParams { address fillTo; address refundTo; bool revertIfIncomplete; } struct Fee { address recipient; uint256 amount; } // --- Fields --- address public immutable router; // --- Errors --- error UnsuccessfulFill(); // --- Constructor --- constructor(address routerAddress) { router = routerAddress; } // --- Modifiers --- modifier refundETHLeftover(address refundTo) { _; uint256 leftover = address(this).balance; if (leftover > 0) { _sendETH(refundTo, leftover); } } modifier refundERC20Leftover(address refundTo, IERC20 token) { _; uint256 leftover = token.balanceOf(address(this)); if (leftover > 0) { token.safeTransfer(refundTo, leftover); } } modifier chargeETHFees(Fee[] calldata fees, uint256 amount) { if (fees.length == 0) { _; } else { uint256 balanceBefore = address(this).balance; _; uint256 length = fees.length; if (length > 0) { uint256 balanceAfter = address(this).balance; uint256 actualPaid = balanceBefore - balanceAfter; uint256 actualFee; for (uint256 i = 0; i < length; ) { // Adjust the fee to what was actually paid actualFee = (fees[i].amount * actualPaid) / amount; if (actualFee > 0) { _sendETH(fees[i].recipient, actualFee); } unchecked { ++i; } } } } } modifier chargeERC20Fees( Fee[] calldata fees, IERC20 token, uint256 amount ) { if (fees.length == 0) { _; } else { uint256 balanceBefore = token.balanceOf(address(this)); _; uint256 length = fees.length; if (length > 0) { uint256 balanceAfter = token.balanceOf(address(this)); uint256 actualPaid = balanceBefore - balanceAfter; uint256 actualFee; for (uint256 i = 0; i < length; ) { // Adjust the fee to what was actually paid actualFee = (fees[i].amount * actualPaid) / amount; if (actualFee > 0) { token.safeTransfer(fees[i].recipient, actualFee); } unchecked { ++i; } } } } } // --- Helpers --- function _sendAllETH(address to) internal { _sendETH(to, address(this).balance); } function _sendAllERC20(address to, IERC20 token) internal { uint256 balance = token.balanceOf(address(this)); if (balance > 0) { token.safeTransfer(to, balance); } } function _sendAllERC721( address to, IERC721 token, uint256 tokenId ) internal { if (token.ownerOf(tokenId) == address(this)) { token.safeTransferFrom(address(this), to, tokenId); } } function _sendAllERC1155( address to, IERC1155 token, uint256 tokenId ) internal { uint256 balance = token.balanceOf(address(this), tokenId); if (balance > 0) { token.safeTransferFrom(address(this), to, tokenId, balance, ""); } } function _approveERC20IfNeeded( IERC20 token, address spender, uint256 amount ) internal { uint256 allowance = token.allowance(address(this), spender); if (allowance < amount) { token.approve(spender, amount - allowance); } } function _approveERC721IfNeeded(IERC721 token, address operator) internal { bool isApproved = token.isApprovedForAll(address(this), operator); if (!isApproved) { token.setApprovalForAll(operator, true); } } function _approveERC1155IfNeeded(IERC1155 token, address operator) internal { bool isApproved = token.isApprovedForAll(address(this), operator); if (!isApproved) { token.setApprovalForAll(operator, true); } } }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"router","type":"address"},{"internalType":"address","name":"exchange","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidParams","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnsuccessfulCall","type":"error"},{"inputs":[],"name":"UnsuccessfulFill","type":"error"},{"inputs":[],"name":"UnsuccessfulPayment","type":"error"},{"inputs":[],"name":"WrongParams","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"CallExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"EXCHANGE","outputs":[{"internalType":"contract IElement","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"erc1155Token","type":"address"},{"internalType":"uint256","name":"erc1155TokenId","type":"uint256"},{"components":[{"internalType":"address","name":"propertyValidator","type":"address"},{"internalType":"bytes","name":"propertyData","type":"bytes"}],"internalType":"struct IElement.Property[]","name":"erc1155TokenProperties","type":"tuple[]"},{"internalType":"uint128","name":"erc1155TokenAmount","type":"uint128"}],"internalType":"struct IElement.ERC1155BuyOrder","name":"order","type":"tuple"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature","name":"signature","type":"tuple"},{"internalType":"uint128","name":"amount","type":"uint128"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"}],"internalType":"struct BaseExchangeModule.OfferParams","name":"params","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC1155Offer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"erc1155Token","type":"address"},{"internalType":"uint256","name":"erc1155TokenId","type":"uint256"},{"internalType":"uint128","name":"erc1155TokenAmount","type":"uint128"}],"internalType":"struct IElement.ERC1155SellOrder","name":"order","type":"tuple"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature","name":"signature","type":"tuple"},{"internalType":"uint128","name":"amount","type":"uint128"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ERC20ListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC20ListingERC1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"internalType":"struct IElement.NFTSellOrder","name":"order","type":"tuple"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature","name":"signature","type":"tuple"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ERC20ListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC20ListingERC721","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"uint256","name":"listingTime","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"},{"internalType":"uint256","name":"startNonce","type":"uint256"},{"internalType":"address","name":"erc20Token","type":"address"},{"internalType":"address","name":"platformFeeRecipient","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"collectionsBytes","type":"bytes"}],"internalType":"struct IElement.BatchSignedOrder","name":"order","type":"tuple"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ERC20ListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC20ListingERC721V2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"erc1155Token","type":"address"},{"internalType":"uint256","name":"erc1155TokenId","type":"uint256"},{"internalType":"uint128","name":"erc1155TokenAmount","type":"uint128"}],"internalType":"struct IElement.ERC1155SellOrder[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"uint128[]","name":"amounts","type":"uint128[]"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ERC20ListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC20ListingsERC1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"internalType":"struct IElement.NFTSellOrder[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature[]","name":"signatures","type":"tuple[]"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ERC20ListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC20ListingsERC721","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"uint256","name":"listingTime","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"},{"internalType":"uint256","name":"startNonce","type":"uint256"},{"internalType":"address","name":"erc20Token","type":"address"},{"internalType":"address","name":"platformFeeRecipient","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"collectionsBytes","type":"bytes"}],"internalType":"struct IElement.BatchSignedOrder[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ERC20ListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC20ListingsERC721V2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"},{"components":[{"internalType":"address","name":"propertyValidator","type":"address"},{"internalType":"bytes","name":"propertyData","type":"bytes"}],"internalType":"struct IElement.Property[]","name":"nftProperties","type":"tuple[]"}],"internalType":"struct IElement.NFTBuyOrder","name":"order","type":"tuple"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature","name":"signature","type":"tuple"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"}],"internalType":"struct BaseExchangeModule.OfferParams","name":"params","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptERC721Offer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"erc1155Token","type":"address"},{"internalType":"uint256","name":"erc1155TokenId","type":"uint256"},{"internalType":"uint128","name":"erc1155TokenAmount","type":"uint128"}],"internalType":"struct IElement.ERC1155SellOrder","name":"order","type":"tuple"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature","name":"signature","type":"tuple"},{"internalType":"uint128","name":"amount","type":"uint128"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ETHListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptETHListingERC1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"internalType":"struct IElement.NFTSellOrder","name":"order","type":"tuple"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature","name":"signature","type":"tuple"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ETHListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptETHListingERC721","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"uint256","name":"listingTime","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"},{"internalType":"uint256","name":"startNonce","type":"uint256"},{"internalType":"address","name":"erc20Token","type":"address"},{"internalType":"address","name":"platformFeeRecipient","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"collectionsBytes","type":"bytes"}],"internalType":"struct IElement.BatchSignedOrder","name":"order","type":"tuple"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ETHListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptETHListingERC721V2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"erc1155Token","type":"address"},{"internalType":"uint256","name":"erc1155TokenId","type":"uint256"},{"internalType":"uint128","name":"erc1155TokenAmount","type":"uint128"}],"internalType":"struct IElement.ERC1155SellOrder[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature[]","name":"signatures","type":"tuple[]"},{"internalType":"uint128[]","name":"amounts","type":"uint128[]"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ETHListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptETHListingsERC1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"contract IERC20","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"erc20TokenAmount","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"feeData","type":"bytes"}],"internalType":"struct IElement.Fee[]","name":"fees","type":"tuple[]"},{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"internalType":"struct IElement.NFTSellOrder[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"uint8","name":"signatureType","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct IElement.Signature[]","name":"signatures","type":"tuple[]"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ETHListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptETHListingsERC721","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"internalType":"uint256","name":"listingTime","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"},{"internalType":"uint256","name":"startNonce","type":"uint256"},{"internalType":"address","name":"erc20Token","type":"address"},{"internalType":"address","name":"platformFeeRecipient","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"collectionsBytes","type":"bytes"}],"internalType":"struct IElement.BatchSignedOrder[]","name":"orders","type":"tuple[]"},{"components":[{"internalType":"address","name":"fillTo","type":"address"},{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"bool","name":"revertIfIncomplete","type":"bool"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.ETHListingParams","name":"params","type":"tuple"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BaseExchangeModule.Fee[]","name":"fees","type":"tuple[]"}],"name":"acceptETHListingsERC721V2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"makeCalls","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c0346200017557601f6200453938819003918201601f19168301916001600160401b038311848410176200017a5780849260609460405283398101031262000175576200004d8162000190565b620000696040620000616020850162000190565b930162000190565b600080546001600160a01b0319166001600160a01b03938416908117825560405194917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a360016002556080521660a0526143939081620001a68239608051818181610139015261022d015260a05181818161035c0152818161046d0152818161066e0152818161076b015281816109be01528181610a8001528181610ab101528181610c2501528181611042015281816114ee015281816116010152818161319d01528181613245015281816135a4015281816136ff0152818161388d015281816139f701528181613b3a01528181613de401528181614051015281816140fb01526142700152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001755756fe6080604052600436101561001b575b361561001957600080fd5b005b6000803560e01c80630b2fe65f1461235657806312f3a43f146121e657806314fbb77014612002578063150b7a0214611f91578063187d827714611e8257806319e1f78b14611d7e5780631f0daeac14611b7957806343b4488414611a8457806346696836146119915780634dfcbc141461179a5780634e71e0c8146117355780635bfb5a57146114585780635d4cbf23146113495780635db7784214610fa95780638c4bb0aa14610e4f5780638da5cb5b14610e285780639565923e146109ed578063b50e44b8146109a8578063c459633014610285578063e30c39781461025c578063f23a6e61146101c1578063f2fde38b1461016b5763f887ea4014610124575061000e565b346101685780600319360112610168576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b5034610168576020366003190112610168576101856125ff565b81546001600160a01b039190821633036101b057166001600160601b0360a01b600154161760015580f35b6040516282b42960e81b8152600490fd5b50346101685760a0366003190112610168576101db6125ff565b506101e4612615565b506084356001600160401b0381116102585761020490369060040161263f565b8061021c575b60405163f23a6e6160e01b8152602090f35b6102519161022b913691612837565b7f0000000000000000000000000000000000000000000000000000000000000000612913565b808061020a565b5080fd5b50346101685780600319360112610168576001546040516001600160a01b039091168152602090f35b50610120366003190112610168576001600160401b036004358181116109a4576102b390369060040161256f565b906024358381116109a0576102cc90369060040161259f565b91909260443585811161099c576102e790369060040161256f565b9560a036606319011261099857610104359081116109985761030d9036906004016125cf565b95909661031861288f565b610320612740565b96610329612714565b98610332612714565b8261061b57505050929461034894929194612714565b6001600160a01b0394906103839060e435907f0000000000000000000000000000000000000000000000000000000000000000881690612c6f565b61038b6126bc565b6103936129e0565b9761039d816132e9565b91871660005b8281106105f55750506103b58161332f565b93604051988997633311d28160e11b89528360c48a0160c060048c01525260e489019060e48560051b8b010194819260005b8281106105a45750505050509161040e9161042094936003198a84030160248b01526133fa565b86810360031901604488015290613462565b848103600319016064860152818152602090810193919060005b8281106105735750505050600083610461829694829460031984830301608485015261349f565b88151560a483015203927f0000000000000000000000000000000000000000000000000000000000000000165af19081610550575b5061054a57610538575b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa91821561052d5784926104f5575b50816104e4575b83600160025580f35b6104ed92612a5c565b3880806104db565b9091506020813d8211610525575b81610510602093836127fb565b81010312610520575190386104d4565b600080fd5b3d9150610503565b6040513d86823e3d90fd5b604051631298f31b60e11b8152600490fd5b506104a0565b61056c903d806000833e61056481836127fb565b810190613379565b5038610496565b91939483965090806001926001600160801b036105908397612682565b16815201960191019187959493919261043a565b91939798999a9b60e397919395969719908203018352873561013e198636030181121561052057600191866105d99201613f8a565b97602080910193019101908d9b9a9998979695949293916103e7565b808261060b60019387989996979d9a9b9d61331b565b52019896959894939291946103a3565b9594919793909692604051956370a0823160e01b875230600488015260208760248160018060a01b038c165afa96871561098d578d97610959575b5094929061069c610668959395612714565b60e435907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690612c6f565b6106a46126bc565b6106ac6129e0565b966106b6816132e9565b9160005b82811061092b5750506106cc8161332f565b95604051978896633311d28160e11b88528360c4890160c060048b01525260e4880160e48560051b8a010194826000905b8282106108de575050505050610726926020949261040e926003198a84030160248b01526133fa565b84810360031901606486015282815201919060005b8181106108b05750505061075e829160009460031984830301608485015261349f565b85151560a48301520381837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081610895575b5061088f57610538575b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa90811561088457889161084e575b6107e4925061293d565b92865b8181106107f85750505050506104a0565b60019061081e60e43561081988602061081286898c612960565b0135612970565b612983565b8061082b575b50016107e7565b6108489061084261083d84878a612960565b612756565b86612a5c565b38610824565b90506020823d60201161087c575b81610869602093836127fb565b81010312610520576107e49151906107da565b3d915061085c565b6040513d8a823e3d90fd5b506107a6565b6108a9903d806000833e61056481836127fb565b503861079c565b91949350916020806001926001600160801b036108cc89612682565b1681520195019101918593949261073b565b91939798999b9a509193949560e3198d8203018552873561013e198336030181121561052057602061091560019385839401613f8a565b9901950192018c9a9b99989796959493916106fd565b600190818060a09b999b9a959697989a1b038316610949828861331b565b52019795979694939291966106ba565b9096506020813d602011610985575b81610975602093836127fb565b8101031261052057519538610656565b3d9150610968565b6040513d8f823e3d90fd5b8780fd5b8680fd5b8480fd5b8280fd5b50346101685780600319360112610168576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346101685761014060031981813601126109a4576001600160401b03918260043511610e2457808260043536030112610e24576080366023190112610e245760603660a3190112610e24578361010491823594610124359081116109a457610a5a9036906004016125cf565b929093610a6561288f565b610aaf6001600160a01b03610a7e60043560e401612756565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169116613027565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163b1561025857610bee90610b9c6040519463a880948560e01b8652610100600487015260018060a01b03610b1160043560040161262b565b16868401526001600160a01b03610b2c60043560240161262b565b16610124870152600435604481013561014488015260648101356101648801526001600160a01b0390610b619060840161262b565b1661018487015260a460043501356101a4870152610b8960c460043501600435600401612d88565b90916101c4880152610244870191612ded565b906001600160a01b03610bb360043560e40161262b565b166101e48601526004350135610204850152610bda61012460043501600435600401612d88565b858303610103190161022487015290612e8e565b610bfa60248401612f34565b8660a48401528160c484015282810395860160e4840152528580826020809701818360018060a01b037f0000000000000000000000000000000000000000000000000000000000000000165af19182610e0c575b5050610d85575050610c5e6129d1565b6105385782915b610c6d612714565b906001600160a01b03610c8460043560e401612756565b16926040516331a9108f60e11b81528260048201528181602481885afa918215610d7a578692610d3c575b50506001600160a01b03163014610cc95783600160025580f35b823b15610d3757604051632142170760e11b81523060048201526001600160a01b03909216602483015260448201529082908290606490829084905af18015610d2c57610d18575b80806104db565b610d21906127b7565b610168578038610d11565b6040513d84823e3d90fd5b505050fd5b90809250813d8311610d73575b610d5381836127fb565b810103126109a057516001600160a01b03811681036109a0573880610caf565b503d610d49565b6040513d88823e3d90fd5b929392835b818110610dba575050508192610db5610da161272a565b610daf608460043501612756565b90612fa9565b610c65565b80610dd0610dcb6001938587612960565b612f69565b85838060a01b03825116910151610deb608460043501612756565b9181610dfb575b50505001610d8a565b610e0492612a5c565b388080610df2565b610e15906127b7565b610e20578538610c4e565b8580fd5b8380fd5b5034610168578060031936011261016857546040516001600160a01b039091168152602090f35b50610100366003190112610168576001600160401b036004358181116109a457610e7d90369060040161256f565b90916024358181116109a057610e9790369060040161259f565b93909260443583811161099c57610eb290369060040161256f565b909360803660631901126109985760e43590811161099857610ed89036906004016125cf565b949096610ee361288f565b610eeb612740565b9760c4359680610f32575050610f1296610f036126bc565b94610f0c6129e0565b96614199565b4780610f22575b82600160025580f35b610f2b916129ef565b3880610f19565b959096979394610f5395610f4c948a944797610f036126bc565b479061293d565b92855b828110610f67575050505050610f12565b80610f7f836108198860206108126001978a8c612960565b80610f8c575b5001610f56565b610fa390610f9e61083d84888a612960565b6129ef565b38610f85565b50346101685761016060031981813601126109a457600435906001600160401b03928383116109a057808284360301126109a05760803660231901126109a057610ff161266c565b9260603660c3190112610e205761014494853590811161099c576110199036906004016125cf565b61102161288f565b60e48301966001600160a01b039489908661103b8b612756565b16611069887f0000000000000000000000000000000000000000000000000000000000000000168092613027565b803b156109a4578288978c60405196879563496c5a5560e01b875260048701610120905283600401928c8061109d8661262b565b169261012493848b015281602488016110b59061262b565b16858b015260448701356101648b015260648701356101848b0152608487019e8f6110df9061262b565b166101a48b015260a48701356101c48b01526110fe60c4880187612d88565b90916101e48c01526102848b019061111592612ded565b9161111f9061262b565b1661020489015261010493848601356102248a015282860161114091612d88565b89830361012319016102448b01526111589291612e8e565b936001600160801b039283910161116e90612682565b1661026488015261118160248801612f34565b359d8e60a48801521660c48601528260e48601528482039b8c01908501525281836020809b01925af19081611336575b506112c8575050506111c16129c1565b6105385784935b816111da6111d46126fe565b92612756565b604051627eeac760e11b815230600482015260248101879052911691908481604481865afa9485156112bd57879561128a575b50508361121e575b85600160025580f35b813b15610e20578560c49281956040519788968795637921219560e11b87523060048801521660248601526044850152606484015260a060848401528160a48401525af18015610d2c57611276575b80808080611215565b61127f906127b7565b61016857803861126d565b819750809295503d83116112b6575b6112a381836127fb565b810103126105205785945192388061120d565b503d611299565b6040513d89823e3d90fd5b91969591865b8181106112f3575050506112ee8596610daf6112e8612714565b91612756565b6111c8565b80611304610dcb6001938587612960565b87878251169101516113158c612756565b9181611325575b505050016112ce565b61132e92612a5c565b38808061131c565b611342909991996127b7565b97386111b1565b5060e0366003190112610168576001600160401b036004358181116109a45761137690369060040161256f565b906024358381116109a05761138f90369060040161259f565b9190936080604319360112610e205760c435908111610e20576113b69036906004016125cf565b9390926113c161288f565b6113c96126bc565b9560a43594866113f05750610f1295506113e16126d2565b926113ea6129a3565b9461366c565b9480969461140794610f4c939447956113e16126d2565b92855b82811061141b575050505050610f12565b80611433836108198860206108126001978a8c612960565b80611440575b500161140a565b61145290610f9e61083d84888a612960565b38611439565b5060e0366003190112610168576001600160401b036004358181116109a45761148590369060040161256f565b909160a0366023190112610e245760c435908111610e24576114ab9036906004016125cf565b9190926114b661288f565b6114be6126d2565b926114c7612740565b946114d0612740565b60a43592806115a8575050509161151c611533936114ec612740565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690612c6f565b6115246126e8565b9061152d6129b2565b92613abe565b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa91821561052d5784926115755750816104e45783600160025580f35b9091506020813d82116115a0575b81611590602093836127fb565b81010312610e24575190386104d4565b3d9150611583565b919360018060a09593951b0380851691604051906370a0823160e01b908183523060048401526020998d8b856024818a5afa958615611728578c958992976116e9575b5061162793929161151c916115fe612740565b907f00000000000000000000000000000000000000000000000000000000000000001690612c6f565b60246040518095819382523060048301525afa9081156116de578a916116a9575b611652925061293d565b885b8381106116675750505050505050611533565b8061167e84610819858b6108126001978b8e612960565b8061168b575b5001611654565b6116a39061169d61083d84898c612960565b88612a5c565b38611684565b90508682813d83116116d7575b6116c081836127fb565b810103126116d357611652915190611648565b8980fd5b503d6116b6565b6040513d8c823e3d90fd5b939295849197508092503d8311611721575b61170581836127fb565b8101031261171d579051938a939087906116276115eb565b8d80fd5b503d6116fb565b50604051903d90823e3d90fd5b50346101685780600319360112610168576001546001600160a01b03811690338290036101b05782546001600160a01b03199081168317845516600155807f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b506003196101603682011261025857600435906001600160401b0390818311610e2457610120908360040193360301126109a45760803660231901126109a45760a03660a31901126109a457610144359081116109a4576117ff9036906004016125cf565b909161180961288f565b611811612714565b9161181a612a45565b93611823612a45565b6101243592806118565750505090611840611533926114ec612a45565b61184861272a565b6118506129d1565b9161323a565b90919260018060a01b03808416906040516370a0823160e01b8082523060048301526020988c8a84602481895afa948515611728578b94889296611954575b506118a79291611840916115fe612a45565b60246040518095819382523060048301525afa9081156116de578a91611923575b6118d2925061293d565b885b8381106118e75750505050505050611533565b806118fe84610819858b6108126001978b8e612960565b8061190b575b50016118d4565b61191d9061169d61083d84898c612960565b38611904565b90508682813d831161194d575b61193a81836127fb565b810103126116d3576118d29151906118c8565b503d611930565b9294839196508092503d831161198a575b61196f81836127fb565b8101031261198657519289929086906118a7611895565b8c80fd5b503d611965565b5060c0366003190112610168576001600160401b036004358181116109a4576119be90369060040161256f565b916080366023190112610e245760a435908111610e24576119e39036906004016125cf565b9190926119ee61288f565b6119f66126d2565b936084359380611a1f57505090610f129291611a106126e8565b90611a196129b2565b92613d6a565b91610f4c85611a3393954793611a106126e8565b92855b828110611a47575050505050610f12565b80611a5f836108198860206108126001978a8c612960565b80611a6c575b5001611a36565b611a7e90610f9e61083d84888a612960565b38611a65565b5060031960c03682011261025857600435906001600160401b0390818311610e2457610140908360040193360301126109a45760803660231901126109a45760a4359081116109a457611adb9036906004016125cf565b9091611ae561288f565b611aed6126d2565b926084359280611b1457505090610f1291611b066126e8565b611b0e6129b2565b91613922565b9091611b2890610f4c854792611b066126e8565b92855b828110611b3c575050505050610f12565b80611b54836108198860206108126001978a8c612960565b80611b61575b5001611b2b565b611b7390610f9e61083d84888a612960565b38611b5a565b506003196101803682011261025857600435906001600160401b0390818311610e2457610140908360040193360301126109a45760803660231901126109a457611bc161266c565b9060a03660c3190112610e245761016435908111610e2457611be79036906004016125cf565b919092611bf261288f565b611bfa6126fe565b92611c03612a2e565b94611c0c612a2e565b610144359280611c405750505091611c29611533936114ec612a2e565b611c31612714565b90611c3a6129c1565b926140ee565b919360018060a09593951b0380851691604051906370a0823160e01b908183523060048401526020998d8b856024818a5afa958615611728578c95899297611d43575b50611c96939291611c29916115fe612a2e565b60246040518095819382523060048301525afa9081156116de578a91611d12575b611cc1925061293d565b885b838110611cd65750505050505050611533565b80611ced84610819858b6108126001978b8e612960565b80611cfa575b5001611cc3565b611d0c9061169d61083d84898c612960565b38611cf3565b90508682813d8311611d3c575b611d2981836127fb565b810103126116d357611cc1915190611cb7565b503d611d1f565b939295849197508092503d8311611d77575b611d5f81836127fb565b8101031261171d579051938a93908790611c96611c83565b503d611d55565b506003196101403682011261025857600435906001600160401b0390818311610e2457610120908360040193360301126109a45760803660231901126109a45760803660a31901126109a457610124359081116109a457611de39036906004016125cf565b9091611ded61288f565b611df5612714565b92610104359280611e1d57505090610f1291611e0f61272a565b611e176129d1565b9161318d565b9091611e3190610f4c854792611e0f61272a565b92855b828110611e45575050505050610f12565b80611e5d836108198860206108126001978a8c612960565b80611e6a575b5001611e34565b611e7c90610f9e61083d84888a612960565b38611e63565b5060031961016036820112610258576004356001600160401b0391828211610e2457610140908260040192360301126109a45760803660231901126109a457611ec961266c565b9160803660c3190112610e245761014435908111610e2457611eef9036906004016125cf565b919092611efa61288f565b611f026126fe565b93610124359380611f2c57505090610f129291611f1d612714565b90611f266129c1565b92614041565b91610f4c85611f4093954793611f1d612714565b92855b828110611f54575050505050610f12565b80611f6c836108198860206108126001978a8c612960565b80611f79575b5001611f43565b611f8b90610f9e61083d84888a612960565b38611f72565b503461016857608036600319011261016857611fab6125ff565b50611fb4612615565b506064356001600160401b03811161025857611fd490369060040161263f565b80611fec575b604051630a85bd0160e11b8152602090f35b611ffb9161022b913691612837565b8080611fda565b5060031960e03682011261025857600435906001600160401b0390818311610e2457610140908360040193360301126109a45760a03660231901126109a45760c4359081116109a4576120599036906004016125cf565b909161206361288f565b61206b6126d2565b91612074612740565b9361207d612740565b60a43592806120af5750505090612099611533926114ec612740565b6120a16126e8565b6120a96129b2565b916137be565b90919260018060a01b03808416906040516370a0823160e01b8082523060048301526020988c8a84602481895afa948515611728578b948892966121ad575b506121009291612099916115fe612740565b60246040518095819382523060048301525afa9081156116de578a9161217c575b61212b925061293d565b885b8381106121405750505050505050611533565b8061215784610819858b6108126001978b8e612960565b80612164575b500161212d565b6121769061169d61083d84898c612960565b3861215d565b90508682813d83116121a6575b61219381836127fb565b810103126116d35761212b915190612121565b503d612189565b9294839196508092503d83116121df575b6121c881836127fb565b8101031261198657519289929086906121006120ee565b503d6121be565b50606080600319360112610258576001600160401b0390600435828111610e245761221590369060040161256f565b9092602435818111610e205761222f90369060040161256f565b9160443590811161099c5761224890369060040161256f565b87546001600160a01b0394929190851633036101b05761226661288f565b885b8681106122785789600160025580f35b61228661083d82898c612696565b908a806122ad61229784898b61279c565b91906122a486898b612696565b35923691612837565b948551918b602080980192165af16122c36128e3565b5015612344577fa3f06cf374cf66be06f5fe85cdd3b13d9d9fdef6482f640d2de1d44c3ed7332c8787600194612335888f8f8f61231f8a8f818f969161231161083d83899861231796612696565b9b61279c565b959096612696565b359560405198899816885287015285019161286e565b9060408301520390a101612268565b6040516322092f2f60e11b8152600490fd5b50610100366003190112610168576001600160401b036004358181116109a45761238490369060040161256f565b90916024358181116109a05761239e90369060040161259f565b93909160a0366043190112610e205760e435908111610e20576123c59036906004016125cf565b9390946123d061288f565b6123d86126bc565b946123e161272a565b966123ea61272a565b60c435928a8161241f575050505093612408611533956114ec61272a565b6124106126d2565b926124196129a3565b946134f4565b9094919560018060a09995991b039283881694604051926370a0823160e01b9283855230600486015260209c8d866024818c5afa968715612563578e968b9198612525575b5061240890612478969798996115fe61272a565b60246040518095819382523060048301525afa9081156116de578a916124f4575b6124a3925061293d565b885b8381106124b85750505050505050611533565b806124cf84610819858b6108126001978b8e612960565b806124dc575b50016124a5565b6124ee9061169d61083d84898c612960565b386124d5565b90508682813d831161251e575b61250b81836127fb565b810103126116d3576124a3915190612499565b503d612501565b9596809298508691503d831161255c575b61254081836127fb565b81010312612558579251948c94939089612408612464565b8f80fd5b503d612536565b604051903d90823e3d90fd5b9181601f84011215610520578235916001600160401b038311610520576020808501948460051b01011161052057565b9181601f84011215610520578235916001600160401b038311610520576020808501948460071b01011161052057565b9181601f84011215610520578235916001600160401b038311610520576020808501948460061b01011161052057565b600435906001600160a01b038216820361052057565b602435906001600160a01b038216820361052057565b35906001600160a01b038216820361052057565b9181601f84011215610520578235916001600160401b038311610520576020838186019501011161052057565b60a435906001600160801b038216820361052057565b35906001600160801b038216820361052057565b91908110156126a65760051b0190565b634e487b7160e01b600052603260045260246000fd5b6064356001600160a01b03811681036105205790565b6044356001600160a01b03811681036105205790565b6024356001600160a01b03811681036105205790565b60e4356001600160a01b03811681036105205790565b60c4356001600160a01b03811681036105205790565b60a4356001600160a01b03811681036105205790565b6084356001600160a01b03811681036105205790565b356001600160a01b03811681036105205790565b903590601e198136030182121561052057018035906001600160401b0382116105205760200191813603831361052057565b908210156126a6576127b39160051b81019061276a565b9091565b6001600160401b0381116127ca57604052565b634e487b7160e01b600052604160045260246000fd5b60a081019081106001600160401b038211176127ca57604052565b90601f801991011681019081106001600160401b038211176127ca57604052565b6001600160401b0381116127ca57601f01601f191660200190565b9291926128438261281c565b9161285160405193846127fb565b829481845281830111610520578281602093846000960137010152565b908060209392818452848401376000828201840152601f01601f1916010190565b600280541461289e5760028055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b3d1561290e573d906128f48261281c565b9161290260405193846127fb565b82523d6000602084013e565b606090565b8151600092839260209091019083906001600160a01b03165af16129356128e3565b501561234457565b9190820391821161294a57565b634e487b7160e01b600052601160045260246000fd5b91908110156126a65760061b0190565b8181029291811591840414171561294a57565b811561298d570490565b634e487b7160e01b600052601260045260246000fd5b60843580151581036105205790565b60643580151581036105205790565b6101043580151581036105205790565b60e43580151581036105205790565b60a43580151581036105205790565b816129f8575050565b6000918291829182916001600160a01b03165af1612a146128e3565b5015612a1c57565b60405163d2dcf4f360e01b8152600490fd5b610124356001600160a01b03811681036105205790565b610104356001600160a01b03811681036105205790565b60405163a9059cbb60e01b60208083019182526001600160a01b0394909416602483015260448083019590955293815291929190612a9b6064836127fb565b60018060a01b031660405191604083018381106001600160401b038211176127ca576040528483527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648386015251612b0493600091829182855af1612afe6128e3565b91612b92565b805180612b1057505050565b818391810103126105205781612b269101612b85565b15612b2e5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b5190811515820361052057565b91929015612bf45750815115612ba6575090565b3b15612baf5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612c075750805190602001fd5b60405162461bcd60e51b815260206004820152908190612c2b906024830190612c2f565b0390fd5b919082519283825260005b848110612c5b575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201612c3a565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526020939192168383604481845afa928315612d4d57600093612d59575b50848310612cbf575b5050505050565b612ccd8493612d029661293d565b60405163095ea7b360e01b81526001600160a01b03909316600484015260248301529093849190829060009082906044820190565b03925af18015612d4d57612d19575b808080612cb8565b81813d8311612d46575b612d2d81836127fb565b8101031261052057612d3e90612b85565b503880612d11565b503d612d23565b6040513d6000823e3d90fd5b90928482813d8311612d81575b612d7081836127fb565b810103126101685750519138612caf565b503d612d66565b9035601e19823603018112156105205701602081359101916001600160401b038211610520578160051b3603831361052057565b9035601e19823603018112156105205701602081359101916001600160401b03821161052057813603831361052057565b9080835260208093019081938160051b83019484600080925b858410612e1857505050505050505090565b909192939495969781810388528835605e1985360301811215610e245760019187918291612e7e9188016001600160a01b03612e538261262b565b1682528381013584830152612e6d60409182810190612dbc565b91909260608092820152019161286e565b9a01980196959401929190612e06565b909182815260208091019283918160051b85019484600080925b858410612eba57505050505050505090565b909192939495969781810388528835603e1985360301811215610e245760019187918291612f1691612f059089016001600160a01b03612ef98261262b565b16835284810190612dbc565b90916040908186820152019161286e565b9a01980196959401929190612ea8565b359060ff8216820361052057565b60243560ff811680910361052057815260443560ff811680910361052057602082015260643560408201526060608435910152565b604081360312610520576040519060408201908282106001600160401b038311176127ca57602091604052612f9d8161262b565b83520135602082015290565b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa918215612d4d57600092612ff4575b5081612fe957505050565b612ff292612a5c565b565b90916020823d821161301f575b8161300e602093836127fb565b810103126101685750519038612fde565b3d9150613001565b60405163e985e9c560e01b81523060048201526001600160a01b038381166024830152918216929190602081604481875afa908115612d4d576000916130b8575b501561307357505050565b823b1561052057604460009283604051958694859363a22cb46560e01b8552166004840152600160248401525af18015612d4d576130af575b50565b612ff2906127b7565b906020823d82116130e9575b816130d1602093836127fb565b8101031261016857506130e390612b85565b38613068565b3d91506130c4565b6001600160a01b039190826131058261262b565b168252826131156020830161262b565b16602083015260408101356040830152606081013560608301528261313c6080830161262b565b16608083015260a081013560a083015261316d61315c60c0830183612d88565b6101208060c0870152850191612ded565b9261317a60e0830161262b565b1660e08301526101008091013591015290565b91926001600160a01b03929091907f0000000000000000000000000000000000000000000000000000000000000000841690813b156105205760009360206131f294604051978896879563b18d619f60e01b875260e0600488015260e48701906130f1565b916131ff60248701612f34565b1660a48501528684820391600319830160c48701525201925af1908161322b575b506130ac5761053857565b613234906127b7565b38613220565b6001600160a01b03917f00000000000000000000000000000000000000000000000000000000000000008316803b156105205760009283602061329a94604051978896879563b18d619f60e01b875260e0600488015260e48701906130f1565b916132a760248701612f34565b1660a48501528284820391600319830160c48701525201925af1908161322b57506130ac5761053857565b6001600160401b0381116127ca5760051b60200190565b906132f3826132d2565b61330060405191826127fb565b8281528092613311601f19916132d2565b0190602036910137565b80518210156126a65760209160051b010190565b90613339826132d2565b61334660405191826127fb565b8281528092613357601f19916132d2565b019060005b82811061336857505050565b80606060208093850101520161335c565b6020908181840312610520578051906001600160401b03821161052057019180601f840112156105205782516133ae816132d2565b936133bc60405195866127fb565b818552838086019260051b820101928311610520578301905b8282106133e3575050505090565b8380916133ef84612b85565b8152019101906133d5565b9190808252602080920192916000905b828210613418575050505090565b9091929360019060ff8061342b88612f26565b168252613439848801612f26565b16818401526040868101359082015260608087013590820152608090810195019392019061340a565b90815180825260208080930193019160005b828110613482575050505090565b83516001600160a01b031685529381019392810192600101613474565b90815180825260208092019182818360051b82019501936000915b8483106134ca5750505050505090565b90919293949584806134e483856001950387528a51612c2f565b98019301930191949392906134ba565b919293613500826132e9565b9060005b8381106136445750506135168261332f565b9160405195869463053c23f160e01b86528260a4870160a060048901525260c486019060c48460051b88010193819260005b8281106135fa575050505050926135886135979361357860009894889760031996878a84030160248b01526133fa565b9084878303016044880152613462565b9184830301606485015261349f565b85151560848301520381837f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190816135df57506130ac5761053857565b6135f3903d806000833e61056481836127fb565b5038613220565b91939697985091939460c3198b8203018352863561011e1986360301811215610520576001918661362b92016130f1565b96602080910193019101908a9897969594929391613548565b8061365660019285969599979961331b565b828060a01b038416905201959395929192613504565b92949593613679826132e9565b9060005b83811061378657505061368f8261332f565b9160405196879563053c23f160e01b87528260a4880160a060048a01525260c487019060c48460051b89010193819260005b82811061373a57505050505093859361358885946135786136f39560009b9960031996878a84030160248b01526133fa565b871515608483015203917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190816135df57506130ac5761053857565b9193969798995091939460c3198c8203018352863561011e1986360301811215610520576001918661376c92016130f1565b96602080910193019101908b9998979695949293916136c1565b806137996001928596959a97989a61331b565b828060a01b0384169052019694939692919261367d565b3560ff811681036105205790565b6040516137ca816127e0565b60009182825260208201838152604083019284845260608101956138b9608083019160e08601358952610100860135835260ff60c01b61380c60c088016137b0565b6001600160a01b03929160c09190911b168261382789612756565b1690602089013560a01b9060608a013560c81b17171785528161384c60808901612756565b16604088013560a01b6001600160401b0360c01b8360601b16171786528161387660a08901612756565b16906001600160601b0360a01b9060a01b161787527f0000000000000000000000000000000000000000000000000000000000000000169461012081019061276a565b9091853b15610998579161390d918894936040519a8b998a98899763a4d7304160e01b895251600489015251602488015251604487015251606486015251608485015260c060a485015260c484019161286e565b03925af1908161322b57506130ac5761053857565b9290919260405190613933826127e0565b600092838352602083019084825260408401938585526060810196613a23608083019160e08701358a52610100870135835260ff60c01b61397660c089016137b0565b6001600160a01b03929160c09190911b16826139918a612756565b169060208a013560a01b9060608b013560c81b1717178552816139b660808a01612756565b16604089013560a01b6001600160401b0360c01b8360601b1617178752816139e060a08a01612756565b16906001600160601b0360a01b9060a01b161788527f0000000000000000000000000000000000000000000000000000000000000000169561012081019061276a565b9091863b15613a75579061390d92916040519a8b998a98899763a4d7304160e01b895251600489015251602488015251604487015251606486015251608485015260c060a485015260c484019161286e565b8880fd5b6040519060c082018281106001600160401b038211176127ca57604052606060a083600081526000602082015260006040820152600083820152600060808201520152565b929190613aca816132d2565b91604094613ada865194856127fb565b828452601f19613ae9846132d2565b0160005b818110613d53575060609360a09390915080851b6001600160c01b03191690841b6001600160a01b03191660005b838110613c75575050505050600084600014613c705750600160f81b5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692833b1561052057908694929451948593630a4dc67360e11b855260648501908460048701528051809252608486019460848360051b880101956020809301946000925b8d868510613c035750505050505050506000838195938193836024840152604483015203925af19081613bf4575b50613bf057613be05750565b51631298f31b60e11b8152600490fd5b5050565b613bfd906127b7565b38613bd4565b94613c5b839597999a600194839a9d988e8596989a608319908503018b525190815184528582015186850152808201519084015287810151888401526080808201519084015201519060c09081898201520190612c2f565b9a0194019401918a9897969491959395613ba6565b613b38565b8060051b8501359061013e19863603018212156105205760019186018b613d3089613c9e613a79565b9360e08101358d8601528c60809461010083013586880152613cce613cc761012085018561276a565b3691612837565b8785015260ff60c01b60c0613ce48582016137b0565b901b1691613d1c8a8060a01b0397889283613cfe88612756565b1690602096878901358a1b9189013560c81b1717178a528501612756565b1690830135841b8b17179086015201612756565b1684178c820152613d41828b61331b565b52613d4c818a61331b565b5001613b1b565b602090613d5e613a79565b82828901015201613aed565b93613d74826132d2565b92604095613d84875195866127fb565b838552601f19613d93856132d2565b0160005b818110613f73575060609460a09390915080861b6001600160c01b03191690841b6001600160a01b03191660005b838110613efd575050505050600085600014613ef85750600160f81b5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031693843b1561052057949291908751958694630a4dc67360e11b8652606486019082600488015280518092528a6084880160848460051b8a0101966020809401956000935b868510613e885750505050505050509183809260009694876024840152604483015203925af19081613bf45750613bf057613be05750565b94613ee1839597999a600194839a9d9e988e8596989a608319908503018b525190815184528582015186850152808201519084015287810151888401526080808201519084015201519060c09081898201520190612c2f565b9a0194019401918b9998979694918e969496613e50565b613de2565b8060051b8501359061013e19863603018212156105205760019186018c613f5089613f26613a79565b938d60e0820135908601528d60809461010083013586880152613cce613cc761012085018561276a565b1684178d820152613f61828c61331b565b52613f6c818b61331b565b5001613dc5565b602090613f7e613a79565b82828a01015201613d97565b6001600160a01b03919082613f9e8261262b565b16825282613fae6020830161262b565b166020830152604081013560408301526060810135606083015282613fd56080830161262b565b16608083015260a081013560a0830152614006613ff560c0830183612d88565b6101408060c0870152850191612ded565b9261401360e0830161262b565b1660e083015261010080820135908301526001600160801b0361403a610120809301612682565b1691015290565b92936001600160a01b03939192917f0000000000000000000000000000000000000000000000000000000000000000851691823b156105205760206140b0946001600160801b03600097604051998a98899763744773f160e01b895261010060048a0152610104890190613f8a565b936140bd60248901612f34565b1660a48701521660c48501528684820391600319830160e48701525201925af1908161322b57506130ac5761053857565b6001600160a01b039291907f0000000000000000000000000000000000000000000000000000000000000000841690813b15610520576000602081956001600160801b0361415b96604051998a98899763744773f160e01b895261010060048a0152610104890190613f8a565b9361416860248901612f34565b1660a48701521660c48501528284820391600319830160e48701525201925af1908161322b57506130ac5761053857565b9490929697956141a8846132e9565b9060005b85811061432f5750506141be8461332f565b93604051988997633311d28160e11b89528260c48a0160c060048c01525260e489019060e48460051b8b010193819260005b8281106142de57505050505061422892916142189160031996878b84030160248c01526133fa565b9084888303016044890152613462565b90828683030160648701528082526020809201949160005b8281106142ab5750505050614264838593849384600099970301608485015261349f565b87151560a483015203917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190816135df57506130ac5761053857565b9193949583975090806001926001600160801b036142c98397612682565b16815201970191019188969594939192614240565b9193969798999a9b60e3969193959619908203018352863561013e198636030181121561052057600191866143139201613f8a565b96602080910193019101908d9b9a9998979695949293916141f0565b8061434460019285969798959c999a9c61331b565b828060a01b0384169052019896959894939291946141ac56fea2646970667358221220576a4908b025eac6da2a146e2332b4261ddcb58e9825278954f7532e014f2dc864736f6c63430008110033000000000000000000000000f3d63166f0ca56c3c1a3508fce03ff0cf3fb691e000000000000000000000000c2c862322e9c97d6244a3506655da95f05246fd800000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4
Deployed Bytecode
0x6080604052600436101561001b575b361561001957600080fd5b005b6000803560e01c80630b2fe65f1461235657806312f3a43f146121e657806314fbb77014612002578063150b7a0214611f91578063187d827714611e8257806319e1f78b14611d7e5780631f0daeac14611b7957806343b4488414611a8457806346696836146119915780634dfcbc141461179a5780634e71e0c8146117355780635bfb5a57146114585780635d4cbf23146113495780635db7784214610fa95780638c4bb0aa14610e4f5780638da5cb5b14610e285780639565923e146109ed578063b50e44b8146109a8578063c459633014610285578063e30c39781461025c578063f23a6e61146101c1578063f2fde38b1461016b5763f887ea4014610124575061000e565b346101685780600319360112610168576040517f000000000000000000000000c2c862322e9c97d6244a3506655da95f05246fd86001600160a01b03168152602090f35b80fd5b5034610168576020366003190112610168576101856125ff565b81546001600160a01b039190821633036101b057166001600160601b0360a01b600154161760015580f35b6040516282b42960e81b8152600490fd5b50346101685760a0366003190112610168576101db6125ff565b506101e4612615565b506084356001600160401b0381116102585761020490369060040161263f565b8061021c575b60405163f23a6e6160e01b8152602090f35b6102519161022b913691612837565b7f000000000000000000000000c2c862322e9c97d6244a3506655da95f05246fd8612913565b808061020a565b5080fd5b50346101685780600319360112610168576001546040516001600160a01b039091168152602090f35b50610120366003190112610168576001600160401b036004358181116109a4576102b390369060040161256f565b906024358381116109a0576102cc90369060040161259f565b91909260443585811161099c576102e790369060040161256f565b9560a036606319011261099857610104359081116109985761030d9036906004016125cf565b95909661031861288f565b610320612740565b96610329612714565b98610332612714565b8261061b57505050929461034894929194612714565b6001600160a01b0394906103839060e435907f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4881690612c6f565b61038b6126bc565b6103936129e0565b9761039d816132e9565b91871660005b8281106105f55750506103b58161332f565b93604051988997633311d28160e11b89528360c48a0160c060048c01525260e489019060e48560051b8b010194819260005b8281106105a45750505050509161040e9161042094936003198a84030160248b01526133fa565b86810360031901604488015290613462565b848103600319016064860152818152602090810193919060005b8281106105735750505050600083610461829694829460031984830301608485015261349f565b88151560a483015203927f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4165af19081610550575b5061054a57610538575b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa91821561052d5784926104f5575b50816104e4575b83600160025580f35b6104ed92612a5c565b3880806104db565b9091506020813d8211610525575b81610510602093836127fb565b81010312610520575190386104d4565b600080fd5b3d9150610503565b6040513d86823e3d90fd5b604051631298f31b60e11b8152600490fd5b506104a0565b61056c903d806000833e61056481836127fb565b810190613379565b5038610496565b91939483965090806001926001600160801b036105908397612682565b16815201960191019187959493919261043a565b91939798999a9b60e397919395969719908203018352873561013e198636030181121561052057600191866105d99201613f8a565b97602080910193019101908d9b9a9998979695949293916103e7565b808261060b60019387989996979d9a9b9d61331b565b52019896959894939291946103a3565b9594919793909692604051956370a0823160e01b875230600488015260208760248160018060a01b038c165afa96871561098d578d97610959575b5094929061069c610668959395612714565b60e435907f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b031690612c6f565b6106a46126bc565b6106ac6129e0565b966106b6816132e9565b9160005b82811061092b5750506106cc8161332f565b95604051978896633311d28160e11b88528360c4890160c060048b01525260e4880160e48560051b8a010194826000905b8282106108de575050505050610726926020949261040e926003198a84030160248b01526133fa565b84810360031901606486015282815201919060005b8181106108b05750505061075e829160009460031984830301608485015261349f565b85151560a48301520381837f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b03165af19081610895575b5061088f57610538575b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa90811561088457889161084e575b6107e4925061293d565b92865b8181106107f85750505050506104a0565b60019061081e60e43561081988602061081286898c612960565b0135612970565b612983565b8061082b575b50016107e7565b6108489061084261083d84878a612960565b612756565b86612a5c565b38610824565b90506020823d60201161087c575b81610869602093836127fb565b81010312610520576107e49151906107da565b3d915061085c565b6040513d8a823e3d90fd5b506107a6565b6108a9903d806000833e61056481836127fb565b503861079c565b91949350916020806001926001600160801b036108cc89612682565b1681520195019101918593949261073b565b91939798999b9a509193949560e3198d8203018552873561013e198336030181121561052057602061091560019385839401613f8a565b9901950192018c9a9b99989796959493916106fd565b600190818060a09b999b9a959697989a1b038316610949828861331b565b52019795979694939291966106ba565b9096506020813d602011610985575b81610975602093836127fb565b8101031261052057519538610656565b3d9150610968565b6040513d8f823e3d90fd5b8780fd5b8680fd5b8480fd5b8280fd5b50346101685780600319360112610168576040517f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b03168152602090f35b50346101685761014060031981813601126109a4576001600160401b03918260043511610e2457808260043536030112610e24576080366023190112610e245760603660a3190112610e24578361010491823594610124359081116109a457610a5a9036906004016125cf565b929093610a6561288f565b610aaf6001600160a01b03610a7e60043560e401612756565b7f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b03169116613027565b7f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b03163b1561025857610bee90610b9c6040519463a880948560e01b8652610100600487015260018060a01b03610b1160043560040161262b565b16868401526001600160a01b03610b2c60043560240161262b565b16610124870152600435604481013561014488015260648101356101648801526001600160a01b0390610b619060840161262b565b1661018487015260a460043501356101a4870152610b8960c460043501600435600401612d88565b90916101c4880152610244870191612ded565b906001600160a01b03610bb360043560e40161262b565b166101e48601526004350135610204850152610bda61012460043501600435600401612d88565b858303610103190161022487015290612e8e565b610bfa60248401612f34565b8660a48401528160c484015282810395860160e4840152528580826020809701818360018060a01b037f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4165af19182610e0c575b5050610d85575050610c5e6129d1565b6105385782915b610c6d612714565b906001600160a01b03610c8460043560e401612756565b16926040516331a9108f60e11b81528260048201528181602481885afa918215610d7a578692610d3c575b50506001600160a01b03163014610cc95783600160025580f35b823b15610d3757604051632142170760e11b81523060048201526001600160a01b03909216602483015260448201529082908290606490829084905af18015610d2c57610d18575b80806104db565b610d21906127b7565b610168578038610d11565b6040513d84823e3d90fd5b505050fd5b90809250813d8311610d73575b610d5381836127fb565b810103126109a057516001600160a01b03811681036109a0573880610caf565b503d610d49565b6040513d88823e3d90fd5b929392835b818110610dba575050508192610db5610da161272a565b610daf608460043501612756565b90612fa9565b610c65565b80610dd0610dcb6001938587612960565b612f69565b85838060a01b03825116910151610deb608460043501612756565b9181610dfb575b50505001610d8a565b610e0492612a5c565b388080610df2565b610e15906127b7565b610e20578538610c4e565b8580fd5b8380fd5b5034610168578060031936011261016857546040516001600160a01b039091168152602090f35b50610100366003190112610168576001600160401b036004358181116109a457610e7d90369060040161256f565b90916024358181116109a057610e9790369060040161259f565b93909260443583811161099c57610eb290369060040161256f565b909360803660631901126109985760e43590811161099857610ed89036906004016125cf565b949096610ee361288f565b610eeb612740565b9760c4359680610f32575050610f1296610f036126bc565b94610f0c6129e0565b96614199565b4780610f22575b82600160025580f35b610f2b916129ef565b3880610f19565b959096979394610f5395610f4c948a944797610f036126bc565b479061293d565b92855b828110610f67575050505050610f12565b80610f7f836108198860206108126001978a8c612960565b80610f8c575b5001610f56565b610fa390610f9e61083d84888a612960565b6129ef565b38610f85565b50346101685761016060031981813601126109a457600435906001600160401b03928383116109a057808284360301126109a05760803660231901126109a057610ff161266c565b9260603660c3190112610e205761014494853590811161099c576110199036906004016125cf565b61102161288f565b60e48301966001600160a01b039489908661103b8b612756565b16611069887f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4168092613027565b803b156109a4578288978c60405196879563496c5a5560e01b875260048701610120905283600401928c8061109d8661262b565b169261012493848b015281602488016110b59061262b565b16858b015260448701356101648b015260648701356101848b0152608487019e8f6110df9061262b565b166101a48b015260a48701356101c48b01526110fe60c4880187612d88565b90916101e48c01526102848b019061111592612ded565b9161111f9061262b565b1661020489015261010493848601356102248a015282860161114091612d88565b89830361012319016102448b01526111589291612e8e565b936001600160801b039283910161116e90612682565b1661026488015261118160248801612f34565b359d8e60a48801521660c48601528260e48601528482039b8c01908501525281836020809b01925af19081611336575b506112c8575050506111c16129c1565b6105385784935b816111da6111d46126fe565b92612756565b604051627eeac760e11b815230600482015260248101879052911691908481604481865afa9485156112bd57879561128a575b50508361121e575b85600160025580f35b813b15610e20578560c49281956040519788968795637921219560e11b87523060048801521660248601526044850152606484015260a060848401528160a48401525af18015610d2c57611276575b80808080611215565b61127f906127b7565b61016857803861126d565b819750809295503d83116112b6575b6112a381836127fb565b810103126105205785945192388061120d565b503d611299565b6040513d89823e3d90fd5b91969591865b8181106112f3575050506112ee8596610daf6112e8612714565b91612756565b6111c8565b80611304610dcb6001938587612960565b87878251169101516113158c612756565b9181611325575b505050016112ce565b61132e92612a5c565b38808061131c565b611342909991996127b7565b97386111b1565b5060e0366003190112610168576001600160401b036004358181116109a45761137690369060040161256f565b906024358381116109a05761138f90369060040161259f565b9190936080604319360112610e205760c435908111610e20576113b69036906004016125cf565b9390926113c161288f565b6113c96126bc565b9560a43594866113f05750610f1295506113e16126d2565b926113ea6129a3565b9461366c565b9480969461140794610f4c939447956113e16126d2565b92855b82811061141b575050505050610f12565b80611433836108198860206108126001978a8c612960565b80611440575b500161140a565b61145290610f9e61083d84888a612960565b38611439565b5060e0366003190112610168576001600160401b036004358181116109a45761148590369060040161256f565b909160a0366023190112610e245760c435908111610e24576114ab9036906004016125cf565b9190926114b661288f565b6114be6126d2565b926114c7612740565b946114d0612740565b60a43592806115a8575050509161151c611533936114ec612740565b7f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b031690612c6f565b6115246126e8565b9061152d6129b2565b92613abe565b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa91821561052d5784926115755750816104e45783600160025580f35b9091506020813d82116115a0575b81611590602093836127fb565b81010312610e24575190386104d4565b3d9150611583565b919360018060a09593951b0380851691604051906370a0823160e01b908183523060048401526020998d8b856024818a5afa958615611728578c958992976116e9575b5061162793929161151c916115fe612740565b907f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c41690612c6f565b60246040518095819382523060048301525afa9081156116de578a916116a9575b611652925061293d565b885b8381106116675750505050505050611533565b8061167e84610819858b6108126001978b8e612960565b8061168b575b5001611654565b6116a39061169d61083d84898c612960565b88612a5c565b38611684565b90508682813d83116116d7575b6116c081836127fb565b810103126116d357611652915190611648565b8980fd5b503d6116b6565b6040513d8c823e3d90fd5b939295849197508092503d8311611721575b61170581836127fb565b8101031261171d579051938a939087906116276115eb565b8d80fd5b503d6116fb565b50604051903d90823e3d90fd5b50346101685780600319360112610168576001546001600160a01b03811690338290036101b05782546001600160a01b03199081168317845516600155807f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b506003196101603682011261025857600435906001600160401b0390818311610e2457610120908360040193360301126109a45760803660231901126109a45760a03660a31901126109a457610144359081116109a4576117ff9036906004016125cf565b909161180961288f565b611811612714565b9161181a612a45565b93611823612a45565b6101243592806118565750505090611840611533926114ec612a45565b61184861272a565b6118506129d1565b9161323a565b90919260018060a01b03808416906040516370a0823160e01b8082523060048301526020988c8a84602481895afa948515611728578b94889296611954575b506118a79291611840916115fe612a45565b60246040518095819382523060048301525afa9081156116de578a91611923575b6118d2925061293d565b885b8381106118e75750505050505050611533565b806118fe84610819858b6108126001978b8e612960565b8061190b575b50016118d4565b61191d9061169d61083d84898c612960565b38611904565b90508682813d831161194d575b61193a81836127fb565b810103126116d3576118d29151906118c8565b503d611930565b9294839196508092503d831161198a575b61196f81836127fb565b8101031261198657519289929086906118a7611895565b8c80fd5b503d611965565b5060c0366003190112610168576001600160401b036004358181116109a4576119be90369060040161256f565b916080366023190112610e245760a435908111610e24576119e39036906004016125cf565b9190926119ee61288f565b6119f66126d2565b936084359380611a1f57505090610f129291611a106126e8565b90611a196129b2565b92613d6a565b91610f4c85611a3393954793611a106126e8565b92855b828110611a47575050505050610f12565b80611a5f836108198860206108126001978a8c612960565b80611a6c575b5001611a36565b611a7e90610f9e61083d84888a612960565b38611a65565b5060031960c03682011261025857600435906001600160401b0390818311610e2457610140908360040193360301126109a45760803660231901126109a45760a4359081116109a457611adb9036906004016125cf565b9091611ae561288f565b611aed6126d2565b926084359280611b1457505090610f1291611b066126e8565b611b0e6129b2565b91613922565b9091611b2890610f4c854792611b066126e8565b92855b828110611b3c575050505050610f12565b80611b54836108198860206108126001978a8c612960565b80611b61575b5001611b2b565b611b7390610f9e61083d84888a612960565b38611b5a565b506003196101803682011261025857600435906001600160401b0390818311610e2457610140908360040193360301126109a45760803660231901126109a457611bc161266c565b9060a03660c3190112610e245761016435908111610e2457611be79036906004016125cf565b919092611bf261288f565b611bfa6126fe565b92611c03612a2e565b94611c0c612a2e565b610144359280611c405750505091611c29611533936114ec612a2e565b611c31612714565b90611c3a6129c1565b926140ee565b919360018060a09593951b0380851691604051906370a0823160e01b908183523060048401526020998d8b856024818a5afa958615611728578c95899297611d43575b50611c96939291611c29916115fe612a2e565b60246040518095819382523060048301525afa9081156116de578a91611d12575b611cc1925061293d565b885b838110611cd65750505050505050611533565b80611ced84610819858b6108126001978b8e612960565b80611cfa575b5001611cc3565b611d0c9061169d61083d84898c612960565b38611cf3565b90508682813d8311611d3c575b611d2981836127fb565b810103126116d357611cc1915190611cb7565b503d611d1f565b939295849197508092503d8311611d77575b611d5f81836127fb565b8101031261171d579051938a93908790611c96611c83565b503d611d55565b506003196101403682011261025857600435906001600160401b0390818311610e2457610120908360040193360301126109a45760803660231901126109a45760803660a31901126109a457610124359081116109a457611de39036906004016125cf565b9091611ded61288f565b611df5612714565b92610104359280611e1d57505090610f1291611e0f61272a565b611e176129d1565b9161318d565b9091611e3190610f4c854792611e0f61272a565b92855b828110611e45575050505050610f12565b80611e5d836108198860206108126001978a8c612960565b80611e6a575b5001611e34565b611e7c90610f9e61083d84888a612960565b38611e63565b5060031961016036820112610258576004356001600160401b0391828211610e2457610140908260040192360301126109a45760803660231901126109a457611ec961266c565b9160803660c3190112610e245761014435908111610e2457611eef9036906004016125cf565b919092611efa61288f565b611f026126fe565b93610124359380611f2c57505090610f129291611f1d612714565b90611f266129c1565b92614041565b91610f4c85611f4093954793611f1d612714565b92855b828110611f54575050505050610f12565b80611f6c836108198860206108126001978a8c612960565b80611f79575b5001611f43565b611f8b90610f9e61083d84888a612960565b38611f72565b503461016857608036600319011261016857611fab6125ff565b50611fb4612615565b506064356001600160401b03811161025857611fd490369060040161263f565b80611fec575b604051630a85bd0160e11b8152602090f35b611ffb9161022b913691612837565b8080611fda565b5060031960e03682011261025857600435906001600160401b0390818311610e2457610140908360040193360301126109a45760a03660231901126109a45760c4359081116109a4576120599036906004016125cf565b909161206361288f565b61206b6126d2565b91612074612740565b9361207d612740565b60a43592806120af5750505090612099611533926114ec612740565b6120a16126e8565b6120a96129b2565b916137be565b90919260018060a01b03808416906040516370a0823160e01b8082523060048301526020988c8a84602481895afa948515611728578b948892966121ad575b506121009291612099916115fe612740565b60246040518095819382523060048301525afa9081156116de578a9161217c575b61212b925061293d565b885b8381106121405750505050505050611533565b8061215784610819858b6108126001978b8e612960565b80612164575b500161212d565b6121769061169d61083d84898c612960565b3861215d565b90508682813d83116121a6575b61219381836127fb565b810103126116d35761212b915190612121565b503d612189565b9294839196508092503d83116121df575b6121c881836127fb565b8101031261198657519289929086906121006120ee565b503d6121be565b50606080600319360112610258576001600160401b0390600435828111610e245761221590369060040161256f565b9092602435818111610e205761222f90369060040161256f565b9160443590811161099c5761224890369060040161256f565b87546001600160a01b0394929190851633036101b05761226661288f565b885b8681106122785789600160025580f35b61228661083d82898c612696565b908a806122ad61229784898b61279c565b91906122a486898b612696565b35923691612837565b948551918b602080980192165af16122c36128e3565b5015612344577fa3f06cf374cf66be06f5fe85cdd3b13d9d9fdef6482f640d2de1d44c3ed7332c8787600194612335888f8f8f61231f8a8f818f969161231161083d83899861231796612696565b9b61279c565b959096612696565b359560405198899816885287015285019161286e565b9060408301520390a101612268565b6040516322092f2f60e11b8152600490fd5b50610100366003190112610168576001600160401b036004358181116109a45761238490369060040161256f565b90916024358181116109a05761239e90369060040161259f565b93909160a0366043190112610e205760e435908111610e20576123c59036906004016125cf565b9390946123d061288f565b6123d86126bc565b946123e161272a565b966123ea61272a565b60c435928a8161241f575050505093612408611533956114ec61272a565b6124106126d2565b926124196129a3565b946134f4565b9094919560018060a09995991b039283881694604051926370a0823160e01b9283855230600486015260209c8d866024818c5afa968715612563578e968b9198612525575b5061240890612478969798996115fe61272a565b60246040518095819382523060048301525afa9081156116de578a916124f4575b6124a3925061293d565b885b8381106124b85750505050505050611533565b806124cf84610819858b6108126001978b8e612960565b806124dc575b50016124a5565b6124ee9061169d61083d84898c612960565b386124d5565b90508682813d831161251e575b61250b81836127fb565b810103126116d3576124a3915190612499565b503d612501565b9596809298508691503d831161255c575b61254081836127fb565b81010312612558579251948c94939089612408612464565b8f80fd5b503d612536565b604051903d90823e3d90fd5b9181601f84011215610520578235916001600160401b038311610520576020808501948460051b01011161052057565b9181601f84011215610520578235916001600160401b038311610520576020808501948460071b01011161052057565b9181601f84011215610520578235916001600160401b038311610520576020808501948460061b01011161052057565b600435906001600160a01b038216820361052057565b602435906001600160a01b038216820361052057565b35906001600160a01b038216820361052057565b9181601f84011215610520578235916001600160401b038311610520576020838186019501011161052057565b60a435906001600160801b038216820361052057565b35906001600160801b038216820361052057565b91908110156126a65760051b0190565b634e487b7160e01b600052603260045260246000fd5b6064356001600160a01b03811681036105205790565b6044356001600160a01b03811681036105205790565b6024356001600160a01b03811681036105205790565b60e4356001600160a01b03811681036105205790565b60c4356001600160a01b03811681036105205790565b60a4356001600160a01b03811681036105205790565b6084356001600160a01b03811681036105205790565b356001600160a01b03811681036105205790565b903590601e198136030182121561052057018035906001600160401b0382116105205760200191813603831361052057565b908210156126a6576127b39160051b81019061276a565b9091565b6001600160401b0381116127ca57604052565b634e487b7160e01b600052604160045260246000fd5b60a081019081106001600160401b038211176127ca57604052565b90601f801991011681019081106001600160401b038211176127ca57604052565b6001600160401b0381116127ca57601f01601f191660200190565b9291926128438261281c565b9161285160405193846127fb565b829481845281830111610520578281602093846000960137010152565b908060209392818452848401376000828201840152601f01601f1916010190565b600280541461289e5760028055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b3d1561290e573d906128f48261281c565b9161290260405193846127fb565b82523d6000602084013e565b606090565b8151600092839260209091019083906001600160a01b03165af16129356128e3565b501561234457565b9190820391821161294a57565b634e487b7160e01b600052601160045260246000fd5b91908110156126a65760061b0190565b8181029291811591840414171561294a57565b811561298d570490565b634e487b7160e01b600052601260045260246000fd5b60843580151581036105205790565b60643580151581036105205790565b6101043580151581036105205790565b60e43580151581036105205790565b60a43580151581036105205790565b816129f8575050565b6000918291829182916001600160a01b03165af1612a146128e3565b5015612a1c57565b60405163d2dcf4f360e01b8152600490fd5b610124356001600160a01b03811681036105205790565b610104356001600160a01b03811681036105205790565b60405163a9059cbb60e01b60208083019182526001600160a01b0394909416602483015260448083019590955293815291929190612a9b6064836127fb565b60018060a01b031660405191604083018381106001600160401b038211176127ca576040528483527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648386015251612b0493600091829182855af1612afe6128e3565b91612b92565b805180612b1057505050565b818391810103126105205781612b269101612b85565b15612b2e5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b5190811515820361052057565b91929015612bf45750815115612ba6575090565b3b15612baf5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612c075750805190602001fd5b60405162461bcd60e51b815260206004820152908190612c2b906024830190612c2f565b0390fd5b919082519283825260005b848110612c5b575050826000602080949584010152601f8019910116010190565b602081830181015184830182015201612c3a565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526020939192168383604481845afa928315612d4d57600093612d59575b50848310612cbf575b5050505050565b612ccd8493612d029661293d565b60405163095ea7b360e01b81526001600160a01b03909316600484015260248301529093849190829060009082906044820190565b03925af18015612d4d57612d19575b808080612cb8565b81813d8311612d46575b612d2d81836127fb565b8101031261052057612d3e90612b85565b503880612d11565b503d612d23565b6040513d6000823e3d90fd5b90928482813d8311612d81575b612d7081836127fb565b810103126101685750519138612caf565b503d612d66565b9035601e19823603018112156105205701602081359101916001600160401b038211610520578160051b3603831361052057565b9035601e19823603018112156105205701602081359101916001600160401b03821161052057813603831361052057565b9080835260208093019081938160051b83019484600080925b858410612e1857505050505050505090565b909192939495969781810388528835605e1985360301811215610e245760019187918291612e7e9188016001600160a01b03612e538261262b565b1682528381013584830152612e6d60409182810190612dbc565b91909260608092820152019161286e565b9a01980196959401929190612e06565b909182815260208091019283918160051b85019484600080925b858410612eba57505050505050505090565b909192939495969781810388528835603e1985360301811215610e245760019187918291612f1691612f059089016001600160a01b03612ef98261262b565b16835284810190612dbc565b90916040908186820152019161286e565b9a01980196959401929190612ea8565b359060ff8216820361052057565b60243560ff811680910361052057815260443560ff811680910361052057602082015260643560408201526060608435910152565b604081360312610520576040519060408201908282106001600160401b038311176127ca57602091604052612f9d8161262b565b83520135602082015290565b6040516370a0823160e01b8152306004820152906020826024816001600160a01b0387165afa918215612d4d57600092612ff4575b5081612fe957505050565b612ff292612a5c565b565b90916020823d821161301f575b8161300e602093836127fb565b810103126101685750519038612fde565b3d9150613001565b60405163e985e9c560e01b81523060048201526001600160a01b038381166024830152918216929190602081604481875afa908115612d4d576000916130b8575b501561307357505050565b823b1561052057604460009283604051958694859363a22cb46560e01b8552166004840152600160248401525af18015612d4d576130af575b50565b612ff2906127b7565b906020823d82116130e9575b816130d1602093836127fb565b8101031261016857506130e390612b85565b38613068565b3d91506130c4565b6001600160a01b039190826131058261262b565b168252826131156020830161262b565b16602083015260408101356040830152606081013560608301528261313c6080830161262b565b16608083015260a081013560a083015261316d61315c60c0830183612d88565b6101208060c0870152850191612ded565b9261317a60e0830161262b565b1660e08301526101008091013591015290565b91926001600160a01b03929091907f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4841690813b156105205760009360206131f294604051978896879563b18d619f60e01b875260e0600488015260e48701906130f1565b916131ff60248701612f34565b1660a48501528684820391600319830160c48701525201925af1908161322b575b506130ac5761053857565b613234906127b7565b38613220565b6001600160a01b03917f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c48316803b156105205760009283602061329a94604051978896879563b18d619f60e01b875260e0600488015260e48701906130f1565b916132a760248701612f34565b1660a48501528284820391600319830160c48701525201925af1908161322b57506130ac5761053857565b6001600160401b0381116127ca5760051b60200190565b906132f3826132d2565b61330060405191826127fb565b8281528092613311601f19916132d2565b0190602036910137565b80518210156126a65760209160051b010190565b90613339826132d2565b61334660405191826127fb565b8281528092613357601f19916132d2565b019060005b82811061336857505050565b80606060208093850101520161335c565b6020908181840312610520578051906001600160401b03821161052057019180601f840112156105205782516133ae816132d2565b936133bc60405195866127fb565b818552838086019260051b820101928311610520578301905b8282106133e3575050505090565b8380916133ef84612b85565b8152019101906133d5565b9190808252602080920192916000905b828210613418575050505090565b9091929360019060ff8061342b88612f26565b168252613439848801612f26565b16818401526040868101359082015260608087013590820152608090810195019392019061340a565b90815180825260208080930193019160005b828110613482575050505090565b83516001600160a01b031685529381019392810192600101613474565b90815180825260208092019182818360051b82019501936000915b8483106134ca5750505050505090565b90919293949584806134e483856001950387528a51612c2f565b98019301930191949392906134ba565b919293613500826132e9565b9060005b8381106136445750506135168261332f565b9160405195869463053c23f160e01b86528260a4870160a060048901525260c486019060c48460051b88010193819260005b8281106135fa575050505050926135886135979361357860009894889760031996878a84030160248b01526133fa565b9084878303016044880152613462565b9184830301606485015261349f565b85151560848301520381837f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b03165af190816135df57506130ac5761053857565b6135f3903d806000833e61056481836127fb565b5038613220565b91939697985091939460c3198b8203018352863561011e1986360301811215610520576001918661362b92016130f1565b96602080910193019101908a9897969594929391613548565b8061365660019285969599979961331b565b828060a01b038416905201959395929192613504565b92949593613679826132e9565b9060005b83811061378657505061368f8261332f565b9160405196879563053c23f160e01b87528260a4880160a060048a01525260c487019060c48460051b89010193819260005b82811061373a57505050505093859361358885946135786136f39560009b9960031996878a84030160248b01526133fa565b871515608483015203917f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b03165af190816135df57506130ac5761053857565b9193969798995091939460c3198c8203018352863561011e1986360301811215610520576001918661376c92016130f1565b96602080910193019101908b9998979695949293916136c1565b806137996001928596959a97989a61331b565b828060a01b0384169052019694939692919261367d565b3560ff811681036105205790565b6040516137ca816127e0565b60009182825260208201838152604083019284845260608101956138b9608083019160e08601358952610100860135835260ff60c01b61380c60c088016137b0565b6001600160a01b03929160c09190911b168261382789612756565b1690602089013560a01b9060608a013560c81b17171785528161384c60808901612756565b16604088013560a01b6001600160401b0360c01b8360601b16171786528161387660a08901612756565b16906001600160601b0360a01b9060a01b161787527f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4169461012081019061276a565b9091853b15610998579161390d918894936040519a8b998a98899763a4d7304160e01b895251600489015251602488015251604487015251606486015251608485015260c060a485015260c484019161286e565b03925af1908161322b57506130ac5761053857565b9290919260405190613933826127e0565b600092838352602083019084825260408401938585526060810196613a23608083019160e08701358a52610100870135835260ff60c01b61397660c089016137b0565b6001600160a01b03929160c09190911b16826139918a612756565b169060208a013560a01b9060608b013560c81b1717178552816139b660808a01612756565b16604089013560a01b6001600160401b0360c01b8360601b1617178752816139e060a08a01612756565b16906001600160601b0360a01b9060a01b161788527f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4169561012081019061276a565b9091863b15613a75579061390d92916040519a8b998a98899763a4d7304160e01b895251600489015251602488015251604487015251606486015251608485015260c060a485015260c484019161286e565b8880fd5b6040519060c082018281106001600160401b038211176127ca57604052606060a083600081526000602082015260006040820152600083820152600060808201520152565b929190613aca816132d2565b91604094613ada865194856127fb565b828452601f19613ae9846132d2565b0160005b818110613d53575060609360a09390915080851b6001600160c01b03191690841b6001600160a01b03191660005b838110613c75575050505050600084600014613c705750600160f81b5b7f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b031692833b1561052057908694929451948593630a4dc67360e11b855260648501908460048701528051809252608486019460848360051b880101956020809301946000925b8d868510613c035750505050505050506000838195938193836024840152604483015203925af19081613bf4575b50613bf057613be05750565b51631298f31b60e11b8152600490fd5b5050565b613bfd906127b7565b38613bd4565b94613c5b839597999a600194839a9d988e8596989a608319908503018b525190815184528582015186850152808201519084015287810151888401526080808201519084015201519060c09081898201520190612c2f565b9a0194019401918a9897969491959395613ba6565b613b38565b8060051b8501359061013e19863603018212156105205760019186018b613d3089613c9e613a79565b9360e08101358d8601528c60809461010083013586880152613cce613cc761012085018561276a565b3691612837565b8785015260ff60c01b60c0613ce48582016137b0565b901b1691613d1c8a8060a01b0397889283613cfe88612756565b1690602096878901358a1b9189013560c81b1717178a528501612756565b1690830135841b8b17179086015201612756565b1684178c820152613d41828b61331b565b52613d4c818a61331b565b5001613b1b565b602090613d5e613a79565b82828901015201613aed565b93613d74826132d2565b92604095613d84875195866127fb565b838552601f19613d93856132d2565b0160005b818110613f73575060609460a09390915080861b6001600160c01b03191690841b6001600160a01b03191660005b838110613efd575050505050600085600014613ef85750600160f81b5b7f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b031693843b1561052057949291908751958694630a4dc67360e11b8652606486019082600488015280518092528a6084880160848460051b8a0101966020809401956000935b868510613e885750505050505050509183809260009694876024840152604483015203925af19081613bf45750613bf057613be05750565b94613ee1839597999a600194839a9d9e988e8596989a608319908503018b525190815184528582015186850152808201519084015287810151888401526080808201519084015201519060c09081898201520190612c2f565b9a0194019401918b9998979694918e969496613e50565b613de2565b8060051b8501359061013e19863603018212156105205760019186018c613f5089613f26613a79565b938d60e0820135908601528d60809461010083013586880152613cce613cc761012085018561276a565b1684178d820152613f61828c61331b565b52613f6c818b61331b565b5001613dc5565b602090613f7e613a79565b82828a01015201613d97565b6001600160a01b03919082613f9e8261262b565b16825282613fae6020830161262b565b166020830152604081013560408301526060810135606083015282613fd56080830161262b565b16608083015260a081013560a0830152614006613ff560c0830183612d88565b6101408060c0870152850191612ded565b9261401360e0830161262b565b1660e083015261010080820135908301526001600160801b0361403a610120809301612682565b1691015290565b92936001600160a01b03939192917f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4851691823b156105205760206140b0946001600160801b03600097604051998a98899763744773f160e01b895261010060048a0152610104890190613f8a565b936140bd60248901612f34565b1660a48701521660c48501528684820391600319830160e48701525201925af1908161322b57506130ac5761053857565b6001600160a01b039291907f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4841690813b15610520576000602081956001600160801b0361415b96604051998a98899763744773f160e01b895261010060048a0152610104890190613f8a565b9361416860248901612f34565b1660a48701521660c48501528284820391600319830160e48701525201925af1908161322b57506130ac5761053857565b9490929697956141a8846132e9565b9060005b85811061432f5750506141be8461332f565b93604051988997633311d28160e11b89528260c48a0160c060048c01525260e489019060e48460051b8b010193819260005b8281106142de57505050505061422892916142189160031996878b84030160248c01526133fa565b9084888303016044890152613462565b90828683030160648701528082526020809201949160005b8281106142ab5750505050614264838593849384600099970301608485015261349f565b87151560a483015203917f00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c46001600160a01b03165af190816135df57506130ac5761053857565b9193949583975090806001926001600160801b036142c98397612682565b16815201970191019188969594939192614240565b9193969798999a9b60e3969193959619908203018352863561013e198636030181121561052057600191866143139201613f8a565b96602080910193019101908d9b9a9998979695949293916141f0565b8061434460019285969798959c999a9c61331b565b828060a01b0384169052019896959894939291946141ac56fea2646970667358221220576a4908b025eac6da2a146e2332b4261ddcb58e9825278954f7532e014f2dc864736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f3d63166f0ca56c3c1a3508fce03ff0cf3fb691e000000000000000000000000c2c862322e9c97d6244a3506655da95f05246fd800000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4
-----Decoded View---------------
Arg [0] : owner (address): 0xf3d63166F0Ca56C3c1A3508FcE03Ff0Cf3Fb691e
Arg [1] : router (address): 0xC2c862322E9c97D6244a3506655DA95F05246Fd8
Arg [2] : exchange (address): 0x20F780A973856B93f63670377900C1d2a50a77c4
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000f3d63166f0ca56c3c1a3508fce03ff0cf3fb691e
Arg [1] : 000000000000000000000000c2c862322e9c97d6244a3506655da95f05246fd8
Arg [2] : 00000000000000000000000020f780a973856b93f63670377900c1d2a50a77c4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.