ETH Price: $2,031.72 (+1.91%)

Contract

0x80a0D7A6FD2A22982Ce282933b384568E5c852bF
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer Ownersh...206846542024-09-05 13:22:11551 days ago1725542531IN
0x80a0D7A6...8E5c852bF
0 ETH0.000092263.23691093
Transfer Ownersh...205976062024-08-24 9:36:35563 days ago1724492195IN
0x80a0D7A6...8E5c852bF
0 ETH0.000031131.09221972
Add Controller204456522024-08-03 4:33:35584 days ago1722659615IN
0x80a0D7A6...8E5c852bF
0 ETH0.000096391.84340552
Transfer Ownersh...203595802024-07-22 4:06:59596 days ago1721621219IN
0x80a0D7A6...8E5c852bF
0 ETH0.000173826.0983347
Add Controller203595752024-07-22 4:05:59596 days ago1721621159IN
0x80a0D7A6...8E5c852bF
0 ETH0.000309025.90947329

Latest 8 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer204588512024-08-05 0:42:47582 days ago1722818567
0x80a0D7A6...8E5c852bF
0.05597417 ETH
Transfer204588512024-08-05 0:42:47582 days ago1722818567
0x80a0D7A6...8E5c852bF
0.05597417 ETH
Transfer204588502024-08-05 0:42:35582 days ago1722818555
0x80a0D7A6...8E5c852bF
3.73295105 ETH
Transfer204588502024-08-05 0:42:35582 days ago1722818555
0x80a0D7A6...8E5c852bF
3.73295105 ETH
Transfer204053592024-07-28 13:31:11590 days ago1722173471
0x80a0D7A6...8E5c852bF
0.00206443 ETH
Transfer204053592024-07-28 13:31:11590 days ago1722173471
0x80a0D7A6...8E5c852bF
0.00206443 ETH
Transfer203894502024-07-26 8:12:23592 days ago1721981543
0x80a0D7A6...8E5c852bF
0.00624863 ETH
Transfer203894502024-07-26 8:12:23592 days ago1721981543
0x80a0D7A6...8E5c852bF
0.00624863 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChaingeOrder

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion, None license
File 1 of 1 : ChaingeOrder.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    constructor() {
        _transferOwnership(_msgSender());
    }

    function owner() public view virtual returns (address) {
        return _owner;
    }

    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(
            newOwner != address(0),
            "Ownable: new owner is the zero address"
        );
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

abstract contract Controller is Ownable {
    event ControllerAdded(address controller);
    event ControllerRemoved(address controller);
    mapping(address => bool) public controllers;
    uint8 public controllerCnt = 0;

    modifier onlyController() {
        require(isController(_msgSender()), "no controller rights");
        _;
    }

    function isController(address _controller) public view returns (bool) {
        return _controller == owner() || controllers[_controller];
    }

    function addController(address _controller) public onlyOwner {
        if (controllers[_controller] == false) {
            controllers[_controller] = true;
            controllerCnt++;
        }
        emit ControllerAdded(_controller);
    }

    function removeController(address _controller) public onlyOwner {
        if (controllers[_controller] == true) {
            controllers[_controller] = false;
            controllerCnt--;
        }
        emit ControllerRemoved(_controller);
    }
}
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);
}
interface IWETH is IERC20 {
    /**
     * @notice Emitted when Ether is deposited to get wrapper tokens.
     */
    event Deposit(address indexed dst, uint256 wad);

    /**
     * @notice Emitted when wrapper tokens is withdrawn as Ether.
     */
    event Withdrawal(address indexed src, uint256 wad);

    /**
     * @notice Deposit Ether to get wrapper tokens.
     */
    function deposit() external payable;

    /**
     * @notice Withdraw wrapped tokens as Ether.
     * @param amount Amount of wrapped tokens to withdraw.
     */
    function withdraw(uint256 amount) external;
}

library OpAddress {
    function isContract(address account) internal view returns (bool) {
        return account.code.length > 0;
    }

    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"
        );
    }

    function functionCall(
        address target,
        bytes memory data
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(
                target,
                data,
                0,
                "Address: low-level call failed"
            );
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    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"
            );
    }

    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
            );
    }

    function functionStaticCall(
        address target,
        bytes memory data
    ) internal view returns (bytes memory) {
        return
            functionStaticCall(
                target,
                data,
                "Address: low-level static call failed"
            );
    }

    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
            );
    }

    function functionDelegateCall(
        address target,
        bytes memory data
    ) internal returns (bytes memory) {
        return
            functionDelegateCall(
                target,
                data,
                "Address: low-level delegate call failed"
            );
    }

    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
            );
    }

    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);
        }
    }

    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);
        }
    }
}
library SafeERC20 {
    using OpAddress 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)
        );
    }

    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        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 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(
                token.approve.selector,
                spender,
                oldAllowance + value
            )
        );
    }

    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"
            );
            _callOptionalReturn(
                token,
                abi.encodeWithSelector(
                    token.approve.selector,
                    spender,
                    oldAllowance - value
                )
            );
        }
    }

    function forceApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        bytes memory approvalCall = abi.encodeWithSelector(
            token.approve.selector,
            spender,
            value
        );

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(
                token,
                abi.encodeWithSelector(token.approve.selector, spender, 0)
            );
            _callOptionalReturn(token, approvalCall);
        }
    }

    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        bytes memory returndata = address(token).functionCall(
            data,
            "SafeERC20: low-level call failed"
        );
        require(
            returndata.length == 0 || abi.decode(returndata, (bool)),
            "SafeERC20: ERC20 operation did not succeed"
        );
    }

    function _callOptionalReturnBool(
        IERC20 token,
        bytes memory data
    ) private returns (bool) {
        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success &&
            (returndata.length == 0 || abi.decode(returndata, (bool))) &&
            OpAddress.isContract(address(token));
    }

    /**
     * @notice Safely deposits a specified amount of Ether into the IWETH contract. Consumes less gas then regular `IWETH.deposit`.
     * @param weth The IWETH token contract.
     * @param amount The amount of Ether to deposit into the IWETH contract.
     */
    function safeDeposit(IWETH weth, uint256 amount) internal {
        if (amount > 0) {
            bytes4 selector = IWETH.deposit.selector;
            assembly ("memory-safe") {
                // solhint-disable-line no-inline-assembly
                mstore(0, selector)
                if iszero(call(gas(), weth, amount, 0, 4, 0, 0)) {
                    let ptr := mload(0x40)
                    returndatacopy(ptr, 0, returndatasize())
                    revert(ptr, returndatasize())
                }
            }
        }
    }

    /**
     * @notice Safely withdraws a specified amount of wrapped Ether from the IWETH contract. Consumes less gas then regular `IWETH.withdraw`.
     * @dev Uses inline assembly to interact with the IWETH contract.
     * @param weth The IWETH token contract.
     * @param amount The amount of wrapped Ether to withdraw from the IWETH contract.
     */
    function safeWithdraw(IWETH weth, uint256 amount) internal {
        bytes4 selector = IWETH.withdraw.selector;
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            mstore(0, selector)
            mstore(4, amount)
            if iszero(call(gas(), weth, 0, 0, 0x24, 0, 0)) {
                let ptr := mload(0x40)
                returndatacopy(ptr, 0, returndatasize())
                revert(ptr, returndatasize())
            }
        }
    }
    uint256 private constant _RAW_CALL_GAS_LIMIT = 5000;
    /**
     * @notice Safely withdraws a specified amount of wrapped Ether from the IWETH contract to a specified recipient.
     * Consumes less gas then regular `IWETH.withdraw`.
     * @param weth The IWETH token contract.
     * @param amount The amount of wrapped Ether to withdraw from the IWETH contract.
     * @param to The recipient of the withdrawn Ether.
     */
    function safeWithdrawTo(IWETH weth, uint256 amount, address to) internal {
        safeWithdraw(weth, amount);
        if (to != address(this)) {
            assembly ("memory-safe") {
                // solhint-disable-line no-inline-assembly
                if iszero(call(_RAW_CALL_GAS_LIMIT, to, amount, 0, 0, 0, 0)) {
                    let ptr := mload(0x40)
                    returndatacopy(ptr, 0, returndatasize())
                    revert(ptr, returndatasize())
                }
            }
        }
    }
}

type Address is uint256;
library AddressLib {
    uint256 private constant _LOW_160_BIT_MASK = (1 << 160) - 1;

    function get(Address a) internal pure returns (address) {
        return address(uint160(Address.unwrap(a) & _LOW_160_BIT_MASK));
    }

    function getFlag(Address a, uint256 flag) internal pure returns (bool) {
        return (Address.unwrap(a) & flag) != 0;
    }

    function getUint32(
        Address a,
        uint256 offset
    ) internal pure returns (uint32) {
        return uint32(Address.unwrap(a) >> offset);
    }

    function getUint64(
        Address a,
        uint256 offset
    ) internal pure returns (uint64) {
        return uint64(Address.unwrap(a) >> offset);
    }
}

type MakerTraits is uint256;

library MakerTraitsLib {
    // Low 200 bits are used for allowed sender, expiration, nonceOrEpoch, and series
    uint256 private constant _ALLOWED_SENDER_MASK = type(uint80).max;
    uint256 private constant _EXPIRATION_OFFSET = 80;
    uint256 private constant _EXPIRATION_MASK = type(uint40).max;
    uint256 private constant _NONCE_OR_EPOCH_OFFSET = 120;
    uint256 private constant _NONCE_OR_EPOCH_MASK = type(uint40).max;
    uint256 private constant _SERIES_OFFSET = 160;
    uint256 private constant _SERIES_MASK = type(uint40).max;

    uint256 private constant _NO_PARTIAL_FILLS_FLAG = 1 << 255;
    uint256 private constant _ALLOW_MULTIPLE_FILLS_FLAG = 1 << 254;
    uint256 private constant _PRE_INTERACTION_CALL_FLAG = 1 << 252;
    uint256 private constant _POST_INTERACTION_CALL_FLAG = 1 << 251;
    uint256 private constant _NEED_CHECK_EPOCH_MANAGER_FLAG = 1 << 250;
    uint256 private constant _HAS_EXTENSION_FLAG = 1 << 249;
    uint256 private constant _USE_PERMIT2_FLAG = 1 << 248;
    uint256 private constant _UNWRAP_WETH_FLAG = 1 << 247;

    /**
     * @notice Checks if the order has the extension flag set.
     * @dev If the `HAS_EXTENSION_FLAG` is set in the makerTraits, then the protocol expects that the order has extension(s).
     * @param makerTraits The traits of the maker.
     * @return result A boolean indicating whether the flag is set.
     */
    function hasExtension(
        MakerTraits makerTraits
    ) internal pure returns (bool) {
        return (MakerTraits.unwrap(makerTraits) & _HAS_EXTENSION_FLAG) != 0;
    }

    /**
     * @notice Checks if the maker allows a specific taker to fill the order.
     * @param makerTraits The traits of the maker.
     * @param sender The address of the taker to be checked.
     * @return result A boolean indicating whether the taker is allowed.
     */
    function isAllowedSender(
        MakerTraits makerTraits,
        address sender
    ) internal pure returns (bool) {
        uint160 allowedSender = uint160(
            MakerTraits.unwrap(makerTraits) & _ALLOWED_SENDER_MASK
        );
        return
            allowedSender == 0 ||
            allowedSender == uint160(sender) & _ALLOWED_SENDER_MASK;
    }

    /**
     * @notice Checks if the order has expired.
     * @param makerTraits The traits of the maker.
     * @return result A boolean indicating whether the order has expired.
     */
    function isExpired(MakerTraits makerTraits) internal view returns (bool) {
        uint256 expiration = (MakerTraits.unwrap(makerTraits) >>
            _EXPIRATION_OFFSET) & _EXPIRATION_MASK;
        return expiration != 0 && expiration < block.timestamp; // solhint-disable-line not-rely-on-time
    }

    /**
     * @notice Returns the nonce or epoch of the order.
     * @param makerTraits The traits of the maker.
     * @return result The nonce or epoch of the order.
     */
    function nonceOrEpoch(
        MakerTraits makerTraits
    ) internal pure returns (uint256) {
        return
            (MakerTraits.unwrap(makerTraits) >> _NONCE_OR_EPOCH_OFFSET) &
            _NONCE_OR_EPOCH_MASK;
    }

    /**
     * @notice Returns the series of the order.
     * @param makerTraits The traits of the maker.
     * @return result The series of the order.
     */
    function series(MakerTraits makerTraits) internal pure returns (uint256) {
        return
            (MakerTraits.unwrap(makerTraits) >> _SERIES_OFFSET) & _SERIES_MASK;
    }

    /**
     * @notice Determines if the order allows partial fills.
     * @dev If the _NO_PARTIAL_FILLS_FLAG is not set in the makerTraits, then the order allows partial fills.
     * @param makerTraits The traits of the maker, determining their preferences for the order.
     * @return result A boolean indicating whether the maker allows partial fills.
     */
    function allowPartialFills(
        MakerTraits makerTraits
    ) internal pure returns (bool) {
        return (MakerTraits.unwrap(makerTraits) & _NO_PARTIAL_FILLS_FLAG) == 0;
    }

    /**
     * @notice Checks if the maker needs pre-interaction call.
     * @param makerTraits The traits of the maker.
     * @return result A boolean indicating whether the maker needs a pre-interaction call.
     */
    function needPreInteractionCall(
        MakerTraits makerTraits
    ) internal pure returns (bool) {
        return
            (MakerTraits.unwrap(makerTraits) & _PRE_INTERACTION_CALL_FLAG) != 0;
    }

    /**
     * @notice Checks if the maker needs post-interaction call.
     * @param makerTraits The traits of the maker.
     * @return result A boolean indicating whether the maker needs a post-interaction call.
     */
    function needPostInteractionCall(
        MakerTraits makerTraits
    ) internal pure returns (bool) {
        return
            (MakerTraits.unwrap(makerTraits) & _POST_INTERACTION_CALL_FLAG) !=
            0;
    }

    /**
     * @notice Determines if the order allows multiple fills.
     * @dev If the _ALLOW_MULTIPLE_FILLS_FLAG is set in the makerTraits, then the maker allows multiple fills.
     * @param makerTraits The traits of the maker, determining their preferences for the order.
     * @return result A boolean indicating whether the maker allows multiple fills.
     */
    function allowMultipleFills(
        MakerTraits makerTraits
    ) internal pure returns (bool) {
        return
            (MakerTraits.unwrap(makerTraits) & _ALLOW_MULTIPLE_FILLS_FLAG) != 0;
    }

    /**
     * @notice Determines if an order should use the bit invalidator or remaining amount validator.
     * @dev The bit invalidator can be used if the order does not allow partial or multiple fills.
     * @param makerTraits The traits of the maker, determining their preferences for the order.
     * @return result A boolean indicating whether the bit invalidator should be used.
     * True if the order requires the use of the bit invalidator.
     */
    function useBitInvalidator(
        MakerTraits makerTraits
    ) internal pure returns (bool) {
        return
            !allowPartialFills(makerTraits) || !allowMultipleFills(makerTraits);
    }

    /**
     * @notice Checks if the maker needs to check the epoch.
     * @param makerTraits The traits of the maker.
     * @return result A boolean indicating whether the maker needs to check the epoch manager.
     */
    function needCheckEpochManager(
        MakerTraits makerTraits
    ) internal pure returns (bool) {
        return
            (MakerTraits.unwrap(makerTraits) &
                _NEED_CHECK_EPOCH_MANAGER_FLAG) != 0;
    }

    /**
     * @notice Checks if the maker uses permit2.
     * @param makerTraits The traits of the maker.
     * @return result A boolean indicating whether the maker uses permit2.
     */
    function usePermit2(MakerTraits makerTraits) internal pure returns (bool) {
        return MakerTraits.unwrap(makerTraits) & _USE_PERMIT2_FLAG != 0;
    }

    /**
     * @notice Checks if the maker needs to unwraps WETH.
     * @param makerTraits The traits of the maker.
     * @return result A boolean indicating whether the maker needs to unwrap WETH.
     */
    function unwrapWeth(MakerTraits makerTraits) internal pure returns (bool) {
        return MakerTraits.unwrap(makerTraits) & _UNWRAP_WETH_FLAG != 0;
    }
}

type TakerTraits is uint256;
library TakerTraitsLib {
    uint256 private constant _MAKER_AMOUNT_FLAG = 1 << 255;
    uint256 private constant _UNWRAP_WETH_FLAG = 1 << 254;
    uint256 private constant _SKIP_ORDER_PERMIT_FLAG = 1 << 253;
    uint256 private constant _USE_PERMIT2_FLAG = 1 << 252;
    uint256 private constant _ARGS_HAS_TARGET = 1 << 251;

    uint256 private constant _ARGS_EXTENSION_LENGTH_OFFSET = 224;
    uint256 private constant _ARGS_EXTENSION_LENGTH_MASK = 0xffffff;
    uint256 private constant _ARGS_INTERACTION_LENGTH_OFFSET = 200;
    uint256 private constant _ARGS_INTERACTION_LENGTH_MASK = 0xffffff;

    uint256 private constant _AMOUNT_MASK =
        0x000000000000000000ffffffffffffffffffffffffffffffffffffffffffffff;
    function argsHasTarget(
        TakerTraits takerTraits
    ) internal pure returns (bool) {
        return (TakerTraits.unwrap(takerTraits) & _ARGS_HAS_TARGET) != 0;
    }

    function argsExtensionLength(
        TakerTraits takerTraits
    ) internal pure returns (uint256) {
        return
            (TakerTraits.unwrap(takerTraits) >> _ARGS_EXTENSION_LENGTH_OFFSET) &
            _ARGS_EXTENSION_LENGTH_MASK;
    }

    function argsInteractionLength(
        TakerTraits takerTraits
    ) internal pure returns (uint256) {
        return
            (TakerTraits.unwrap(takerTraits) >>
                _ARGS_INTERACTION_LENGTH_OFFSET) &
            _ARGS_INTERACTION_LENGTH_MASK;
    }

    function isMakingAmount(
        TakerTraits takerTraits
    ) internal pure returns (bool) {
        return (TakerTraits.unwrap(takerTraits) & _MAKER_AMOUNT_FLAG) != 0;
    }

    function unwrapWeth(TakerTraits takerTraits) internal pure returns (bool) {
        return (TakerTraits.unwrap(takerTraits) & _UNWRAP_WETH_FLAG) != 0;
    }

    function skipMakerPermit(
        TakerTraits takerTraits
    ) internal pure returns (bool) {
        return (TakerTraits.unwrap(takerTraits) & _SKIP_ORDER_PERMIT_FLAG) != 0;
    }

    function usePermit2(TakerTraits takerTraits) internal pure returns (bool) {
        return (TakerTraits.unwrap(takerTraits) & _USE_PERMIT2_FLAG) != 0;
    }

    function threshold(
        TakerTraits takerTraits
    ) internal pure returns (uint256) {
        return TakerTraits.unwrap(takerTraits) & _AMOUNT_MASK;
    }
}

type Offsets is uint256;
library OffsetsLib {
    error OffsetOutOfBounds();
    function get(
        Offsets offsets,
        bytes calldata concat,
        uint256 index
    ) internal pure returns (bytes calldata result) {
        bytes4 exception = OffsetOutOfBounds.selector;
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            let bitShift := shl(5, index) // bitShift = index * 32
            let begin := and(0xffffffff, shr(bitShift, shl(32, offsets))) // begin = offsets[ bitShift : bitShift + 32 ]
            let end := and(0xffffffff, shr(bitShift, offsets)) // end   = offsets[ bitShift + 32 : bitShift + 64 ]
            result.offset := add(concat.offset, begin)
            result.length := sub(end, begin)
            if gt(end, concat.length) {
                mstore(0, exception)
                revert(0, 4)
            }
        }
    }
}

library ExtensionLib {
    using AddressLib for Address;
    using OffsetsLib for Offsets;

    enum DynamicField {
        MakerAssetSuffix,
        TakerAssetSuffix,
        MakingAmountData,
        TakingAmountData,
        Predicate,
        MakerPermit,
        PreInteractionData,
        PostInteractionData,
        CustomData
    }

    function makerAssetSuffix(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.MakerAssetSuffix);
    }
    function takerAssetSuffix(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.TakerAssetSuffix);
    }

    function makingAmountData(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.MakingAmountData);
    }

    function takingAmountData(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.TakingAmountData);
    }

    function predicate(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.Predicate);
    }

    function makerPermit(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.MakerPermit);
    }

    function preInteractionTargetAndData(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.PreInteractionData);
    }

    function postInteractionTargetAndData(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        return _get(extension, DynamicField.PostInteractionData);
    }

    function customData(
        bytes calldata extension
    ) internal pure returns (bytes calldata) {
        if (extension.length < 0x20) return msg.data[:0];
        uint256 offsets = uint256(bytes32(extension));
        unchecked {
            return extension[0x20 + (offsets >> 224):];
        }
    }

    function _get(
        bytes calldata extension,
        DynamicField field
    ) private pure returns (bytes calldata) {
        if (extension.length < 0x20) return msg.data[:0];

        Offsets offsets;
        bytes calldata concat;
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            offsets := calldataload(extension.offset)
            concat.offset := add(extension.offset, 0x20)
            concat.length := sub(extension.length, 0x20)
        }

        return offsets.get(concat, uint256(field));
    }
}

interface IOrderMixin {
    struct Order {
        uint256 salt;
        Address maker;
        Address receiver;
        Address makerAsset;
        Address takerAsset;
        uint256 makingAmount;
        uint256 takingAmount;
        MakerTraits makerTraits;
    }
}

library ECDSA {
    uint256 private constant _S_BOUNDARY =
        0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 + 1;
    uint256 private constant _COMPACT_S_MASK =
        0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
    uint256 private constant _COMPACT_V_SHIFT = 255;

    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal view returns (address signer) {
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            if lt(s, _S_BOUNDARY) {
                let ptr := mload(0x40)

                mstore(ptr, hash)
                mstore(add(ptr, 0x20), v)
                mstore(add(ptr, 0x40), r)
                mstore(add(ptr, 0x60), s)
                mstore(0, 0)
                pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))
                signer := mload(0)
            }
        }
    }

    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal view returns (address signer) {
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            let s := and(vs, _COMPACT_S_MASK)
            if lt(s, _S_BOUNDARY) {
                let ptr := mload(0x40)

                mstore(ptr, hash)
                mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs)))
                mstore(add(ptr, 0x40), r)
                mstore(add(ptr, 0x60), s)
                mstore(0, 0)
                pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))
                signer := mload(0)
            }
        }
    }

    function recover(
        bytes32 hash,
        bytes calldata signature
    ) internal view returns (address signer) {
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            let ptr := mload(0x40)

            // memory[ptr:ptr+0x80] = (hash, v, r, s)
            switch signature.length
            case 65 {
                // memory[ptr+0x20:ptr+0x80] = (v, r, s)
                mstore(
                    add(ptr, 0x20),
                    byte(0, calldataload(add(signature.offset, 0x40)))
                )
                calldatacopy(add(ptr, 0x40), signature.offset, 0x40)
            }
            case 64 {
                // memory[ptr+0x20:ptr+0x80] = (v, r, s)
                let vs := calldataload(add(signature.offset, 0x20))
                mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs)))
                calldatacopy(add(ptr, 0x40), signature.offset, 0x20)
                mstore(add(ptr, 0x60), and(vs, _COMPACT_S_MASK))
            }
            default {
                ptr := 0
            }

            if ptr {
                if lt(mload(add(ptr, 0x60)), _S_BOUNDARY) {
                    // memory[ptr:ptr+0x20] = (hash)
                    mstore(ptr, hash)

                    mstore(0, 0)
                    pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))
                    signer := mload(0)
                }
            }
        }
    }

    function toEthSignedMessageHash(
        bytes32 hash
    ) internal pure returns (bytes32 res) {
        // 32 is the length in bytes of hash, enforced by the type signature above
        // return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            mstore(
                0,
                0x19457468657265756d205369676e6564204d6573736167653a0a333200000000
            ) // "\x19Ethereum Signed Message:\n32"
            mstore(28, hash)
            res := keccak256(0, 60)
        }
    }

    function toTypedDataHash(
        bytes32 domainSeparator,
        bytes32 structHash
    ) internal pure returns (bytes32 res) {
        // return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            let ptr := mload(0x40)
            mstore(
                ptr,
                0x1901000000000000000000000000000000000000000000000000000000000000
            ) // "\x19\x01"
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            res := keccak256(ptr, 66)
        }
    }
}

library AmountCalculatorLib {
    function getMakingAmount(
        uint256 orderMakerAmount,
        uint256 orderTakerAmount,
        uint256 swapTakerAmount
    ) internal pure returns (uint256) {
        if ((swapTakerAmount | orderMakerAmount) >> 128 == 0) {
            unchecked {
                return (swapTakerAmount * orderMakerAmount) / orderTakerAmount;
            }
        }
        return (swapTakerAmount * orderMakerAmount) / orderTakerAmount;
    }

    /// @notice Calculates taker amount
    /// @return Result Ceiled taker amount
    function getTakingAmount(
        uint256 orderMakerAmount,
        uint256 orderTakerAmount,
        uint256 swapMakerAmount
    ) internal pure returns (uint256) {
        if ((swapMakerAmount | orderTakerAmount) >> 128 == 0) {
            unchecked {
                return
                    (swapMakerAmount *
                        orderTakerAmount +
                        orderMakerAmount -
                        1) / orderMakerAmount;
            }
        }
        return
            (swapMakerAmount * orderTakerAmount + orderMakerAmount - 1) /
            orderMakerAmount;
    }
}

type RemainingInvalidator is uint256;
library RemainingInvalidatorLib {
    error RemainingInvalidatedOrder();

    function isNewOrder(
        RemainingInvalidator invalidator
    ) internal pure returns (bool) {
        return RemainingInvalidator.unwrap(invalidator) == 0;
    }

    function remaining(
        RemainingInvalidator invalidator
    ) internal pure returns (uint256) {
        uint256 value = RemainingInvalidator.unwrap(invalidator);
        if (value == 0) {
            revert RemainingInvalidatedOrder();
        }
        unchecked {
            return ~value;
        }
    }

    function remaining(
        RemainingInvalidator invalidator,
        uint256 orderMakerAmount
    ) internal pure returns (uint256) {
        uint256 value = RemainingInvalidator.unwrap(invalidator);
        if (value == 0) {
            return orderMakerAmount;
        }
        unchecked {
            return ~value;
        }
    }

    function remains(
        uint256 remainingMakingAmount,
        uint256 makingAmount
    ) internal pure returns (RemainingInvalidator) {
        unchecked {
            return
                RemainingInvalidator.wrap(
                    ~(remainingMakingAmount - makingAmount)
                );
        }
    }
    function fullyFilled() internal pure returns (RemainingInvalidator) {
        return RemainingInvalidator.wrap(type(uint256).max);
    }
}
library OrderLib {
    using AddressLib for Address;
    using MakerTraitsLib for MakerTraits;
    using ExtensionLib for bytes;

    /// @dev Error to be thrown when the extension data of an order is missing.
    error MissingOrderExtension();
    /// @dev Error to be thrown when the order has an unexpected extension.
    error UnexpectedOrderExtension();
    /// @dev Error to be thrown when the order extension hash is invalid.
    error InvalidExtensionHash();

    /// @dev The typehash of the order struct.
    bytes32 internal constant _LIMIT_ORDER_TYPEHASH =
        keccak256(
            "Order("
            "uint256 salt,"
            "address maker,"
            "address receiver,"
            "address makerAsset,"
            "address takerAsset,"
            "uint256 makingAmount,"
            "uint256 takingAmount,"
            "uint256 makerTraits"
            ")"
        );
    uint256 internal constant _ORDER_STRUCT_SIZE = 0x100;
    uint256 internal constant _DATA_HASH_SIZE = 0x120;

    function hash(
        IOrderMixin.Order calldata order
    ) internal pure returns (bytes32 result) {
        bytes32 typehash = _LIMIT_ORDER_TYPEHASH;
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            let ptr := mload(0x40)

            // keccak256(abi.encode(_LIMIT_ORDER_TYPEHASH, order));
            mstore(ptr, typehash)
            calldatacopy(add(ptr, 0x20), order, _ORDER_STRUCT_SIZE)
            result := keccak256(ptr, _DATA_HASH_SIZE)
        }
        result = ECDSA.toTypedDataHash("0x", result);
    }

    function getReceiver(
        IOrderMixin.Order calldata order
    ) internal pure returns (address /*receiver*/) {
        address receiver = order.receiver.get();
        return receiver != address(0) ? receiver : order.maker.get();
    }

    function isValidExtension(
        IOrderMixin.Order calldata order,
        bytes calldata extension
    ) internal pure returns (bool, bytes4) {
        if (order.makerTraits.hasExtension()) {
            if (extension.length == 0)
                return (false, MissingOrderExtension.selector);
            // Lowest 160 bits of the order salt must be equal to the lowest 160 bits of the extension hash
            if (
                uint256(keccak256(extension)) & type(uint160).max !=
                order.salt & type(uint160).max
            ) return (false, InvalidExtensionHash.selector);
        } else {
            if (extension.length > 0)
                return (false, UnexpectedOrderExtension.selector);
        }
        return (true, 0x00000000);
    }
}

interface IPostInteraction {
    /**
     * @notice Callback method that gets called after all fund transfers
     * @param order Order being processed
     * @param extension Order extension data
     * @param orderHash Hash of the order being processed
     * @param taker Taker address
     * @param makingAmount Actual making amount
     * @param takingAmount Actual taking amount
     * @param remainingMakingAmount Order remaining making amount
     * @param extraData Extra data
     */
    function postInteraction(
        IOrderMixin.Order calldata order,
        bytes calldata extension,
        bytes32 orderHash,
        address taker,
        uint256 makingAmount,
        uint256 takingAmount,
        uint256 remainingMakingAmount,
        bytes calldata extraData
    ) external;
}

interface IPreInteraction {
    /**
     * @notice Callback method that gets called before any funds transfers
     * @param order Order being processed
     * @param extension Order extension data
     * @param orderHash Hash of the order being processed
     * @param taker Taker address
     * @param makingAmount Actual making amount
     * @param takingAmount Actual taking amount
     * @param remainingMakingAmount Order remaining making amount
     * @param extraData Extra data
     */
    function preInteraction(
        IOrderMixin.Order calldata order,
        bytes calldata extension,
        bytes32 orderHash,
        address taker,
        uint256 makingAmount,
        uint256 takingAmount,
        uint256 remainingMakingAmount,
        bytes calldata extraData
    ) external;
}
contract ChaingeOrder is Controller {
    using SafeERC20 for IERC20;
    using SafeERC20 for IWETH;
    using OrderLib for IOrderMixin.Order;
    using ExtensionLib for bytes;
    using AddressLib for Address;
    using MakerTraitsLib for MakerTraits;
    using TakerTraitsLib for TakerTraits;
    using RemainingInvalidatorLib for RemainingInvalidator;

    IWETH private _WETH;
    bool private _paused;

    event OrderFilled(bytes32 orderHash, uint256 remainingAmount);

    event OrderCancelled(bytes32 orderHash);

    mapping(address => mapping(bytes32 => RemainingInvalidator))
        private _remainingInvalidator;

    constructor(IWETH weth) {
        _WETH = weth;
        _paused = false;
    }
    modifier whenNotPaused() {
        require(!_paused, "MP: paused");
        _;
    }
    receive() external payable {}

    fallback() external payable {}

    function pause() external onlyOwner {
        _paused = true;
    }

    function unpause() external onlyOwner {
        _paused = false;
    }

    function setWToken(IWETH weth) external onlyOwner {
        _WETH = weth;
    }

    function cancelOrder(bytes32 orderHash) public {
        _remainingInvalidator[msg.sender][orderHash] = RemainingInvalidatorLib
            .fullyFilled();
        emit OrderCancelled(orderHash);
    }

    function cancelOrders(bytes32[] calldata orderHashes) external {
        unchecked {
            for (uint256 i = 0; i < orderHashes.length; i++) {
                cancelOrder(orderHashes[i]);
            }
        }
    }
    function hashOrder(
        IOrderMixin.Order calldata order
    ) external pure returns (bytes32) {
        return order.hash();
    }

    function fillContractOrderArgs(
        IOrderMixin.Order calldata order,
        bytes calldata signature,
        uint256 amount,
        TakerTraits takerTraits,
        bytes calldata args
    )
        external
        onlyController
        whenNotPaused
        returns (
            uint256 /* makingAmount */,
            uint256 /* takingAmount */,
            bytes32 /* orderHash */
        )
    {
        (
            address target,
            bytes calldata extension,
            bytes calldata interaction
        ) = _parseArgs(takerTraits, args);

        return
            _fillContractOrder(
                order,
                signature,
                amount,
                takerTraits,
                target,
                extension,
                interaction
            );
    }

    function _fillContractOrder(
        IOrderMixin.Order calldata order,
        bytes calldata /*signature*/,
        uint256 amount,
        TakerTraits takerTraits,
        address target,
        bytes calldata extension,
        bytes calldata interaction
    )
        private
        returns (uint256 makingAmount, uint256 takingAmount, bytes32 orderHash)
    {
        // Check signature only on the first fill
        orderHash = order.hash();
        uint256 remainingMakingAmount = _checkRemainingMakingAmount(
            order,
            orderHash
        );

        (makingAmount, takingAmount) = _fill(
            order,
            orderHash,
            remainingMakingAmount,
            amount,
            takerTraits,
            target,
            extension,
            interaction
        );
    }

    function _fill(
        IOrderMixin.Order calldata order,
        bytes32 orderHash,
        uint256 remainingMakingAmount,
        uint256 amount,
        TakerTraits takerTraits,
        address target,
        bytes calldata extension,
        bytes calldata /*interaction*/
    ) private returns (uint256 makingAmount, uint256 takingAmount) {
        require(!order.makerTraits.isExpired(), "OrderExpired");

        // Compute maker and taker assets amount
        if (takerTraits.isMakingAmount()) {
            makingAmount = amount < remainingMakingAmount
                ? amount
                : remainingMakingAmount;
            takingAmount = AmountCalculatorLib.getTakingAmount(
                order.makingAmount,
                order.takingAmount,
                remainingMakingAmount
            );

            uint256 threshold = takerTraits.threshold();
            if (threshold > 0) {
                // Check rate: takingAmount / makingAmount <= threshold / amount
                if (amount == makingAmount) {
                    // Gas optimization, no SafeMath.mul()
                    require(takingAmount <= threshold, "TakingAmountTooHigh");
                } else {
                    require(
                        takingAmount * amount <= threshold * makingAmount,
                        "TakingAmountTooHigh"
                    );
                }
            }
        } else {
            takingAmount = amount;
            makingAmount = AmountCalculatorLib.getMakingAmount(
                order.makingAmount,
                order.takingAmount,
                takingAmount
            );
            if (makingAmount > remainingMakingAmount) {
                // Try to decrease taking amount because computed making amount exceeds remaining amount
                makingAmount = remainingMakingAmount;

                takingAmount = AmountCalculatorLib.getTakingAmount(
                    order.makingAmount,
                    order.takingAmount,
                    makingAmount
                );
                require(takingAmount <= amount, "TakingAmountExceeded");
            }

            uint256 threshold = takerTraits.threshold();
            if (threshold > 0) {
                // Check rate: makingAmount / takingAmount >= threshold / amount
                if (amount == takingAmount) {
                    // Gas optimization, no SafeMath.mul()
                    require(makingAmount >= threshold, "MakingAmountTooLow");
                } else {
                    require(
                        makingAmount * amount >= threshold * takingAmount,
                        "MakingAmountTooLow"
                    );
                }
            }
        }
        if (!order.makerTraits.allowPartialFills()) {
            require(
                makingAmount == order.makingAmount,
                "PartialFillNotAllowed"
            );
        }
        require(makingAmount * takingAmount > 0, "SwapWithZeroAmount");

        // Pre interaction, where maker can prepare funds interactively
        {
            if (order.makerTraits.needPreInteractionCall()) {
                bytes calldata data = extension.preInteractionTargetAndData();
                address listener = order.maker.get();
                if (data.length > 19) {
                    listener = address(bytes20(data));
                    data = data[20:];
                }
                IPreInteraction(listener).preInteraction(
                    order,
                    extension,
                    orderHash,
                    msg.sender,
                    makingAmount,
                    takingAmount,
                    remainingMakingAmount,
                    data
                );
            }
        }

        // Maker => Taker
        {
            bool needUnwrap = order.makerAsset.get() == address(_WETH) &&
                takerTraits.unwrapWeth();
            address receiver = needUnwrap ? address(this) : target;
            bool success = _callTransferFromWithSuffix(
                order.makerAsset.get(),
                order.maker.get(),
                receiver,
                makingAmount,
                extension.makerAssetSuffix()
            );
            require(success, "TransferFromMakerToTakerFailed");
            if (needUnwrap) {
                _WETH.safeWithdrawTo(makingAmount, target);
            }
        }

        // Taker => Maker
        if (order.takerAsset.get() == address(_WETH) && msg.value > 0) {
            require(msg.value >= takingAmount, "InvalidMsgValue");
            if (msg.value > takingAmount) {
                unchecked {
                    // solhint-disable-next-line avoid-low-level-calls
                    (bool success, ) = msg.sender.call{
                        value: msg.value - takingAmount
                    }("");
                    require(success, "ETHTransferFailed");
                }
            }

            if (order.makerTraits.unwrapWeth()) {
                // solhint-disable-next-line avoid-low-level-calls
                (bool success, ) = order.getReceiver().call{
                    value: takingAmount
                }("");
                require(success, "ETHTransferFailed");
            } else {
                _WETH.safeDeposit(takingAmount);
                _WETH.safeTransfer(order.getReceiver(), takingAmount);
            }
        } else {
            require(msg.value == 0, "InvalidMsgValue");

            bool needUnwrap = order.takerAsset.get() == address(_WETH) &&
                order.makerTraits.unwrapWeth();
            address receiver = needUnwrap ? address(this) : order.getReceiver();
            require(
                _callTransferFromWithSuffix(
                    order.takerAsset.get(),
                    msg.sender,
                    receiver,
                    takingAmount,
                    extension.takerAssetSuffix()
                ),
                "TransferFromTakerToMakerFailed"
            );

            if (needUnwrap) {
                _WETH.safeWithdrawTo(takingAmount, order.getReceiver());
            }
        }

        // Post interaction, where maker can handle funds interactively
        if (order.makerTraits.needPostInteractionCall()) {
            bytes calldata data = extension.postInteractionTargetAndData();
            address listener = order.maker.get();
            if (data.length > 19) {
                listener = address(bytes20(data));
                data = data[20:];
            }
            IPostInteraction(listener).postInteraction(
                order,
                extension,
                orderHash,
                msg.sender,
                makingAmount,
                takingAmount,
                remainingMakingAmount,
                data
            );
        }

        emit OrderFilled(orderHash, remainingMakingAmount - makingAmount);
    }

    /**
     * @notice Processes the taker interaction arguments.
     * @param takerTraits The taker preferences for the order.
     * @param args The taker interaction arguments.
     * @return target The address to which the order is filled.
     * @return extension The extension calldata of the order.
     * @return interaction The interaction calldata.
     */
    function _parseArgs(
        TakerTraits takerTraits,
        bytes calldata args
    )
        private
        view
        returns (
            address target,
            bytes calldata extension,
            bytes calldata interaction
        )
    {
        if (takerTraits.argsHasTarget()) {
            target = address(bytes20(args));
            args = args[20:];
        } else {
            target = msg.sender;
        }

        uint256 extensionLength = takerTraits.argsExtensionLength();
        if (extensionLength > 0) {
            extension = args[:extensionLength];
            args = args[extensionLength:];
        } else {
            extension = msg.data[:0];
        }

        uint256 interactionLength = takerTraits.argsInteractionLength();
        if (interactionLength > 0) {
            interaction = args[:interactionLength];
        } else {
            interaction = msg.data[:0];
        }
    }

    /**
     * @notice Checks the remaining making amount for the order.
     * @dev If the order has been invalidated, the function will revert.
     * @param order The order to check.
     * @param orderHash The hash of the order.
     * @return remainingMakingAmount The remaining amount of the order.
     */
    function _checkRemainingMakingAmount(
        IOrderMixin.Order calldata order,
        bytes32 orderHash
    ) private view returns (uint256 remainingMakingAmount) {
        remainingMakingAmount = _remainingInvalidator[order.maker.get()][
            orderHash
        ].remaining(order.makingAmount);
        require(remainingMakingAmount > 0, "InvalidatedOrder");
    }

    /**
     * @notice Calls the transferFrom function with an arbitrary suffix.
     * @dev The suffix is appended to the end of the standard ERC20 transferFrom function parameters.
     * @param asset The token to be transferred.
     * @param from The address to transfer the token from.
     * @param to The address to transfer the token to.
     * @param amount The amount of the token to transfer.
     * @param suffix The suffix (additional data) to append to the end of the transferFrom call.
     * @return success A boolean indicating whether the transfer was successful.
     */
    function _callTransferFromWithSuffix(
        address asset,
        address from,
        address to,
        uint256 amount,
        bytes calldata suffix
    ) private returns (bool success) {
        bytes4 selector = IERC20.transferFrom.selector;
        assembly ("memory-safe") {
            // solhint-disable-line no-inline-assembly
            let data := mload(0x40)
            mstore(data, selector)
            mstore(add(data, 0x04), from)
            mstore(add(data, 0x24), to)
            mstore(add(data, 0x44), amount)
            if suffix.length {
                calldatacopy(add(data, 0x64), suffix.offset, suffix.length)
            }
            let status := call(
                gas(),
                asset,
                0,
                data,
                add(0x64, suffix.length),
                0x0,
                0x20
            )
            success := and(
                status,
                or(
                    iszero(returndatasize()),
                    and(gt(returndatasize(), 31), eq(mload(0), 1))
                )
            )
        }
    }
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IWETH","name":"weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"controller","type":"address"}],"name":"ControllerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"controller","type":"address"}],"name":"ControllerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"remainingAmount","type":"uint256"}],"name":"OrderFilled","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"addController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"}],"name":"cancelOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controllerCnt","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"controllers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"Address","name":"maker","type":"uint256"},{"internalType":"Address","name":"receiver","type":"uint256"},{"internalType":"Address","name":"makerAsset","type":"uint256"},{"internalType":"Address","name":"takerAsset","type":"uint256"},{"internalType":"uint256","name":"makingAmount","type":"uint256"},{"internalType":"uint256","name":"takingAmount","type":"uint256"},{"internalType":"MakerTraits","name":"makerTraits","type":"uint256"}],"internalType":"struct IOrderMixin.Order","name":"order","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"TakerTraits","name":"takerTraits","type":"uint256"},{"internalType":"bytes","name":"args","type":"bytes"}],"name":"fillContractOrderArgs","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"Address","name":"maker","type":"uint256"},{"internalType":"Address","name":"receiver","type":"uint256"},{"internalType":"Address","name":"makerAsset","type":"uint256"},{"internalType":"Address","name":"takerAsset","type":"uint256"},{"internalType":"uint256","name":"makingAmount","type":"uint256"},{"internalType":"uint256","name":"takingAmount","type":"uint256"},{"internalType":"MakerTraits","name":"makerTraits","type":"uint256"}],"internalType":"struct IOrderMixin.Order","name":"order","type":"tuple"}],"name":"hashOrder","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"isController","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"removeController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IWETH","name":"weth","type":"address"}],"name":"setWToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080346100bf57601f61172938819003918201601f19168301916001600160401b038311848410176100c4578084926020946040528339810103126100bf57516001600160a01b039081811681036100bf576000543360018060a01b0319821617600055604051923391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3600280546001600160b01b03191660089290921b610100600160a81b031691909117905561164e90816100db8239f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe60806040526004361015610018575b361561001657005b005b6000803560e01c806321c77c9614610f4d5780633f4ba83a14610f1857806356a75868146104e35780637489ec23146104c357806378bbe8b6146104a2578063802b2ef11461047d5780638456cb59146104425780638da5cb5b1461041b578063a7fc7a071461034c578063b429afeb14610311578063d7fc2da4146102b5578063da8c229e1461026f578063f2fde38b146101a75763f6a74ed7146100be575061000e565b346101a45760203660031901126101a4576004356001600160a01b03818116918290036101a0576100f3908354163314610ffa565b808252600160205260408220805490600160ff831615151461013f575b837f33d83959be2573f5453b12eb9d43b3499bc57d96bd2f067ba44803c859e81113602085604051908152a180f35b60ff1991821690556002549060ff8216801561018c57911660001990910160ff161760025560207f33d83959be2573f5453b12eb9d43b3499bc57d96bd2f067ba44803c859e81113610110565b634e487b7160e01b85526011600452602485fd5b8280fd5b80fd5b50346101a45760203660031901126101a4576004356001600160a01b03818116918290036101a0578254908116906101e0338314610ffa565b821561021b576001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b50346101a45760203660031901126101a4576004356001600160a01b038116908190036102b15760408260ff9260209452600184522054166040519015158152f35b5080fd5b50346101a45760203660031901126101a4576004356001600160a01b0380821682036101a0576102e9908354163314610ffa565b60028054610100600160a81b03191660089290921b610100600160a81b031691909117905580f35b50346101a45760203660031901126101a457600435906001600160a01b03821682036101a45760206103428361108e565b6040519015158152f35b50346101a45760203660031901126101a4576004356001600160a01b03818116918290036101a057610382908354163314610ffa565b80825260016020526040822080549060ff8216156103ca575b837f0a8bb31534c0ed46f380cb867bd5c803a189ced9a764e30b3a4991a9901d7474602085604051908152a180f35b600160ff198093161790556002549060ff821660ff811461018c579116600190910160ff161760025560207f0a8bb31534c0ed46f380cb867bd5c803a189ced9a764e30b3a4991a9901d747461039b565b50346101a457806003193601126101a457546040516001600160a01b039091168152602090f35b50346101a457806003193601126101a45761046760018060a01b038254163314610ffa565b6002805460ff60a81b1916600160a81b17905580f35b50346101a4576101003660031901126101a457602061049a6110f2565b604051908152f35b50346101a457806003193601126101a457602060ff60025416604051908152f35b50346101a45760203660031901126101a4576104e0600435611045565b80f35b50346101a457366003190161018081126102b157610100136101a4576101043567ffffffffffffffff81116102b157610520903690600401610fc7565b50506101643567ffffffffffffffff81116102b157610543903690600401610fc7565b9161054d3361108e565b15610edc5760ff60025460a81c16610eaa57818361014435600160fb1b1615610e9f57505061057c83836110c1565b60601c91836014116102b15760140192601319015b62ffffff6101443560e01c8116948515610e9257828611610a175794809203905b6101443560c81c168015610e8b57116102b1575b6105ce6110f2565b9160018060a01b036024351681526003602052604081208382526020526105fc604082205460a435906112fc565b948515610e535764ffffffffff60e43560501c168015159081610e49575b50610e155761014435600160ff1b1615610d4657856101243510600014610d3f5761012435925b83956106528860c43560a435611354565b94610144356001600160b81b031680610cfb575b50505b60e435600160ff1b16610cb5575b610681858861114a565b15610c7b5760e435600160fc1b16610bae575b60025460081c6001600160a01b039081166064359091169081149081610b9b575b6106e2908215610b945730905b8a6106cd87896114b2565b9390926024356001600160a01b03169061139b565b15610b4f57610b2e575b5060025460081c6001600160a01b03908116608435909116908114908180610b26575b15610a6857505083610a315760e435600160f71b16156108bd578280808087610736611444565b5af16107406112b1565b5015610884575b60e435600160fb1b166107bc575b5050508284039384116107a6577ffec331350fce78ba658e082a71da20ac9f8d798a99b3c79681c8440cbfe77e0760406060958151908582526020820152a160405192835260208301526040820152f35b634e487b7160e01b600052601160045260246000fd5b6107c68183611513565b9091906024356001600160a01b0316818460138211610858575b50506001600160a01b031692833b1561085457858995936108208296948b948e8c6040519b8c9a8b998a986323175ef160e11b8a52339260048b01611215565b03925af1801561084957610835575b80610755565b61083f82916111e0565b6101a4578061082f565b6040513d84823e3d90fd5b8580fd5b81955080935061086892506110c1565b60601c90836014116108545760140192601319019038806107e0565b60405162461bcd60e51b8152602060048201526011602482015270115512151c985b9cd9995c91985a5b1959607a1b6044820152606490fd5b60025460081c6001600160a01b03166108d4611444565b60405163a9059cbb60e01b60208201526001600160a01b0390911660248201526044808201879052815267ffffffffffffffff6080820190811190821117610a1b576080810160c082011067ffffffffffffffff60c083011117610a1b576109899160c08201604052602060808301527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656460a08301526080868084516020860182865af19201916109836112b1565b91611544565b80519081159182156109f4575b50506107475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b8192509060209181010312610a1757602001518015158103610a17573880610996565b8380fd5b634e487b7160e01b600052604160045260246000fd5b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c69644d736756616c756560881b6044820152606490fd5b81610b14575b610a90908215610b065730905b87610a8686886114e3565b939092339061139b565b15610ac1571561074757600254610abc9060081c6001600160a01b031685610ab6611444565b916113f0565b610747565b60405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657246726f6d54616b6572546f4d616b65724661696c656400006044820152606490fd5b610b0e611444565b90610a7b565b60e435600160f71b1615159150610a6e565b50600061070f565b600254610b499190889060081c6001600160a01b03166113f0565b386106ec565b60405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657246726f6d4d616b6572546f54616b65724661696c656400006044820152606490fd5b83906106c2565b61014435600160fe1b16151591506106b5565b610bb88284611465565b6024356001600160a01b031691808260138111610c50575b50506001600160a01b0383163b15610c4c578992898887610c108f968b9684988f6040519b8c9a8b998a98630986bdd560e01b8a52339260048b01611215565b03926001600160a01b03165af18015610c4157610c2e575b50610694565b610c3a909491946111e0565b9238610c28565b6040513d87823e3d90fd5b8680fd5b9250925050610c5f81836110c1565b60601c9181601411610c4c576014019060131901903880610bd0565b60405162461bcd60e51b815260206004820152601260248201527114ddd85c15da5d1a16995c9bd05b5bdd5b9d60721b6044820152606490fd5b60a43587146106775760405162461bcd60e51b815260206004820152601560248201527414185c9d1a585b119a5b1b139bdd105b1b1bddd959605a1b6044820152606490fd5b610124358203610d1957610d12915086111561119e565b3880610666565b610d33610d3a92610d2d610124358a61114a565b9261114a565b101561119e565b610d12565b8592610641565b6101243592610d5a8460c43560a43561132d565b95878711610db9575b610144356001600160b81b031680610d7c575b50610669565b610124358603610d9857610d929088101561115d565b38610d76565b610db490610dad87610d2d610124358c61114a565b111561115d565b610d92565b8796509350610dcd8660c43560a435611354565b9361012435851115610d635760405162461bcd60e51b815260206004820152601460248201527315185ada5b99d05b5bdd5b9d115e18d95959195960621b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b13dc99195c915e1c1a5c995960a21b6044820152606490fd5b905042113861061a565b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b230ba32b227b93232b960811b6044820152606490fd5b50506105c6565b50909350819382916105b2565b925092503391610591565b60405162461bcd60e51b815260206004820152600a60248201526913540e881c185d5cd95960b21b6044820152606490fd5b60405162461bcd60e51b81526020600482015260146024820152736e6f20636f6e74726f6c6c65722072696768747360601b6044820152606490fd5b50346101a457806003193601126101a457610f3d60018060a01b038254163314610ffa565b6002805460ff60a81b1916905580f35b50346101a45760203660031901126101a45767ffffffffffffffff6004358181116101a057366023820112156101a05780600401359182116101a05760249060053660248560051b84010111610fc357845b848110610faa578580f35b80610fbd85600193851b86010135611045565b01610f9f565b8480fd5b9181601f84011215610ff55782359167ffffffffffffffff8311610ff55760208381860195010111610ff557565b600080fd5b1561100157565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60207f5152abf959f6564662358c2e52b702259b78bac5ee7842a0f01937e670efcc7d9133600052600382526040600020816000528252600019604060002055604051908152a1565b6000546001600160a01b03918216911681149081156110ab575090565b9050600052600160205260ff6040600020541690565b6bffffffffffffffffffffffff1990358181169392601481106110e357505050565b60140360031b82901b16169150565b60426101206040517f3af21ec5a20011b88d3b7b4ed7c806cef05a5980cf34974bcd53566a131f7e4c8152610100600460208301372060405161190160f01b815261060f60f31b600282015260228101919091522090565b818102929181159184041417156107a657565b1561116457565b60405162461bcd60e51b81526020600482015260126024820152714d616b696e67416d6f756e74546f6f4c6f7760701b6044820152606490fd5b156111a557565b60405162461bcd60e51b81526020600482015260136024820152720a8c2d6d2dcce82dadeeadce8a8dede90d2ced606b1b6044820152606490fd5b67ffffffffffffffff8111610a1b57604052565b908060209392818452848401376000828201840152601f01601f1916010190565b94916112ae9997949161127591999794996101e0600435895260243560208a015260443560408a015260643560608a015260843560808a015260a43560a08a015260c43560c08a015260e43560e08a0152806101008a01528801916111f4565b6101208601989098526001600160a01b03166101408501526101608401526101808301526101a08201528084036101c0909101526111f4565b90565b3d156112f75767ffffffffffffffff903d828111610a1b5760405192601f8201601f19908116603f0116840190811184821017610a1b5760405282523d6000602084013e565b606090565b90811561130857501990565b905090565b8115611317570490565b634e487b7160e01b600052601260045260246000fd5b80831760801c1561134a57611345906112ae9361114a565b61130d565b6112ae920261130d565b9181811760801c1561138a579061136a9161114a565b908082018092116107a65760001982019182116107a6576112ae9161130d565b6112ae92910281016000190161130d565b92948060009581602098889596604051976323b872dd60e01b89526004890152602488015260448701526113e4575b5050606401925af1600160005114601f3d11163d15171690565b606485013780386113ca565b916024926000809481808094632e1a7d4d60e01b8252876004525af11561084957306001600160a01b0382160361142657505050565b828080938193611388f1156114385750565b604051903d90823e3d90fd5b6001600160a01b03604435811690811561145c575090565b90506024351690565b919091602083106114a95780359063ffffffff808360a01c169260c01c1693601f19018411611498578101602001920390565b6309605a0160e41b60005260046000fd5b50600091508190565b919091602083106114a95780359063ffffffff918060201b8316921693601f19018411611498578101602001920390565b919091602083106114a95780359063ffffffff8083169260201c1693601f19018411611498578101602001920390565b919091602083106114a95780359063ffffffff8260c01c169160e01c93601f19018411611498578101602001920390565b919290156115a65750815115611558575090565b3b156115615790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156115b95750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b8285106115ff575050604492506000838284010152601f80199101168101030190fd5b84810182015186860160440152938101938593506115dc56fea2646970667358221220bc99d09c388768d2df496298f426d330e34ae5938868e7d121e259fadf58d07564736f6c63430008170033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed Bytecode

0x60806040526004361015610018575b361561001657005b005b6000803560e01c806321c77c9614610f4d5780633f4ba83a14610f1857806356a75868146104e35780637489ec23146104c357806378bbe8b6146104a2578063802b2ef11461047d5780638456cb59146104425780638da5cb5b1461041b578063a7fc7a071461034c578063b429afeb14610311578063d7fc2da4146102b5578063da8c229e1461026f578063f2fde38b146101a75763f6a74ed7146100be575061000e565b346101a45760203660031901126101a4576004356001600160a01b03818116918290036101a0576100f3908354163314610ffa565b808252600160205260408220805490600160ff831615151461013f575b837f33d83959be2573f5453b12eb9d43b3499bc57d96bd2f067ba44803c859e81113602085604051908152a180f35b60ff1991821690556002549060ff8216801561018c57911660001990910160ff161760025560207f33d83959be2573f5453b12eb9d43b3499bc57d96bd2f067ba44803c859e81113610110565b634e487b7160e01b85526011600452602485fd5b8280fd5b80fd5b50346101a45760203660031901126101a4576004356001600160a01b03818116918290036101a0578254908116906101e0338314610ffa565b821561021b576001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b50346101a45760203660031901126101a4576004356001600160a01b038116908190036102b15760408260ff9260209452600184522054166040519015158152f35b5080fd5b50346101a45760203660031901126101a4576004356001600160a01b0380821682036101a0576102e9908354163314610ffa565b60028054610100600160a81b03191660089290921b610100600160a81b031691909117905580f35b50346101a45760203660031901126101a457600435906001600160a01b03821682036101a45760206103428361108e565b6040519015158152f35b50346101a45760203660031901126101a4576004356001600160a01b03818116918290036101a057610382908354163314610ffa565b80825260016020526040822080549060ff8216156103ca575b837f0a8bb31534c0ed46f380cb867bd5c803a189ced9a764e30b3a4991a9901d7474602085604051908152a180f35b600160ff198093161790556002549060ff821660ff811461018c579116600190910160ff161760025560207f0a8bb31534c0ed46f380cb867bd5c803a189ced9a764e30b3a4991a9901d747461039b565b50346101a457806003193601126101a457546040516001600160a01b039091168152602090f35b50346101a457806003193601126101a45761046760018060a01b038254163314610ffa565b6002805460ff60a81b1916600160a81b17905580f35b50346101a4576101003660031901126101a457602061049a6110f2565b604051908152f35b50346101a457806003193601126101a457602060ff60025416604051908152f35b50346101a45760203660031901126101a4576104e0600435611045565b80f35b50346101a457366003190161018081126102b157610100136101a4576101043567ffffffffffffffff81116102b157610520903690600401610fc7565b50506101643567ffffffffffffffff81116102b157610543903690600401610fc7565b9161054d3361108e565b15610edc5760ff60025460a81c16610eaa57818361014435600160fb1b1615610e9f57505061057c83836110c1565b60601c91836014116102b15760140192601319015b62ffffff6101443560e01c8116948515610e9257828611610a175794809203905b6101443560c81c168015610e8b57116102b1575b6105ce6110f2565b9160018060a01b036024351681526003602052604081208382526020526105fc604082205460a435906112fc565b948515610e535764ffffffffff60e43560501c168015159081610e49575b50610e155761014435600160ff1b1615610d4657856101243510600014610d3f5761012435925b83956106528860c43560a435611354565b94610144356001600160b81b031680610cfb575b50505b60e435600160ff1b16610cb5575b610681858861114a565b15610c7b5760e435600160fc1b16610bae575b60025460081c6001600160a01b039081166064359091169081149081610b9b575b6106e2908215610b945730905b8a6106cd87896114b2565b9390926024356001600160a01b03169061139b565b15610b4f57610b2e575b5060025460081c6001600160a01b03908116608435909116908114908180610b26575b15610a6857505083610a315760e435600160f71b16156108bd578280808087610736611444565b5af16107406112b1565b5015610884575b60e435600160fb1b166107bc575b5050508284039384116107a6577ffec331350fce78ba658e082a71da20ac9f8d798a99b3c79681c8440cbfe77e0760406060958151908582526020820152a160405192835260208301526040820152f35b634e487b7160e01b600052601160045260246000fd5b6107c68183611513565b9091906024356001600160a01b0316818460138211610858575b50506001600160a01b031692833b1561085457858995936108208296948b948e8c6040519b8c9a8b998a986323175ef160e11b8a52339260048b01611215565b03925af1801561084957610835575b80610755565b61083f82916111e0565b6101a4578061082f565b6040513d84823e3d90fd5b8580fd5b81955080935061086892506110c1565b60601c90836014116108545760140192601319019038806107e0565b60405162461bcd60e51b8152602060048201526011602482015270115512151c985b9cd9995c91985a5b1959607a1b6044820152606490fd5b60025460081c6001600160a01b03166108d4611444565b60405163a9059cbb60e01b60208201526001600160a01b0390911660248201526044808201879052815267ffffffffffffffff6080820190811190821117610a1b576080810160c082011067ffffffffffffffff60c083011117610a1b576109899160c08201604052602060808301527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656460a08301526080868084516020860182865af19201916109836112b1565b91611544565b80519081159182156109f4575b50506107475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b8192509060209181010312610a1757602001518015158103610a17573880610996565b8380fd5b634e487b7160e01b600052604160045260246000fd5b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c69644d736756616c756560881b6044820152606490fd5b81610b14575b610a90908215610b065730905b87610a8686886114e3565b939092339061139b565b15610ac1571561074757600254610abc9060081c6001600160a01b031685610ab6611444565b916113f0565b610747565b60405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657246726f6d54616b6572546f4d616b65724661696c656400006044820152606490fd5b610b0e611444565b90610a7b565b60e435600160f71b1615159150610a6e565b50600061070f565b600254610b499190889060081c6001600160a01b03166113f0565b386106ec565b60405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657246726f6d4d616b6572546f54616b65724661696c656400006044820152606490fd5b83906106c2565b61014435600160fe1b16151591506106b5565b610bb88284611465565b6024356001600160a01b031691808260138111610c50575b50506001600160a01b0383163b15610c4c578992898887610c108f968b9684988f6040519b8c9a8b998a98630986bdd560e01b8a52339260048b01611215565b03926001600160a01b03165af18015610c4157610c2e575b50610694565b610c3a909491946111e0565b9238610c28565b6040513d87823e3d90fd5b8680fd5b9250925050610c5f81836110c1565b60601c9181601411610c4c576014019060131901903880610bd0565b60405162461bcd60e51b815260206004820152601260248201527114ddd85c15da5d1a16995c9bd05b5bdd5b9d60721b6044820152606490fd5b60a43587146106775760405162461bcd60e51b815260206004820152601560248201527414185c9d1a585b119a5b1b139bdd105b1b1bddd959605a1b6044820152606490fd5b610124358203610d1957610d12915086111561119e565b3880610666565b610d33610d3a92610d2d610124358a61114a565b9261114a565b101561119e565b610d12565b8592610641565b6101243592610d5a8460c43560a43561132d565b95878711610db9575b610144356001600160b81b031680610d7c575b50610669565b610124358603610d9857610d929088101561115d565b38610d76565b610db490610dad87610d2d610124358c61114a565b111561115d565b610d92565b8796509350610dcd8660c43560a435611354565b9361012435851115610d635760405162461bcd60e51b815260206004820152601460248201527315185ada5b99d05b5bdd5b9d115e18d95959195960621b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b13dc99195c915e1c1a5c995960a21b6044820152606490fd5b905042113861061a565b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b230ba32b227b93232b960811b6044820152606490fd5b50506105c6565b50909350819382916105b2565b925092503391610591565b60405162461bcd60e51b815260206004820152600a60248201526913540e881c185d5cd95960b21b6044820152606490fd5b60405162461bcd60e51b81526020600482015260146024820152736e6f20636f6e74726f6c6c65722072696768747360601b6044820152606490fd5b50346101a457806003193601126101a457610f3d60018060a01b038254163314610ffa565b6002805460ff60a81b1916905580f35b50346101a45760203660031901126101a45767ffffffffffffffff6004358181116101a057366023820112156101a05780600401359182116101a05760249060053660248560051b84010111610fc357845b848110610faa578580f35b80610fbd85600193851b86010135611045565b01610f9f565b8480fd5b9181601f84011215610ff55782359167ffffffffffffffff8311610ff55760208381860195010111610ff557565b600080fd5b1561100157565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60207f5152abf959f6564662358c2e52b702259b78bac5ee7842a0f01937e670efcc7d9133600052600382526040600020816000528252600019604060002055604051908152a1565b6000546001600160a01b03918216911681149081156110ab575090565b9050600052600160205260ff6040600020541690565b6bffffffffffffffffffffffff1990358181169392601481106110e357505050565b60140360031b82901b16169150565b60426101206040517f3af21ec5a20011b88d3b7b4ed7c806cef05a5980cf34974bcd53566a131f7e4c8152610100600460208301372060405161190160f01b815261060f60f31b600282015260228101919091522090565b818102929181159184041417156107a657565b1561116457565b60405162461bcd60e51b81526020600482015260126024820152714d616b696e67416d6f756e74546f6f4c6f7760701b6044820152606490fd5b156111a557565b60405162461bcd60e51b81526020600482015260136024820152720a8c2d6d2dcce82dadeeadce8a8dede90d2ced606b1b6044820152606490fd5b67ffffffffffffffff8111610a1b57604052565b908060209392818452848401376000828201840152601f01601f1916010190565b94916112ae9997949161127591999794996101e0600435895260243560208a015260443560408a015260643560608a015260843560808a015260a43560a08a015260c43560c08a015260e43560e08a0152806101008a01528801916111f4565b6101208601989098526001600160a01b03166101408501526101608401526101808301526101a08201528084036101c0909101526111f4565b90565b3d156112f75767ffffffffffffffff903d828111610a1b5760405192601f8201601f19908116603f0116840190811184821017610a1b5760405282523d6000602084013e565b606090565b90811561130857501990565b905090565b8115611317570490565b634e487b7160e01b600052601260045260246000fd5b80831760801c1561134a57611345906112ae9361114a565b61130d565b6112ae920261130d565b9181811760801c1561138a579061136a9161114a565b908082018092116107a65760001982019182116107a6576112ae9161130d565b6112ae92910281016000190161130d565b92948060009581602098889596604051976323b872dd60e01b89526004890152602488015260448701526113e4575b5050606401925af1600160005114601f3d11163d15171690565b606485013780386113ca565b916024926000809481808094632e1a7d4d60e01b8252876004525af11561084957306001600160a01b0382160361142657505050565b828080938193611388f1156114385750565b604051903d90823e3d90fd5b6001600160a01b03604435811690811561145c575090565b90506024351690565b919091602083106114a95780359063ffffffff808360a01c169260c01c1693601f19018411611498578101602001920390565b6309605a0160e41b60005260046000fd5b50600091508190565b919091602083106114a95780359063ffffffff918060201b8316921693601f19018411611498578101602001920390565b919091602083106114a95780359063ffffffff8083169260201c1693601f19018411611498578101602001920390565b919091602083106114a95780359063ffffffff8260c01c169160e01c93601f19018411611498578101602001920390565b919290156115a65750815115611558575090565b3b156115615790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156115b95750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b8285106115ff575050604492506000838284010152601f80199101168101030190fd5b84810182015186860160440152938101938593506115dc56fea2646970667358221220bc99d09c388768d2df496298f426d330e34ae5938868e7d121e259fadf58d07564736f6c63430008170033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

-----Decoded View---------------
Arg [0] : weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2


Deployed Bytecode Sourcemap

41639:13987:0:-:0;;;;;;;;;-1:-1:-1;41639:13987:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48829:16;41639:13987;48829:16;;;41639:13987;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;669:68;41639:13987;;;;168:10;677:23;669:68;:::i;:::-;41639:13987;;;2015:11;41639:13987;;;;;;;;2015:11;41639:13987;;;;;2015:32;2011:124;;41639:13987;;2149:30;41639:13987;;;;;;;2149:30;41639:13987;;2011:124;-1:-1:-1;;41639:13987:0;;;;;2109:15;41639:13987;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;2109:15;41639:13987;;2149:30;2011:124;;41639:13987;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;;;;;;168:10;669:68;168:10;677:23;;669:68;:::i;:::-;862:22;;41639:13987;;-1:-1:-1;;;;;;41639:13987:0;;;;;1139:40;41639:13987;;1139:40;41639:13987;;;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;;;;;;;1332:43;41639:13987;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;669:68;41639:13987;;;;168:10;677:23;669:68;:::i;:::-;42722:12;41639:13987;;-1:-1:-1;;;;;;41639:13987:0;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;669:68;41639:13987;;;;168:10;677:23;669:68;:::i;:::-;41639:13987;;;1762:11;41639:13987;;;;;;;;;;;;1758:124;;41639:13987;;1896:28;41639:13987;;;;;;;1896:28;41639:13987;;1758:124;1762:11;41639:13987;;;;;;;;1856:15;41639:13987;;;;;;;;;;;;1762:11;41639:13987;;;;;;1856:15;41639:13987;;1896:28;1758:124;;41639:13987;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;;;;;;;;;;;;;669:68;41639:13987;;;;;;;;168:10;677:23;669:68;:::i;:::-;42559:14;41639:13987;;-1:-1:-1;;;;41639:13987:0;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;43297:12;;:::i;:::-;41639:13987;;;;;;;;;;;;;;;;;;;;;1381:30;41639:13987;;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;;-1:-1:-1;41639:13987:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:::i;:::-;168:10;1462:26;168:10;1462:26;:::i;:::-;41639:13987;;;;42397:7;41639:13987;;;;;;43860:29;;41639:13987;;-1:-1:-1;;;25186:50:0;25185:57;41639:13987;;52625:13;;;;;;:::i;:::-;41639:13987;;;;52665:2;41639:13987;;;52665:2;41639:13987;;-1:-1:-1;;41639:13987:0;52561:169;24803:8;41639:13987;;;;25384:108;;;52813:19;;;;41639:13987;;;;;52848:34;;41639:13987;;52809:182;;41639:13987;;24876:3;41639:13987;25636:128;53078:21;;;;41639:13987;;;53074:147;44584:12;;:::i;:::-;41639:13987;;;;;;53767:11;41639:13987;16476:37;41639:13987;;53745:21;53767:11;41639:13987;;;;;;;53767:11;41639:13987;53745:103;41639:13987;;;;53829:18;41639:13987;53745:103;;:::i;:::-;53866:25;;;41639:13987;;17247:2;45341:17;41639:13987;17247:2;41639:13987;19528:86;19631:15;;;:47;;;;53074:147;45340:30;41639:13987;;;;-1:-1:-1;;;25887:52:0;25886:59;41639:13987;;;;;45510:30;:95;:30;;;41639:13987;;45510:95;;45495:110;41639:13987;45634:160;41639:13987;45723:18;41639:13987;53829:18;41639:13987;45634:160;:::i;:::-;25005:66;41639:13987;;-1:-1:-1;;;;;26576:46:0;;45866:515;;45510:95;45447:2263;;;45341:17;41639:13987;-1:-1:-1;;;20961:56:0;47719:183;;45447:2263;47919:27;;;;:::i;:::-;:31;41639:13987;;45341:17;41639:13987;-1:-1:-1;;;21387:60:0;48070:681;;45447:2263;42397:7;41639:13987;;;-1:-1:-1;;;;;41639:13987:0;;;48829:16;41639:13987;16476:37;;;48829:40;;;;;:84;;45447:2263;49010:218;;48946:35;;;;48967:4;48946:35;;28016:46;;;;;:::i;:::-;41639:13987;;;53767:11;41639:13987;-1:-1:-1;;;;;16476:37:0;;49010:218;:::i;:::-;41639:13987;;;49306:91;;48946:35;-1:-1:-1;42397:7:0;41639:13987;;;-1:-1:-1;;;;;41639:13987:0;;;49447:16;41639:13987;16476:37;;;49447:40;;;;;;:57;;48946:35;49443:1699;;;49528:25;;;41639:13987;;45341:17;41639:13987;-1:-1:-1;;;24255:51:0;:56;41639:13987;;50101:19;;;;;;;:::i;:::-;:87;;;;:::i;:::-;;41639:13987;;;49961:438;45341:17;41639:13987;-1:-1:-1;;;25186:50:0;51224:617;;49443:1699;41639:13987;;;;;;;;;;;51856:60;41639:13987;48829:16;41639:13987;;;;;;;53767:11;41639:13987;;;51856:60;41639:13987;;;;;53767:11;41639:13987;;;;;;;;;;;;;;;;;53767:11;41639:13987;;51224:617;29283:49;;;;:::i;:::-;51287:62;;;53767:11;41639:13987;-1:-1:-1;;;;;16476:37:0;51287:62;;51431:2;51417:16;;51413:122;;51224:617;-1:-1:-1;;;;;;;41639:13987:0;;51548:282;;;;;41639:13987;;;;51548:282;41639:13987;;;;;;;;;;;;;;;;;;;51548:282;;168:10;51548:282;41639:13987;51548:282;;;:::i;:::-;;;;;;;;;;;51224:617;;;;51548:282;;;;;:::i;:::-;41639:13987;;51548:282;;;;41639:13987;;;;;;;;;51548:282;41639:13987;;;51413:122;51472:13;;;;;;;;;;:::i;:::-;48829:16;41639:13987;;;51516:2;41639:13987;;;51516:2;41639:13987;;-1:-1:-1;;41639:13987:0;;51413:122;;;;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;48829:16;;41639:13987;49961:438;42397:7;41639:13987;;;-1:-1:-1;;;;;41639:13987:0;50350:19;;:::i;:::-;41639:13987;;-1:-1:-1;;;53767:11:0;10541:58;;;-1:-1:-1;;;;;41639:13987:0;;;53767:11;10541:58;;41639:13987;;;;;;;;10541:58;;41639:13987;;;;;;;;;-1:-1:-1;41639:13987:0;;;;;;;;;;;;;;;;;;7247:147;41639:13987;;;;;;53767:11;41639:13987;;;;;;;;;;7165:53;;;;53767:11;10541:58;;7165:53;;;;41639:13987;;7165:53;;;:::i;:::-;7247:147;;:::i;:::-;41639:13987;;13132:22;;;:56;;;;;49961:438;41639:13987;;49961:438;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;;;;;;-1:-1:-1;;;48829:16:0;41639:13987;;;49447:16;;41639:13987;13132:56;13158:30;;;;53767:11;13158:30;;;41639:13987;;;;53767:11;13158:30;41639:13987;;;;;;;;13132:56;;;;41639:13987;;;;;;;;;;;;;53767:11;41639:13987;;;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;48829:16;;41639:13987;49443:1699;50504:90;;;49443:1699;50714:235;;50627:48;;;;50648:4;50627:48;;28196:46;;;;;:::i;:::-;168:10;;;;50714:235;;:::i;:::-;41639:13987;;;51028:104;49443:1699;51028:104;42397:7;41639:13987;51097:19;;41639:13987;;-1:-1:-1;;;;;41639:13987:0;51097:19;;;:::i;:::-;;;:::i;:::-;49443:1699;;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;;;;;;48829:16;;41639:13987;50627:48;50656:19;;:::i;:::-;50627:48;;;50504:90;45341:17;41639:13987;-1:-1:-1;;;24255:51:0;:56;;;-1:-1:-1;50504:90:0;;49447:57;;41639:13987;49447:57;;49306:91;42397:7;41639:13987;49375:6;;41639:13987;;;;;-1:-1:-1;;;;;41639:13987:0;49375:6;:::i;:::-;49306:91;;;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;;;;;;48829:16;;41639:13987;48946:35;;;;;48829:84;41639:13987;;-1:-1:-1;;;26050:51:0;26049:58;;;-1:-1:-1;48829:84:0;;48070:681;29088:48;;;;:::i;:::-;53767:11;41639:13987;-1:-1:-1;;;;;16476:37:0;;48136:61;;48287:2;48273:16;;48269:134;;48070:681;-1:-1:-1;;;;;;;41639:13987:0;;48420:316;;;;41639:13987;;;;;48420:316;41639:13987;;;;;;;;;;;;;;;;;;;48420:316;;168:10;48420:316;41639:13987;48420:316;;;:::i;:::-;;;-1:-1:-1;;;;;41639:13987:0;48420:316;;;;;;;;48070:681;;;;48420:316;;;;;;;:::i;:::-;;;;;;41639:13987;;;;;;;;;48420:316;41639:13987;;;48269:134;48332:13;;;;;;;;;:::i;:::-;41639:13987;;;;48380:2;41639:13987;;;48380:2;41639:13987;;;;;48269:134;;;;;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;;;;47719:183;53829:18;41639:13987;;;47719:183;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;;;;45866:515;41639:13987;;45988:22;;;;46093:57;46101:25;;;;;46093:57;:::i;:::-;45866:515;;;;45984:383;46255:24;46197:151;41639:13987;46230:21;41639:13987;;46230:21;;:::i;:::-;46255:24;;:::i;:::-;-1:-1:-1;46230:49:0;46197:151;:::i;:::-;45984:383;;45510:95;;;;;45447:2263;41639:13987;;;46461:151;41639:13987;46550:18;41639:13987;53829:18;41639:13987;46461:151;:::i;:::-;46630:36;;;;46626:490;;45447:2263;41639:13987;;-1:-1:-1;;;;;26576:46:0;;47187:513;;45447:2263;;;;47187:513;41639:13987;;47309:22;;;;47414:56;47422:25;;;;47414:56;:::i;:::-;47187:513;;;47305:381;47517:150;41639:13987;47575:24;41639:13987;47550:21;41639:13987;;47550:21;;:::i;47575:24::-;-1:-1:-1;47550:49:0;47517:150;:::i;:::-;47305:381;;46626:490;46791:36;;-1:-1:-1;46791:36:0;-1:-1:-1;46861:167:0;46791:36;46550:18;41639:13987;53829:18;41639:13987;46861:167;:::i;:::-;41639:13987;;;47054:22;;41639:13987;46626:490;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;;;;19631:47;19663:15;;;-1:-1:-1;19631:47:0;;;41639:13987;;;-1:-1:-1;;;41639:13987:0;;53767:11;41639:13987;;;;;53767:11;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;;;;53074:147;;;;;52809:182;52956:24;;;;;;;52809:182;;;52561:169;168:10;;;;;52561:169;;;41639:13987;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;;;;;;;;;669:68;41639:13987;;;;;;;;168:10;677:23;669:68;:::i;:::-;42634:15;41639:13987;;-1:-1:-1;;;;41639:13987:0;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43056:13;43071:22;;;;;;41639:13987;;;43095:3;41639:13987;43130:14;41639:13987;;;;;;;;;43130:14;:::i;:::-;41639:13987;43056:13;;41639:13987;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;42747:201;41639:13987;42916:25;42747:201;42826:10;-1:-1:-1;41639:13987:0;42804:21;41639:13987;;;-1:-1:-1;41639:13987:0;;-1:-1:-1;41639:13987:0;;;;;;-1:-1:-1;41639:13987:0;;;;;;;42916:25;42747:201::o;1537:144::-;619:6;41639:13987;-1:-1:-1;;;;;41639:13987:0;;;;;1624:22;;;:50;;;;1617:57;1537:144;:::o;1624:50::-;41639:13987;;619:6;41639:13987;1650:11;41639:13987;;;;619:6;41639:13987;;;1537:144;:::o;41639:13987::-;-1:-1:-1;;41639:13987:0;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;41639:13987:0:o;38438:572::-;34429:415;38599:351;;;37998:320;38599:351;;;41639:13987;38599:351;;;;;;34429:415;-1:-1:-1;;;34429:415:0;;-1:-1:-1;;;34429:415:0;;;;;;;;;;;;;38438:572::o;41639:13987::-;;;;;;;;;;;;;;;;:::o;:::-;;;;:::o;:::-;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;41639:13987:0;;;;;;;;-1:-1:-1;;41639:13987:0;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;41639:13987:0;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41639:13987:0;;;;:::o;:::-;;;:::o;36620:336::-;;36833:10;;36829:64;;36933:6;;36620:336;:::o;36829:64::-;36859:23;;;:::o;41639:13987::-;;;;;;;:::o;:::-;;;;;;;;;;;;34888:435;35067:34;;;35106:3;41639:13987;35066:48;35062:183;;35262:34;;35261:55;35262:34;;:::i;:::-;35261:55;:::i;35062:183::-;35165:55;41639:13987;;35165:55;:::i;35412:597::-;;35591:34;;;35630:3;41639:13987;35590:48;35586:298;;35913:34;;;;:::i;:::-;41639:13987;;;;;;;;;-1:-1:-1;;41639:13987:0;;;;;;;35912:90;;;:::i;35586:298::-;35709:150;;41639:13987;;;;-1:-1:-1;;41639:13987:0;35709:150;:::i;54515:1109::-;;;;54775:843;54515:1109;;54775:843;54515:1109;;;;54775:843;;54737:28;;;;54775:843;;;;;;;;;;;;;;;;54515:1109;54775:843;;;;;;;;;;;;;;;;;;;54515:1109;:::o;54775:843::-;;;;;;;;;15743:524;;14929:370;15743:524;14929:370;14896:23;;;;;;;;;14929:370;;;;;;;;;;15880:4;-1:-1:-1;;;;;41639:13987:0;;15866:19;15862:399;;15743:524;;;:::o;15862:399::-;15901:350;;;;;;;;;;;15743:524;:::o;15901:350::-;;;;;;;;;;;39016:240;-1:-1:-1;;;;;39159:14:0;41639:13987;16476:37;;;39196:22;;41639:13987;;39196:53;39016:240;:::o;39196:53::-;41639:13987;;39232:11;41639:13987;16476:37;39016:240;:::o;29656:563::-;;;;29809:4;29790:23;;29786:48;;29901:259;;26923:614;;;;;;;;;;;41639:13987;;;29901:259;26923:614;;;;;;29809:4;26923:614;;;;29656:563::o;26923:614::-;26887:26;;;-1:-1:-1;26923:614:0;;-1:-1:-1;26923:614:0;29786:48;-1:-1:-1;29822:8:0;;-1:-1:-1;29822:8:0;;29815:19::o;29656:563::-;;;;29809:4;29790:23;;29786:48;;29901:259;;26923:614;;;;29809:4;26923:614;;;;;41639:13987;;;29901:259;26923:614;;;;;;29809:4;26923:614;;;;29656:563::o;:::-;;;;29809:4;29790:23;;29786:48;;29901:259;;26923:614;;;;;;29809:4;26923:614;;41639:13987;;;29901:259;26923:614;;;;;;29809:4;26923:614;;;;29656:563::o;:::-;;;;29809:4;29790:23;;29786:48;;29901:259;;26923:614;;;;;;;;;41639:13987;;;29901:259;26923:614;;;;;;29809:4;26923:614;;;;29656:563::o;8849:628::-;;;;9053:418;;;41639:13987;;;9084:22;9080:286;;9379:17;;:::o;9080:286::-;5505:19;:23;41639:13987;;9379:17;:::o;41639:13987::-;;;-1:-1:-1;;;41639:13987:0;;;;;;;;;;;;;;;;;;;;9053:418;41639:13987;;;;-1:-1:-1;9965:21:0;:17;;10137:142;;;;;;;9961:379;41639:13987;;;;;;10309:20;;41639:13987;;;10309:20;;;41639:13987;;;;;;;;;9985:1;41639:13987;;;;;;;;;;;;9985:1;41639:13987;;;;;;;;;;;;;;10309:20;;;;41639:13987;;;;;;;;;;;;;;;;;;;-1:-1:-1;41639:13987:0;

Swarm Source

ipfs://bc99d09c388768d2df496298f426d330e34ae5938868e7d121e259fadf58d075

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.