S Price: $0.497683 (-8.07%)
    /

    Contract

    0xD4aD5Ed9E1436904624b6dB8B1BE31f36317C636

    Overview

    S Balance

    Sonic LogoSonic LogoSonic Logo10,410.519703872168939579 S

    S Value

    $5,181.14 (@ $0.50/S)

    Token Holdings

    Multichain Info

    No addresses found
    Transaction Hash
    Method
    Block
    Age
    From
    To
    Amount
    Set Approval For...167622722025-03-29 10:09:0628 mins ago1743242946IN
    0xD4aD5Ed9...36317C636
    0 S0.0026686555
    Set Approval For...162319152025-03-27 2:24:112 days ago1743042251IN
    0xD4aD5Ed9...36317C636
    0 S0.0026696255.02
    Set Approval For...146964682025-03-19 20:02:199 days ago1742414539IN
    0xD4aD5Ed9...36317C636
    0 S0.0012149550.0001
    Set Approval For...139077202025-03-15 17:07:5913 days ago1742058479IN
    0xD4aD5Ed9...36317C636
    0 S0.0030568263
    Set Approval For...136640472025-03-14 12:10:4114 days ago1741954241IN
    0xD4aD5Ed9...36317C636
    0 S0.0023105550.0001
    Set Approval For...131312312025-03-11 22:01:4317 days ago1741730503IN
    0xD4aD5Ed9...36317C636
    0 S0.0023105550.0001
    Set Approval For...130867322025-03-11 17:02:3717 days ago1741712557IN
    0xD4aD5Ed9...36317C636
    0 S0.0023105550.0001
    Set Approval For...121201042025-03-06 20:03:1922 days ago1741291399IN
    0xD4aD5Ed9...36317C636
    0 S0.0014164755
    Set Approval For...119364462025-03-06 0:09:2623 days ago1741219766IN
    0xD4aD5Ed9...36317C636
    0 S0.0031630865.19
    Set Approval For...119241812025-03-05 22:52:1023 days ago1741215130IN
    0xD4aD5Ed9...36317C636
    0 S0.0026691455.01
    Set Approval For...119055002025-03-05 20:54:2623 days ago1741208066IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    Set Approval For...118442942025-03-05 14:39:3023 days ago1741185570IN
    0xD4aD5Ed9...36317C636
    0 S0.0014471156.19
    Set Approval For...115230612025-03-04 2:13:3825 days ago1741054418IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    Set Approval For...111901372025-03-02 14:06:3426 days ago1740924394IN
    0xD4aD5Ed9...36317C636
    0 S0.0027726550
    Set Approval For...107908262025-02-28 16:02:3728 days ago1740758557IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    Set Approval For...106530582025-02-28 1:43:2329 days ago1740707003IN
    0xD4aD5Ed9...36317C636
    0 S0.0032169466.3
    Set Approval For...106051632025-02-27 20:30:3829 days ago1740688238IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    Set Approval For...104996232025-02-27 9:59:2230 days ago1740650362IN
    0xD4aD5Ed9...36317C636
    0 S0.0014167255.01
    Set Approval For...103687352025-02-26 19:45:1330 days ago1740599113IN
    0xD4aD5Ed9...36317C636
    0 S0.0013364455
    Set Approval For...103685582025-02-26 19:44:0830 days ago1740599048IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    Set Approval For...100893862025-02-25 16:13:0831 days ago1740499988IN
    0xD4aD5Ed9...36317C636
    0 S0.0026686555
    Set Approval For...100697112025-02-25 14:23:2331 days ago1740493403IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    Set Approval For...100637872025-02-25 13:48:1531 days ago1740491295IN
    0xD4aD5Ed9...36317C636
    0 S0.0015807861.38
    Set Approval For...99022782025-02-24 21:51:2332 days ago1740433883IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    Set Approval For...96637392025-02-23 22:26:1333 days ago1740349573IN
    0xD4aD5Ed9...36317C636
    0 S0.002541655
    View all transactions

    Latest 25 internal transactions (View All)

    Parent Transaction Hash Block Age From To Amount
    167622892025-03-29 10:09:1228 mins ago1743242952
    0xD4aD5Ed9...36317C636
    85.87623661 S
    167585622025-03-29 9:45:3452 mins ago1743241534
    0xD4aD5Ed9...36317C636
    28.19973959 S
    167584292025-03-29 9:44:5253 mins ago1743241492
    0xD4aD5Ed9...36317C636
    57.67649701 S
    162591902025-03-27 5:04:232 days ago1743051863
    0xD4aD5Ed9...36317C636
    98.11229178 S
    161249352025-03-26 16:11:232 days ago1743005483
    0xD4aD5Ed9...36317C636
    16.9652113 S
    161161292025-03-26 15:22:202 days ago1743002540
    0xD4aD5Ed9...36317C636
    1.90908307 S
    161004952025-03-26 13:55:402 days ago1742997340
    0xD4aD5Ed9...36317C636
    82.74800137 S
    133527182025-03-13 0:43:3616 days ago1741826616
    0xD4aD5Ed9...36317C636
    0.13439 S
    133252992025-03-12 21:26:1516 days ago1741814775
    0xD4aD5Ed9...36317C636
    0.00000909 S
    132938032025-03-12 17:49:4516 days ago1741801785
    0xD4aD5Ed9...36317C636
    6.70172076 S
    132174812025-03-12 9:12:3317 days ago1741770753
    0xD4aD5Ed9...36317C636
    193.14390267 S
    132084312025-03-12 8:11:4817 days ago1741767108
    0xD4aD5Ed9...36317C636
    0.81471852 S
    131530932025-03-12 0:53:1617 days ago1741740796
    0xD4aD5Ed9...36317C636
    200 S
    131312482025-03-11 22:01:5317 days ago1741730513
    0xD4aD5Ed9...36317C636
    647.98974054 S
    131263552025-03-11 21:25:3917 days ago1741728339
    0xD4aD5Ed9...36317C636
    5.50447142 S
    131252612025-03-11 21:17:1517 days ago1741727835
    0xD4aD5Ed9...36317C636
    307.57459514 S
    131250972025-03-11 21:16:0017 days ago1741727760
    0xD4aD5Ed9...36317C636
    334.91067396 S
    128680832025-03-10 15:21:3118 days ago1741620091
    0xD4aD5Ed9...36317C636
    0.18803419 S
    127675362025-03-10 3:15:5819 days ago1741576558
    0xD4aD5Ed9...36317C636
    0.07580441 S
    127349092025-03-09 23:07:4919 days ago1741561669
    0xD4aD5Ed9...36317C636
    34.94073657 S
    127349092025-03-09 23:07:4919 days ago1741561669
    0xD4aD5Ed9...36317C636
    6.16601233 S
    127108512025-03-09 20:23:1719 days ago1741551797
    0xD4aD5Ed9...36317C636
    59.69405399 S
    125627202025-03-09 2:07:3820 days ago1741486058
    0xD4aD5Ed9...36317C636
    2.41655 S
    122983922025-03-07 16:36:5921 days ago1741365419
    0xD4aD5Ed9...36317C636
    0.123524 S
    122973952025-03-07 16:30:5421 days ago1741365054
    0xD4aD5Ed9...36317C636
    25.38746299 S
    View All Internal Transactions
    Loading...
    Loading

    Contract Source Code Verified (Exact Match)

    Contract Name:
    BookManager

    Compiler Version
    v0.8.25+commit.b61c2a91

    Optimization Enabled:
    Yes with 1000 runs

    Other Settings:
    cancun EvmVersion
    File 1 of 45 : BookManager.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: -
    // License: https://license.sonic.market/LICENSE.pdf
    pragma solidity ^0.8.20;
    import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol";
    import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
    import {IBookManager} from "./interfaces/IBookManager.sol";
    import {ILocker} from "./interfaces/ILocker.sol";
    import {IHooks} from "./interfaces/IHooks.sol";
    import {BookId, BookIdLibrary} from "./libraries/BookId.sol";
    import {Book} from "./libraries/Book.sol";
    import {Currency, CurrencyLibrary} from "./libraries/Currency.sol";
    import {FeePolicy, FeePolicyLibrary} from "./libraries/FeePolicy.sol";
    import {Tick, TickLibrary} from "./libraries/Tick.sol";
    import {OrderId, OrderIdLibrary} from "./libraries/OrderId.sol";
    import {Lockers} from "./libraries/Lockers.sol";
    import {CurrencyDelta} from "./libraries/CurrencyDelta.sol";
    import {ERC721Permit} from "./libraries/ERC721Permit.sol";
    import {Hooks} from "./libraries/Hooks.sol";
    contract BookManager is IBookManager, Ownable2Step, ERC721Permit {
    using SafeCast for *;
    using BookIdLibrary for IBookManager.BookKey;
    using TickLibrary for Tick;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 2 of 45 : Ownable.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
    pragma solidity ^0.8.20;
    import {Context} from "../utils/Context.sol";
    /**
    * @dev Contract module which provides a basic access control mechanism, where
    * there is an account (an owner) that can be granted exclusive access to
    * specific functions.
    *
    * The initial owner is set to the address provided by the deployer. This can
    * later be changed with {transferOwnership}.
    *
    * This module is used through inheritance. It will make available the modifier
    * `onlyOwner`, which can be applied to your functions to restrict their use to
    * the owner.
    */
    abstract contract Ownable is Context {
    address private _owner;
    /**
    * @dev The caller account is not authorized to perform an operation.
    */
    error OwnableUnauthorizedAccount(address account);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 3 of 45 : Ownable2Step.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)
    pragma solidity ^0.8.20;
    import {Ownable} from "./Ownable.sol";
    /**
    * @dev Contract module which provides access control mechanism, where
    * there is an account (an owner) that can be granted exclusive access to
    * specific functions.
    *
    * This extension of the {Ownable} contract includes a two-step mechanism to transfer
    * ownership, where the new owner must call {acceptOwnership} in order to replace the
    * old one. This can help prevent common mistakes, such as transfers of ownership to
    * incorrect accounts, or to contracts that are unable to interact with the
    * permission system.
    *
    * The initial owner is specified at deployment time in the constructor for `Ownable`. This
    * can later be changed with {transferOwnership} and {acceptOwnership}.
    *
    * This module is used through inheritance. It will make available all functions
    * from parent (Ownable).
    */
    abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 4 of 45 : draft-IERC6093.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Standard ERC-20 Errors
    * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
    */
    interface IERC20Errors {
    /**
    * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
    * @param sender Address whose tokens are being transferred.
    * @param balance Current balance for the interacting account.
    * @param needed Minimum amount required to perform a transfer.
    */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
    /**
    * @dev Indicates a failure with the token `sender`. Used in transfers.
    * @param sender Address whose tokens are being transferred.
    */
    error ERC20InvalidSender(address sender);
    /**
    * @dev Indicates a failure with the token `receiver`. Used in transfers.
    * @param receiver Address to which tokens are being transferred.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 5 of 45 : IERC1271.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1271.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Interface of the ERC-1271 standard signature validation method for
    * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
    */
    interface IERC1271 {
    /**
    * @dev Should return whether the signature provided is valid for the provided data
    * @param hash Hash of the data to be signed
    * @param signature Signature byte array associated with _data
    */
    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 6 of 45 : IERC5267.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)
    pragma solidity ^0.8.20;
    interface IERC5267 {
    /**
    * @dev MAY be emitted to signal that the domain could have changed.
    */
    event EIP712DomainChanged();
    /**
    * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
    * signature.
    */
    function eip712Domain()
    external
    view
    returns (
    bytes1 fields,
    string memory name,
    string memory version,
    uint256 chainId,
    address verifyingContract,
    bytes32 salt,
    uint256[] memory extensions
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 7 of 45 : IERC20.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Interface of the ERC-20 standard as defined in the ERC.
    */
    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 value of tokens in existence.
    */
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 8 of 45 : IERC721Metadata.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)
    pragma solidity ^0.8.20;
    import {IERC721} from "../IERC721.sol";
    /**
    * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
    * @dev See https://eips.ethereum.org/EIPS/eip-721
    */
    interface IERC721Metadata is IERC721 {
    /**
    * @dev Returns the token collection name.
    */
    function name() external view returns (string memory);
    /**
    * @dev Returns the token collection symbol.
    */
    function symbol() external view returns (string memory);
    /**
    * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
    */
    function tokenURI(uint256 tokenId) external view returns (string memory);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 9 of 45 : IERC721.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)
    pragma solidity ^0.8.20;
    import {IERC165} from "../../utils/introspection/IERC165.sol";
    /**
    * @dev Required interface of an ERC-721 compliant contract.
    */
    interface IERC721 is IERC165 {
    /**
    * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
    */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    /**
    * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
    */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    /**
    * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
    */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 10 of 45 : IERC721Receiver.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)
    pragma solidity ^0.8.20;
    /**
    * @title ERC-721 token receiver interface
    * @dev Interface for any contract that wants to support safeTransfers
    * from ERC-721 asset contracts.
    */
    interface IERC721Receiver {
    /**
    * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
    * by `operator` from `from`, this function is called.
    *
    * It must return its Solidity selector to confirm the token transfer.
    * If any other value is returned or the interface is not implemented by the recipient, the transfer will be
    * reverted.
    *
    * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
    */
    function onERC721Received(
    address operator,
    address from,
    uint256 tokenId,
    bytes calldata data
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 11 of 45 : Context.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Provides information about the current execution context, including the
    * sender of the transaction and its data. While these are generally available
    * via msg.sender and msg.data, they should not be accessed in such a direct
    * manner, since when dealing with meta-transactions the account sending and
    * paying for execution may not be the actual sender (as far as an application
    * is concerned).
    *
    * This contract is only required for intermediate, library-like contracts.
    */
    abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
    return msg.sender;
    }
    function _msgData() internal view virtual returns (bytes calldata) {
    return msg.data;
    }
    function _contextSuffixLength() internal view virtual returns (uint256) {
    return 0;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 12 of 45 : ECDSA.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
    *
    * These functions can be used to verify that a message was signed by the holder
    * of the private keys of a given address.
    */
    library ECDSA {
    enum RecoverError {
    NoError,
    InvalidSignature,
    InvalidSignatureLength,
    InvalidSignatureS
    }
    /**
    * @dev The signature derives the `address(0)`.
    */
    error ECDSAInvalidSignature();
    /**
    * @dev The signature has an invalid length.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 13 of 45 : EIP712.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)
    pragma solidity ^0.8.20;
    import {MessageHashUtils} from "./MessageHashUtils.sol";
    import {ShortStrings, ShortString} from "../ShortStrings.sol";
    import {IERC5267} from "../../interfaces/IERC5267.sol";
    /**
    * @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data.
    *
    * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose
    * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract
    * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to
    * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.
    *
    * This contract implements the EIP-712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
    * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
    * ({_hashTypedDataV4}).
    *
    * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
    * the chain id to protect against replay attacks on an eventual fork of the chain.
    *
    * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
    * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 14 of 45 : MessageHashUtils.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)
    pragma solidity ^0.8.20;
    import {Strings} from "../Strings.sol";
    /**
    * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.
    *
    * The library provides methods for generating a hash of a message that conforms to the
    * https://eips.ethereum.org/EIPS/eip-191[ERC-191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
    * specifications.
    */
    library MessageHashUtils {
    /**
    * @dev Returns the keccak256 digest of an ERC-191 signed data with version
    * `0x45` (`personal_sign` messages).
    *
    * The digest is calculated by prefixing a bytes32 `messageHash` with
    * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the
    * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
    *
    * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with
    * keccak256, although any bytes32 value can be safely used because the final digest will
    * be re-hashed.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 15 of 45 : ERC165.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
    pragma solidity ^0.8.20;
    import {IERC165} from "./IERC165.sol";
    /**
    * @dev Implementation of the {IERC165} interface.
    *
    * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
    * for the additional interface id that will be supported. For example:
    *
    * ```solidity
    * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
    * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
    * }
    * ```
    */
    abstract contract ERC165 is IERC165 {
    /**
    * @dev See {IERC165-supportsInterface}.
    */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
    return interfaceId == type(IERC165).interfaceId;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 16 of 45 : IERC165.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Interface of the ERC-165 standard, as defined in the
    * https://eips.ethereum.org/EIPS/eip-165[ERC].
    *
    * Implementers can declare support of contract interfaces, which can then be
    * queried by others ({ERC165Checker}).
    *
    * For an implementation, see {ERC165}.
    */
    interface IERC165 {
    /**
    * @dev Returns true if this contract implements the interface defined by
    * `interfaceId`. See the corresponding
    * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
    * to learn more about how these ids are created.
    *
    * This function call must use less than 30 000 gas.
    */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 17 of 45 : Math.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
    pragma solidity ^0.8.20;
    import {Panic} from "../Panic.sol";
    import {SafeCast} from "./SafeCast.sol";
    /**
    * @dev Standard math utilities missing in the Solidity language.
    */
    library Math {
    enum Rounding {
    Floor, // Toward negative infinity
    Ceil, // Toward positive infinity
    Trunc, // Toward zero
    Expand // Away from zero
    }
    /**
    * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).
    */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
    unchecked {
    uint256 c = a + b;
    if (c < a) return (false, 0);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 18 of 45 : SafeCast.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)
    // This file was procedurally generated from scripts/generate/templates/SafeCast.js.
    pragma solidity ^0.8.20;
    /**
    * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
    * checks.
    *
    * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
    * easily result in undesired exploitation or bugs, since developers usually
    * assume that overflows raise errors. `SafeCast` restores this intuition by
    * reverting the transaction when such an operation overflows.
    *
    * Using this library instead of the unchecked operations eliminates an entire
    * class of bugs, so it's recommended to use it always.
    */
    library SafeCast {
    /**
    * @dev Value doesn't fit in an uint of `bits` size.
    */
    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
    /**
    * @dev An int value doesn't fit in an uint of `bits` size.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 19 of 45 : SignedMath.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Standard signed math utilities missing in the Solidity language.
    */
    library SignedMath {
    /**
    * @dev Returns the largest of two signed numbers.
    */
    function max(int256 a, int256 b) internal pure returns (int256) {
    return a > b ? a : b;
    }
    /**
    * @dev Returns the smallest of two signed numbers.
    */
    function min(int256 a, int256 b) internal pure returns (int256) {
    return a < b ? a : b;
    }
    /**
    * @dev Returns the average of two signed numbers without overflow.
    * The result is rounded towards zero.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 20 of 45 : Panic.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    /**
    * @dev Helper library for emitting standardized panic codes.
    *
    * ```solidity
    * contract Example {
    * using Panic for uint256;
    *
    * // Use any of the declared internal constants
    * function foo() { Panic.GENERIC.panic(); }
    *
    * // Alternatively
    * function foo() { Panic.panic(Panic.GENERIC); }
    * }
    * ```
    *
    * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
    */
    // slither-disable-next-line unused-state
    library Panic {
    /// @dev generic / unspecified error
    uint256 internal constant GENERIC = 0x00;
    /// @dev used by the assert() builtin
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 21 of 45 : ShortStrings.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/ShortStrings.sol)
    pragma solidity ^0.8.20;
    import {StorageSlot} from "./StorageSlot.sol";
    // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
    // | length | 0x BB |
    type ShortString is bytes32;
    /**
    * @dev This library provides functions to convert short memory strings
    * into a `ShortString` type that can be used as an immutable variable.
    *
    * Strings of arbitrary length can be optimized using this library if
    * they are short enough (up to 31 bytes) by packing them with their
    * length (1 byte) in a single EVM word (32 bytes). Additionally, a
    * fallback mechanism can be used for every other case.
    *
    * Usage example:
    *
    * ```solidity
    * contract Named {
    * using ShortStrings for *;
    *
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 22 of 45 : StorageSlot.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
    // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
    pragma solidity ^0.8.24;
    /**
    * @dev Library for reading and writing primitive types to specific storage slots.
    *
    * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
    * This library helps with reading and writing to such slots without the need for inline assembly.
    *
    * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
    *
    * Example usage to set ERC-1967 implementation slot:
    * ```solidity
    * contract ERC1967 {
    * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
    * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    *
    * function _getImplementation() internal view returns (address) {
    * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
    * }
    *
    * function _setImplementation(address newImplementation) internal {
    * require(newImplementation.code.length > 0);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 23 of 45 : Strings.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
    pragma solidity ^0.8.20;
    import {Math} from "./math/Math.sol";
    import {SignedMath} from "./math/SignedMath.sol";
    /**
    * @dev String operations.
    */
    library Strings {
    bytes16 private constant HEX_DIGITS = "0123456789abcdef";
    uint8 private constant ADDRESS_LENGTH = 20;
    /**
    * @dev The `value` string doesn't fit in the specified `length`.
    */
    error StringsInsufficientHexLength(uint256 value, uint256 length);
    /**
    * @dev Converts a `uint256` to its ASCII `string` decimal representation.
    */
    function toString(uint256 value) internal pure returns (string memory) {
    unchecked {
    uint256 length = Math.log10(value) + 1;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 24 of 45 : IBookManager.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
    import {BookId} from "../libraries/BookId.sol";
    import {Currency} from "../libraries/Currency.sol";
    import {OrderId} from "../libraries/OrderId.sol";
    import {Tick} from "../libraries/Tick.sol";
    import {FeePolicy} from "../libraries/FeePolicy.sol";
    import {IERC721Permit} from "./IERC721Permit.sol";
    import {IHooks} from "./IHooks.sol";
    /**
    * @title IBookManager
    * @notice The interface for the BookManager contract
    */
    interface IBookManager is IERC721Metadata, IERC721Permit {
    error InvalidUnitSize();
    error InvalidFeePolicy();
    error InvalidProvider(address provider);
    error LockedBy(address locker, address hook);
    error CurrencyNotSettled();
    /**
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 25 of 45 : IERC721Permit.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
    /**
    * @title IERC721Permit
    * @notice An interface for the ERC721 permit extension
    */
    interface IERC721Permit is IERC721 {
    error InvalidSignature();
    error PermitExpired();
    /**
    * @notice The EIP-712 typehash for the permit struct used by the contract
    */
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    /**
    * @notice The EIP-712 domain separator for this contract
    */
    function DOMAIN_SEPARATOR() external view returns (bytes32);
    /**
    * @notice Approve the spender to transfer the given tokenId
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 26 of 45 : IHooks.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    import {IBookManager} from "./IBookManager.sol";
    import {OrderId} from "../libraries/OrderId.sol";
    /**
    * @title IHooks
    * @notice Interface for the hooks contract
    */
    interface IHooks {
    /**
    * @notice Hook called before opening a new book
    * @param sender The sender of the open transaction
    * @param key The key of the book being opened
    * @param hookData The data passed to the hook
    * @return Returns the function selector if the hook is successful
    */
    function beforeOpen(address sender, IBookManager.BookKey calldata key, bytes calldata hookData)
    external
    returns (bytes4);
    /**
    * @notice Hook called after opening a new book
    * @param sender The sender of the open transaction
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 27 of 45 : ILocker.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    /**
    * @title ILocker
    * @notice Interface for the locker contract
    */
    interface ILocker {
    /**
    * @notice Called by the book manager on `msg.sender` when a lock is acquired
    * @param data The data that was passed to the call to lock
    * @return Any data that you want to be returned from the lock call
    */
    function lockAcquired(address lockCaller, bytes calldata data) external returns (bytes memory);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 28 of 45 : Book.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: -
    // License: https://license.sonic.market/LICENSE.pdf
    pragma solidity ^0.8.20;
    import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
    import {IBookManager} from "../interfaces/IBookManager.sol";
    import {SegmentedSegmentTree} from "./SegmentedSegmentTree.sol";
    import {Tick, TickLibrary} from "./Tick.sol";
    import {OrderId, OrderIdLibrary} from "./OrderId.sol";
    import {TotalClaimableMap} from "./TotalClaimableMap.sol";
    import {TickBitmap} from "./TickBitmap.sol";
    library Book {
    using Book for State;
    using TickBitmap for mapping(uint256 => uint256);
    using SegmentedSegmentTree for SegmentedSegmentTree.Core;
    using TotalClaimableMap for mapping(uint24 => uint256);
    using TickLibrary for Tick;
    using OrderIdLibrary for OrderId;
    error ZeroUnit();
    error BookAlreadyOpened();
    error BookNotOpened();
    error QueueReplaceFailed();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 29 of 45 : BookId.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.20;
    import {IBookManager} from "../interfaces/IBookManager.sol";
    type BookId is uint192;
    library BookIdLibrary {
    function toId(IBookManager.BookKey memory bookKey) internal pure returns (BookId id) {
    bytes32 hash = keccak256(abi.encode(bookKey));
    assembly {
    id := and(hash, 0xffffffffffffffffffffffffffffffffffffffffffffffff)
    }
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 30 of 45 : Currency.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.20;
    import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    type Currency is address;
    /// @title CurrencyLibrary
    /// @dev This library allows for transferring and holding native tokens and ERC20 tokens
    library CurrencyLibrary {
    using CurrencyLibrary for Currency;
    /// @notice Thrown when a native transfer fails
    error NativeTransferFailed();
    /// @notice Thrown when an ERC20 transfer fails
    error ERC20TransferFailed();
    Currency public constant NATIVE = Currency.wrap(address(0));
    function transfer(Currency currency, address to, uint256 amount) internal {
    // implementation from
    // https://github.com/transmissions11/solmate/blob/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/SafeTransferLib.sol
    bool success;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 31 of 45 : CurrencyDelta.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8.0;
    import {Currency, CurrencyLibrary} from "./Currency.sol";
    library CurrencyDelta {
    // uint256(keccak256("CurrencyDelta")) + 1
    uint256 internal constant CURRENCY_DELTA_SLOT = 0x95b400a0305233758f18c75aa62cbbb5d6882951dd55f1407390ee7b6924e26f;
    function get(address locker, Currency currency) internal view returns (int256 delta) {
    assembly {
    mstore(0x14, currency)
    mstore(0x00, locker)
    delta := tload(keccak256(0x0c, 0x28))
    }
    }
    function add(address locker, Currency currency, int256 delta) internal returns (int256 result) {
    assembly {
    mstore(0x14, currency)
    mstore(0x00, locker)
    let slot := keccak256(0x0c, 0x28)
    result := add(tload(slot), delta)
    tstore(slot, result)
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 32 of 45 : DirtyUint64.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: -
    // License: https://license.sonic.market/LICENSE.pdf
    pragma solidity ^0.8.0;
    library DirtyUint64 {
    error DirtyUint64Error(uint256 errorCode);
    uint256 private constant _OVERFLOW_ERROR = 0;
    uint256 private constant _UNDERFLOW_ERROR = 1;
    function toDirtyUnsafe(uint64 cleanUint) internal pure returns (uint64 dirtyUint) {
    assembly {
    dirtyUint := add(cleanUint, 1)
    }
    }
    function toDirty(uint64 cleanUint) internal pure returns (uint64 dirtyUint) {
    assembly {
    dirtyUint := add(cleanUint, 1)
    }
    if (dirtyUint == 0) {
    revert DirtyUint64Error(_OVERFLOW_ERROR);
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 33 of 45 : ERC721.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)
    // Modified by Sonic Market Team
    pragma solidity ^0.8.20;
    import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
    import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
    import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
    import {Context} from "@openzeppelin/contracts/utils/Context.sol";
    import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
    import {IERC165, ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
    import {IERC721Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
    /**
    * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
    * the Metadata extension, but not including the Enumerable extension, which is available separately as
    * {ERC721Enumerable}.
    */
    abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
    using Strings for uint256;
    // Token name
    string private _name;
    // Token symbol
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 34 of 45 : ERC721Permit.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.0;
    import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
    import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
    import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
    import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
    import {ERC721} from "./ERC721.sol";
    import {IERC721Permit} from "../interfaces/IERC721Permit.sol";
    contract ERC721Permit is ERC721, IERC721Permit, EIP712 {
    // keccak256("Permit(address spender,uint256 tokenId,uint256 nonce,uint256 deadline)");
    bytes32 public constant override PERMIT_TYPEHASH =
    0x49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad;
    uint256 private constant _NONCE_MASK = uint256(0xffffffffffffffffffffffff) << 160;
    // @dev tokenId => (nonce << 160 | owner)
    mapping(uint256 => uint256) private _nonceAndOwner;
    constructor(string memory name_, string memory symbol_, string memory version_)
    ERC721(name_, symbol_)
    EIP712(name_, version_)
    {}
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 35 of 45 : FeePolicy.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.20;
    import {Math} from "./Math.sol";
    type FeePolicy is uint24;
    library FeePolicyLibrary {
    uint256 internal constant RATE_PRECISION = 10 ** 6;
    int256 internal constant MAX_FEE_RATE = 500000;
    int256 internal constant MIN_FEE_RATE = -500000;
    uint256 internal constant RATE_MASK = 0x7fffff; // 23 bits
    error InvalidFeePolicy();
    function encode(bool usesQuote_, int24 rate_) internal pure returns (FeePolicy feePolicy) {
    if (rate_ > MAX_FEE_RATE || rate_ < MIN_FEE_RATE) {
    revert InvalidFeePolicy();
    }
    uint256 mask = usesQuote_ ? 1 << 23 : 0;
    assembly {
    feePolicy := or(mask, add(and(rate_, 0xffffff), MAX_FEE_RATE))
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 36 of 45 : Hooks.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    import {Lockers} from "./Lockers.sol";
    import {IBookManager} from "../interfaces/IBookManager.sol";
    import {IHooks} from "../interfaces/IHooks.sol";
    import {OrderId} from "../libraries/OrderId.sol";
    /// @author Sonic Market
    /// @author Modified from Uniswap V4 (https://github.com/Uniswap/v4-core/blob/1f350fa95e862ba8c56c8ff7e146d47c9043465e)
    /// @notice V4 decides whether to invoke specific hooks by inspecting the leading bits of the address that
    /// the hooks contract is deployed to.
    /// For example, a hooks contract deployed to address: 0x9000000000000000000000000000000000000000
    /// has leading bits '1001' which would cause the 'before open' and 'after make' hooks to be used.
    library Hooks {
    using Hooks for IHooks;
    uint256 internal constant BEFORE_OPEN_FLAG = 1 << 159;
    uint256 internal constant AFTER_OPEN_FLAG = 1 << 158;
    uint256 internal constant BEFORE_MAKE_FLAG = 1 << 157;
    uint256 internal constant AFTER_MAKE_FLAG = 1 << 156;
    uint256 internal constant BEFORE_TAKE_FLAG = 1 << 155;
    uint256 internal constant AFTER_TAKE_FLAG = 1 << 154;
    uint256 internal constant BEFORE_CANCEL_FLAG = 1 << 153;
    uint256 internal constant AFTER_CANCEL_FLAG = 1 << 152;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 37 of 45 : Lockers.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: BUSL-1.1
    pragma solidity ^0.8.23;
    import {IHooks} from "../interfaces/IHooks.sol";
    /// @author Sonic Market
    /// @author Modified from Uniswap V4 (https://github.com/Uniswap/v4-core/tree/98680ebc1a654120e995d53a5b10ec6fe153066f)
    /// @notice Contains data about pool lockers.
    /// @dev This library manages a custom storage implementation for a queue
    /// that tracks current lockers. The "sentinel" storage slot for this data structure,
    /// always passed in as IPoolManager.LockData storage self, stores not just the current
    /// length of the queue but also the global count of non-zero deltas across all lockers.
    /// The values of the data structure start at OFFSET, and each value is a locker address.
    library Lockers {
    /// struct LockData {
    /// /// @notice The current number of active lockers
    /// uint128 length;
    /// /// @notice The total number of nonzero deltas over all active + completed lockers
    /// uint128 nonzeroDeltaCount;
    /// }
    // uint256(keccak256("LockData")) + 1
    uint256 internal constant LOCK_DATA_SLOT = 0x760a9a962ae3d184e99c0483cf5684fb3170f47116ca4f445c50209da4f4f907;
    // uint256(keccak256("Lockers")) + 1
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 38 of 45 : Math.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.0;
    library Math {
    function divide(uint256 a, uint256 b, bool roundingUp) internal pure returns (uint256 ret) {
    // In the OrderBook contract code, b is never zero.
    assembly {
    ret := add(div(a, b), and(gt(mod(a, b), 0), roundingUp))
    }
    }
    /// @dev Returns `ln(x)`, denominated in `WAD`.
    /// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln
    function lnWad(int256 x) internal pure returns (int256 r) {
    /// @solidity memory-safe-assembly
    assembly {
    // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.
    // We do this by multiplying by `2**96 / 10**18`. But since
    // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here
    // and add `ln(2**96 / 10**18)` at the end.
    // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.
    r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
    r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
    r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 39 of 45 : OrderId.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.0;
    import {Tick} from "./Tick.sol";
    import {BookId} from "./BookId.sol";
    type OrderId is uint256;
    library OrderIdLibrary {
    /**
    * @dev Encode the order id.
    * @param bookId The book id.
    * @param tick The tick.
    * @param index The index.
    * @return id The order id.
    */
    function encode(BookId bookId, Tick tick, uint40 index) internal pure returns (OrderId id) {
    // @dev If we just use tick at the assembly code, the code will convert tick into bytes32.
    // e.g. When index == -2, the shifted value( shl(40, tick) ) will be
    // 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000 instead of 0xfffffffe0000000000
    // Therefore, we have to safely cast tick into uint256 first.
    uint256 _tick = uint256(uint24(Tick.unwrap(tick)));
    assembly {
    id := add(index, add(shl(40, _tick), shl(64, bookId)))
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 40 of 45 : PackedUint256.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: -
    // License: https://license.sonic.market/LICENSE.pdf
    pragma solidity ^0.8.0;
    library PackedUint256 {
    error PackedUint256Error(uint256 errorCode);
    uint256 private constant _UINT8_INDEX_ERROR = 0;
    uint256 private constant _UINT16_INDEX_ERROR = 1;
    uint256 private constant _UINT32_INDEX_ERROR = 2;
    uint256 private constant _UINT64_INDEX_ERROR = 3;
    uint256 private constant _MAX_UINT64 = type(uint64).max;
    uint256 private constant _MAX_UINT32 = type(uint32).max;
    uint256 private constant _MAX_UINT16 = type(uint16).max;
    uint256 private constant _MAX_UINT8 = type(uint8).max;
    function get8Unsafe(uint256 packed, uint256 index) internal pure returns (uint8 ret) {
    assembly {
    ret := and(shr(shl(3, index), packed), 0xff)
    }
    }
    function get8(uint256 packed, uint256 index) internal pure returns (uint8 ret) {
    if (index > 31) {
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 41 of 45 : SegmentedSegmentTree.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: -
    // License: https://license.sonic.market/LICENSE.pdf
    pragma solidity ^0.8.0;
    import "./PackedUint256.sol";
    import "./DirtyUint64.sol";
    /**
    * 🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲🌲
    *
    * Segmented Segment Tree
    * by Sonic Market
    *
    * ____________/\\\_______________/\\\\\____________/\\\____
    * __________/\\\\\___________/\\\\////___________/\\\\\____
    * ________/\\\/\\\________/\\\///______________/\\\/\\\____
    * ______/\\\/\/\\\______/\\\\\\\\\\\_________/\\\/\/\\\____
    * ____/\\\/__\/\\\_____/\\\\///////\\\_____/\\\/__\/\\\____
    * __/\\\\\\\\\\\\\\\\_\/\\\______\//\\\__/\\\\\\\\\\\\\\\\_
    * _\///////////\\\//__\//\\\______/\\\__\///////////\\\//__
    * ___________\/\\\_____\///\\\\\\\\\/_____________\/\\\____
    * ___________\///________\/////////_______________\///_____
    *
    * 4 Layers of 64-bit nodes, hence 464
    *
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 42 of 45 : SignificantBit.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.0;
    library SignificantBit {
    // http://supertech.csail.mit.edu/papers/debruijn.pdf
    uint256 internal constant DEBRUIJN_SEQ = 0x818283848586878898A8B8C8D8E8F929395969799A9B9D9E9FAAEB6BEDEEFF;
    bytes internal constant DEBRUIJN_INDEX =
    hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c90717273743
                53637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff081018202830384044
                4c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7
                bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8";
    /**
    * @notice Finds the index of the least significant bit.
    * @param x The value to compute the least significant bit for. Must be a non-zero value.
    * @return ret The index of the least significant bit.
    */
    function leastSignificantBit(uint256 x) internal pure returns (uint8) {
    require(x > 0);
    uint256 index;
    assembly {
    index := shr(248, mul(and(x, add(not(x), 1)), DEBRUIJN_SEQ))
    }
    return uint8(DEBRUIJN_INDEX[index]); // can optimize with CODECOPY opcode
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 43 of 45 : Tick.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.20;
    import {Math} from "./Math.sol";
    type Tick is int24;
    library TickLibrary {
    using Math for *;
    using TickLibrary for Tick;
    error InvalidTick();
    error InvalidPrice();
    error TickOverflow();
    int24 internal constant MAX_TICK = 2 ** 19 - 1;
    int24 internal constant MIN_TICK = -MAX_TICK;
    uint256 internal constant MIN_PRICE = 1350587;
    uint256 internal constant MAX_PRICE = 4647684107270898330752324302845848816923571339324334;
    uint256 private constant _R0 = 0xfff97272373d413259a46990;
    uint256 private constant _R1 = 0xfff2e50f5f656932ef12357c;
    uint256 private constant _R2 = 0xffe5caca7e10e4e61c3624ea;
    uint256 private constant _R3 = 0xffcb9843d60f6159c9db5883;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 44 of 45 : TickBitmap.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: -
    // License: https://license.sonic.market/LICENSE.pdf
    pragma solidity ^0.8.0;
    import {SignificantBit} from "./SignificantBit.sol";
    import {Tick} from "./Tick.sol";
    library TickBitmap {
    using SignificantBit for uint256;
    error EmptyError();
    error AlreadyExistsError();
    uint256 public constant B0_BITMAP_KEY = uint256(keccak256("TickBitmap")) + 1;
    uint256 public constant MAX_UINT_256_MINUS_1 = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe;
    function has(mapping(uint256 => uint256) storage self, Tick tick) internal view returns (bool) {
    (uint256 b0b1, uint256 b2) = _split(tick);
    uint256 mask = 1 << b2;
    return self[b0b1] & mask == mask;
    }
    function isEmpty(mapping(uint256 => uint256) storage self) internal view returns (bool) {
    return self[B0_BITMAP_KEY] == 0;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 45 of 45 : TotalClaimableMap.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: -
    // License: https://license.sonic.market/LICENSE.pdf
    pragma solidity ^0.8.20;
    import {DirtyUint64} from "./DirtyUint64.sol";
    import {PackedUint256} from "./PackedUint256.sol";
    import {Tick} from "./Tick.sol";
    library TotalClaimableMap {
    using DirtyUint64 for uint64;
    using PackedUint256 for uint256;
    // @dev n should be less than type(uint64).max due to the dirty storage logic.
    function add(mapping(uint24 => uint256) storage self, Tick tick, uint64 n) internal {
    (uint24 groupIndex, uint8 elementIndex) = _splitTick(tick);
    uint256 group = self[groupIndex];
    // @notice Be aware of dirty storage add logic
    self[groupIndex] = group.update64Unsafe(
    elementIndex, // elementIndex < 4
    group.get64Unsafe(elementIndex).addClean(n)
    );
    }
    function sub(mapping(uint24 => uint256) storage self, Tick tick, uint64 n) internal {
    (uint24 groupIndex, uint8 elementIndex) = _splitTick(tick);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Settings
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    {
    "evmVersion": "cancun",
    "optimizer": {
    "enabled": true,
    "runs": 1000
    },
    "outputSelection": {
    "*": {
    "*": [
    "evm.bytecode",
    "evm.deployedBytecode",
    "devdoc",
    "userdoc",
    "metadata",
    "abi"
    ]
    }
    },
    "metadata": {
    "useLiteralContent": true
    },
    "libraries": {
    "src/libraries/Book.sol": {
    "Book": "0x5489922f8312c812fbb7184ebf70b9dbfaeed9d4"
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Contract Security Audit

    Contract ABI

    API
    [{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"defaultProvider_","type":"address"},{"internalType":"string","name":"baseURI_","type":"string"},{"internalType":"string","name":"contractURI_","type":"string"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BookNotOpened","type":"error"},{"inputs":[],"name":"CurrencyNotSettled","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[],"name":"ERC20TransferFailed","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"EmptyError","type":"error"},{"inputs":[],"name":"FailedHookCall","type":"error"},{"inputs":[{"internalType":"address","name":"hooks","type":"address"}],"name":"HookAddressNotValid","type":"error"},{"inputs":[],"name":"InvalidFeePolicy","type":"error"},{"inputs":[],"name":"InvalidHookResponse","type":"error"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"InvalidProvider","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidTick","type":"error"},{"inputs":[],"name":"InvalidUnitSize","type":"error"},{"inputs":[{"internalType":"address","name":"locker","type":"address"},{"internalType":"address","name":"hook","type":"address"}],"name":"LockedBy","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"PermitExpired","type":"error"},{"inputs":[{"internalType":"int256","name":"value","type":"int256"}],"name":"SafeCastOverflowedIntToUint","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintToInt","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"OrderId","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"}],"name":"Cancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"OrderId","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"Currency","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Collect","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"}],"name":"Delist","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"BookId","name":"bookId","type":"uint192"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"Tick","name":"tick","type":"int24"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"},{"indexed":false,"internalType":"address","name":"provider","type":"address"}],"name":"Make","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"BookId","name":"id","type":"uint192"},{"indexed":true,"internalType":"Currency","name":"base","type":"address"},{"indexed":true,"internalType":"Currency","name":"quote","type":"address"},{"indexed":false,"internalType":"uint64","name":"unitSize","type":"uint64"},{"indexed":false,"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"indexed":false,"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"},{"indexed":false,"internalType":"contract IHooks","name":"hooks","type":"address"}],"name":"Open","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newDefaultProvider","type":"address"}],"name":"SetDefaultProvider","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"BookId","name":"bookId","type":"uint192"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"Tick","name":"tick","type":"int24"},{"indexed":false,"internalType":"uint64","name":"unit","type":"uint64"}],"name":"Take","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"}],"name":"Whitelist","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"OrderId","name":"id","type":"uint256"},{"internalType":"uint64","name":"toUnit","type":"uint64"}],"internalType":"struct IBookManager.CancelParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"cancel","outputs":[{"internalType":"uint256","name":"canceledAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"checkAuthorized","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"OrderId","name":"id","type":"uint256"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"claim","outputs":[{"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"Currency","name":"currency","type":"address"}],"name":"collect","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"delist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"}],"name":"encodeBookKey","outputs":[{"internalType":"BookId","name":"","type":"uint192"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"getBookKey","outputs":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"locker","type":"address"},{"internalType":"Currency","name":"currency","type":"address"}],"name":"getCurrencyDelta","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"},{"internalType":"Tick","name":"tick","type":"int24"}],"name":"getDepth","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"getHighest","outputs":[{"internalType":"Tick","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"i","type":"uint256"}],"name":"getLock","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLockData","outputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"OrderId","name":"id","type":"uint256"}],"name":"getOrder","outputs":[{"components":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"uint64","name":"open","type":"uint64"},{"internalType":"uint64","name":"claimable","type":"uint64"}],"internalType":"struct IBookManager.OrderInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"isEmpty","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"}],"name":"isOpened","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"load","outputs":[{"internalType":"bytes32","name":"value","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"startSlot","type":"bytes32"},{"internalType":"uint256","name":"nSlot","type":"uint256"}],"name":"load","outputs":[{"internalType":"bytes","name":"value","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"locker","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"lock","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"},{"internalType":"Tick","name":"tick","type":"int24"},{"internalType":"uint64","name":"unit","type":"uint64"},{"internalType":"address","name":"provider","type":"address"}],"internalType":"struct IBookManager.MakeParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"make","outputs":[{"internalType":"OrderId","name":"id","type":"uint256"},{"internalType":"uint256","name":"quoteAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"BookId","name":"id","type":"uint192"},{"internalType":"Tick","name":"tick","type":"int24"}],"name":"maxLessThan","outputs":[{"internalType":"Tick","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"open","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Currency","name":"currency","type":"address"}],"name":"reservesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDefaultProvider","type":"address"}],"name":"setDefaultProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Currency","name":"currency","type":"address"}],"name":"settle","outputs":[{"internalType":"uint256","name":"paid","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"Currency","name":"base","type":"address"},{"internalType":"uint64","name":"unitSize","type":"uint64"},{"internalType":"Currency","name":"quote","type":"address"},{"internalType":"FeePolicy","name":"makerPolicy","type":"uint24"},{"internalType":"contract IHooks","name":"hooks","type":"address"},{"internalType":"FeePolicy","name":"takerPolicy","type":"uint24"}],"internalType":"struct IBookManager.BookKey","name":"key","type":"tuple"},{"internalType":"Tick","name":"tick","type":"int24"},{"internalType":"uint64","name":"maxUnit","type":"uint64"}],"internalType":"struct IBookManager.TakeParams","name":"params","type":"tuple"},{"internalType":"bytes","name":"hookData","type":"bytes"}],"name":"take","outputs":[{"internalType":"uint256","name":"quoteAmount","type":"uint256"},{"internalType":"uint256","name":"baseAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"Currency","name":"currency","type":"address"}],"name":"tokenOwed","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"Currency","name":"currency","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

    610160604052348015610010575f80fd5b5060405161625738038061625783398101604081905261002f91610361565b6040805180820190915260018152601960f91b60208201528290829082818a82855f61005b83826104aa565b50600161006882826104aa565b5050506001600160a01b03811661009957604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6100a281610185565b506100ae8260076101a1565b610120526100bd8160086101a1565b61014052815160208084019190912060e052815190820120610100524660a05261014960e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b60805250503060c0525061016091508690506101d3565b600a61016c85826104aa565b50600b61017984826104aa565b505050505050506105c1565b600680546001600160a01b031916905561019e8161021c565b50565b5f6020835110156101bc576101b58361026d565b90506101cd565b816101c784826104aa565b5060ff90505b92915050565b600c80546001600160a01b0319166001600160a01b0383169081179091556040517fef673bbfc2ac7e4d4b810bffda0b15a1f2b48c2aa4d178d3fca87d0d1f337062905f90a250565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f80829050601f81511115610297578260405163305a27a960e01b81526004016100909190610569565b80516102a28261059e565b179392505050565b80516001600160a01b03811681146102c0575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126102e8575f80fd5b81516001600160401b0380821115610302576103026102c5565b604051601f8301601f19908116603f0116810190828211818310171561032a5761032a6102c5565b81604052838152866020858801011115610342575f80fd5b8360208701602083015e5f602085830101528094505050505092915050565b5f805f805f8060c08789031215610376575f80fd5b61037f876102aa565b955061038d602088016102aa565b60408801519095506001600160401b03808211156103a9575f80fd5b6103b58a838b016102d9565b955060608901519150808211156103ca575f80fd5b6103d68a838b016102d9565b945060808901519150808211156103eb575f80fd5b6103f78a838b016102d9565b935060a089015191508082111561040c575f80fd5b5061041989828a016102d9565b9150509295509295509295565b600181811c9082168061043a57607f821691505b60208210810361045857634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156104a557805f5260205f20601f840160051c810160208510156104835750805b601f840160051c820191505b818110156104a2575f815560010161048f565b50505b505050565b81516001600160401b038111156104c3576104c36102c5565b6104d7816104d18454610426565b8461045e565b602080601f83116001811461050a575f84156104f35750858301515b5f19600386901b1c1916600185901b178555610561565b5f85815260208120601f198616915b8281101561053857888601518255948401946001909101908401610519565b508582101561055557878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80516020808301519190811015610458575f1960209190910360031b1b16919050565b60805160a05160c05160e051610100516101205161014051615c456106125f395f6136d301525f6136a601525f61313b01525f61311301525f61306e01525f61309801525f6130c20152615c455ff3fe608060405260043610610353575f3560e01c80637ac2ff7b116101bd578063cdc92f2d116100f2578063e8a3d48511610092578063f2fde38b1161006d578063f2fde38b14610bd5578063f86a11b314610bf4578063fcc8fc9b14610c13578063fefc7c5114610c32575f80fd5b8063e8a3d48514610b5c578063e985e9c514610b70578063f035079914610bb7575f80fd5b8063d83747e8116100cd578063d83747e814610ae2578063d9caed1214610b01578063de4478ec14610b20578063e30c397814610b3f575f80fd5b8063cdc92f2d146109dd578063d09ef241146109fc578063d68f4dd114610a58575f80fd5b80639b22917d1161015d578063a179dadc11610138578063a179dadc1461094e578063a22cb46514610980578063b88d4fde1461099f578063c87b56dd146109be575f80fd5b80639b22917d146108335780639ca1799814610910578063a12ef25e1461092f575f80fd5b806393c85a211161019857806393c85a21146107b657806395d89b41146107e15780639611cf6c146107f55780639b19251a14610814575f80fd5b80637ac2ff7b1461075357806384b0196e146107725780638da5cb5b14610799575f80fd5b80633af32abf116102935780636352211e116102335780636c0360eb1161020e5780636c0360eb146106f857806370a082311461070c578063715018a61461072b57806379ba50971461073f575f80fd5b80636352211e146106a75780636a256b29146106c65780636b2cc75c146106d9575f80fd5b806341a8bb881161026e57806341a8bb88146105f857806342842e0e146106305780634c02bf0b1461064f57806355af6a3214610688575f80fd5b80633af32abf146105755780633b9500b0146105a35780633e547b06146105c2575f80fd5b80631dbef488116102fe5780632f584a6d116102d95780632f584a6d146104f057806330adf81f1461050f5780633644e5151461054257806338926b6d14610556575f80fd5b80631dbef488146104665780631ff63f931461049a57806323b872dd146104d1575f80fd5b8063095ea7b31161032e578063095ea7b3146103ea578063141a468c1461040b57806314d6a9eb14610447575f80fd5b806301ffc9a71461035e57806306fdde0314610392578063081812fc146103b3575f80fd5b3661035a57005b5f80fd5b348015610369575f80fd5b5061037d610378366004614ac4565b610c51565b60405190151581526020015b60405180910390f35b34801561039d575f80fd5b506103a6610c94565b6040516103899190614b0d565b3480156103be575f80fd5b506103d26103cd366004614b1f565b610d23565b6040516001600160a01b039091168152602001610389565b3480156103f5575f80fd5b50610409610404366004614b4a565b610d4a565b005b348015610416575f80fd5b50610439610425366004614b1f565b5f9081526009602052604090205460a01c90565b604051908152602001610389565b348015610452575f80fd5b50610439610461366004614bb9565b610d59565b348015610471575f80fd5b50610485610480366004614c0f565b610f9a565b60408051928352602083019190915201610389565b3480156104a5575f80fd5b506104b96104b4366004614c5e565b61138b565b6040516001600160c01b039091168152602001610389565b3480156104dc575f80fd5b506104096104eb366004614c78565b61139e565b3480156104fb575f80fd5b5061040961050a366004614c78565b611440565b34801561051a575f80fd5b506104397f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad81565b34801561054d575f80fd5b50610439611450565b348015610561575f80fd5b50610439610570366004614cb6565b61145e565b348015610580575f80fd5b5061037d61058f366004614ce5565b600f6020525f908152604090205460ff1681565b3480156105ae575f80fd5b506104856105bd366004614d00565b611821565b3480156105cd575f80fd5b506104396105dc366004614d23565b601060209081525f928352604080842090915290825290205481565b348015610603575f80fd5b50610617610612366004614d81565b611aea565b60405167ffffffffffffffff9091168152602001610389565b34801561063b575f80fd5b5061040961064a366004614c78565b611b12565b34801561065a575f80fd5b50604080515f80516020615af08339815191525c6001600160801b038116825260801c602082015201610389565b348015610693575f80fd5b5061037d6106a2366004614db2565b611b2c565b3480156106b2575f80fd5b506103d26106c1366004614b1f565b611b5c565b6104396106d4366004614ce5565b611b66565b3480156106e4575f80fd5b506104096106f3366004614ce5565b611bcc565b348015610703575f80fd5b506103a6611c1c565b348015610717575f80fd5b50610439610726366004614ce5565b611ca8565b348015610736575f80fd5b50610409611d06565b34801561074a575f80fd5b50610409611d19565b34801561075e575f80fd5b5061040961076d366004614dcb565b611d5d565b34801561077d575f80fd5b50610786611fbe565b6040516103899796959493929190614e28565b3480156107a4575f80fd5b506005546001600160a01b03166103d2565b3480156107c1575f80fd5b506104396107d0366004614ce5565b600d6020525f908152604090205481565b3480156107ec575f80fd5b506103a661201c565b348015610800575f80fd5b5061043961080f366004614d23565b61202b565b34801561081f575f80fd5b5061040961082e366004614ce5565b61203f565b34801561083e575f80fd5b5061090361084d366004614db2565b6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160c01b03165f908152600e6020908152604091829020825160c08101845281546001600160a01b03808216835267ffffffffffffffff600160a01b92839004169483019490945260018301548085169583019590955262ffffff94819004851660608301526002909201549283166080820152910490911660a082015290565b6040516103899190614edb565b34801561091b575f80fd5b506103a661092a366004614f42565b612092565b34801561093a575f80fd5b50610439610949366004614d23565b6121a6565b348015610959575f80fd5b5061096d610968366004614d81565b61225d565b60405160029190910b8152602001610389565b34801561098b575f80fd5b5061040961099a366004614f7a565b61227e565b3480156109aa575f80fd5b506104096109b9366004615016565b612289565b3480156109c9575f80fd5b506103a66109d8366004614b1f565b6122a0565b3480156109e8575f80fd5b5061096d6109f7366004614db2565b612304565b348015610a07575f80fd5b50610a1b610a16366004614b1f565b612324565b6040805182516001600160a01b0316815260208084015167ffffffffffffffff908116918301919091529282015190921690820152606001610389565b348015610a63575f80fd5b50610ac2610a72366004614b1f565b6002027f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b181015c917f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b29091015c90565b604080516001600160a01b03938416815292909116602083015201610389565b348015610aed575f80fd5b50600c546103d2906001600160a01b031681565b348015610b0c575f80fd5b50610409610b1b366004614c78565b612468565b348015610b2b575f80fd5b50610409610b3a366004614ce5565b6124ce565b348015610b4a575f80fd5b506006546001600160a01b03166103d2565b348015610b67575f80fd5b506103a66124df565b348015610b7b575f80fd5b5061037d610b8a366004614d23565b6001600160a01b039182165f90815260046020908152604080832093909416825291909152205460ff1690565b348015610bc2575f80fd5b50610439610bd1366004614b1f565b5490565b348015610be0575f80fd5b50610409610bef366004614ce5565b6124ec565b348015610bff575f80fd5b506103a6610c0e3660046150be565b61255d565b348015610c1e575f80fd5b5061037d610c2d366004614db2565b6125d9565b348015610c3d575f80fd5b50610409610c4c3660046150de565b6125f9565b5f6001600160e01b031982167f6831a4fd000000000000000000000000000000000000000000000000000000001480610c8e5750610c8e82612966565b92915050565b60605f8054610ca290615115565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90615115565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050505050905090565b5f610d2d82612a00565b505f828152600360205260409020546001600160a01b0316610c8e565b610d55828233612a38565b5050565b5f610d6333612a45565b610d84610d7c85355f9081526009602052604090205490565b338635612b06565b8335604090811c5f908152600e602090815290829020825160c08101845281546001600160a01b03808216835267ffffffffffffffff600160a01b92839004169483019490945260018301548085169583019590955262ffffff9481900485166060830152600283015493841660808301819052930490931660a08401529190610e1090878787612b83565b5f80735489922f8312c812fbb7184ebf70b9dbfaeed9d4633ac502c1858a35610e3f60408d0160208e0161515c565b6040516001600160e01b031960e086901b1681526004810193909352602483019190915267ffffffffffffffff1660448201526064016040805180830381865af4158015610e8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eb39190615177565b91509150826020015167ffffffffffffffff168267ffffffffffffffff16029450610ee7836060015162ffffff1660171c90565b15610f0b5760608301515f90610f049062ffffff16876001612c03565b9590950194505b8067ffffffffffffffff165f03610f2657610f268835612c83565b610f34836040015186612cbb565b60405167ffffffffffffffff831681528835907f0c6ba7ef5064094c17cce013aa4c617a23e2582f867774d07a5931de43b85d729060200160405180910390a26080830151610f8f906001600160a01b031689848a8a612d02565b505050509392505050565b5f80610fa533612a45565b5f610fb861012087016101008801614ce5565b6001600160a01b031614158015610ffd5750600f5f610fdf61012088016101008901614ce5565b6001600160a01b0316815260208101919091526040015f205460ff16155b156110575761101461012086016101008701614ce5565b6040517f962715990000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b61107261106a60e0870160c088016151a4565b60020b612d8b565b5f61108a61108536889003880188615277565b612de7565b6001600160c01b0381165f908152600e602052604090209091506110ad81612e22565b6110e26110bf36899003890189615291565b87876110d160a08c0160808d01614ce5565b6001600160a01b0316929190612e6b565b5f735489922f8312c812fbb7184ebf70b9dbfaeed9d463ffa0afb58361110e60e08c0160c08d016151a4565b61111f6101008d0160e08e0161515c565b6111316101208e016101008f01614ce5565b6040516001600160e01b031960e087901b168152600481019490945260029290920b602484015267ffffffffffffffff1660448301526001600160a01b03166064820152608401602060405180830381865af4158015611193573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b79190615313565b90506111e9836111cd60e08b0160c08c016151a4565b60409190911b60289190911b67ffffff00000000001601820190565b94505f6111fc60408a0160208b0161515c565b67ffffffffffffffff166112176101008b0160e08c0161515c565b67ffffffffffffffff1602945084905061124561123a60808b0160608c01615337565b62ffffff1660171c90565b156112705761126b855f61125f60808d0160608e01615337565b62ffffff169190612c03565b019350835b61129161128360608b0160408c01614ce5565b61128c83615364565b612cbb565b61129b3387612ea9565b336001600160c01b0385167f251db4df45fa692f68b4e3f072919384c5b71995c71bf22888385168930fd22a6112d760e08d0160c08e016151a4565b858d60e00160208101906112eb919061515c565b8e6101000160208101906112ff9190614ce5565b6040805160029590950b855264ffffffffff93909316602085015267ffffffffffffffff91909116838301526001600160a01b03166060830152519081900360800190a361137f611355368b90038b018b615291565b878a8a8d5f01608001602081019061136d9190614ce5565b6001600160a01b031693929190612f23565b50505050935093915050565b5f610c8e61108536849003840184615277565b6001600160a01b0382166113c757604051633250574960e11b81525f600482015260240161104e565b5f6113d3838333612f63565b9050836001600160a01b0316816001600160a01b03161461143a576040517f64283d7b0000000000000000000000000000000000000000000000000000000081526001600160a01b038086166004830152602482018490528216604482015260640161104e565b50505050565b61144b838383612b06565b505050565b5f611459613062565b905090565b5f61146833612a45565b5f84815260096020526040902054611481903386612b06565b604084811c5f908152600e602090815290829020825160c08101845281546001600160a01b03808216835267ffffffffffffffff600160a01b92839004169483019490945260018301548085169583019590955262ffffff94819004851660608301526002830154938416608083018190529304841660a0820152602888901c9093169264ffffffffff88169261151a9089898961318b565b6040517fc49d262100000000000000000000000000000000000000000000000000000000815260048101839052600285900b602482015264ffffffffff841660448201525f90735489922f8312c812fbb7184ebf70b9dbfaeed9d49063c49d262190606401602060405180830381865af415801561159a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115be919061539a565b60208301519091505f90819067ffffffffffffffff8085169116026115e8600289900b82846131c8565b606086015160a0870151919a509061160562ffffff821660171c90565b156116225761161b62ffffff8216846001612c03565b9450611636565b61163362ffffff82168c6001612c03565b93505b6116458262ffffff1660171c90565b1561166c5761165b62ffffff8316846001612c03565b61166590866153b5565b94506116b8565b5f61167d62ffffff84168d83612c03565b905061168981866153b5565b94505f81136116aa5761169b81615364565b6116a5908d6153dc565b6116b4565b6116b4818d6153ef565b9b50505b505f91506116c990508689896131f2565b80519091506001600160a01b0381166116ea5750600c546001600160a01b03165b5f84131561173b576116fb84613246565b6001600160a01b038083165f9081526010602090815260408083208b820151909416835292905290812080549091906117359084906153dc565b90915550505b5f83131561178a5761174c83613246565b6001600160a01b038083165f9081526010602090815260408083208b51909416835292905290812080549091906117849084906153dc565b90915550505b816020015167ffffffffffffffff165f036117a8576117a88d612c83565b85516117b79061128c8c613288565b60405167ffffffffffffffff861681528d907ffc7df80a30ee916cc040221cf6fcfb3c6dc994b3fa4c4ab23e8a0f134de5c0c09060200160405180910390a26080860151611811906001600160a01b03168e878f8f6132e6565b5050505050505050509392505050565b5f8061182c33612a45565b61183f61106a60e0870160c088016151a4565b5f61185261108536889003880188615277565b6001600160c01b0381165f908152600e6020526040902090915061187581612e22565b6118aa61188736899003890189615402565b878761189960a08c0160808d01614ce5565b6001600160a01b0316929190613325565b5f735489922f8312c812fbb7184ebf70b9dbfaeed9d463a151a7e1836118d660e08c0160c08d016151a4565b6118e76101008d0160e08e0161515c565b6040516001600160e01b031960e086901b168152600481019390935260029190910b602483015267ffffffffffffffff166044820152606401602060405180830381865af415801561193b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061195f919061539a565b90506119716040890160208a0161515c565b67ffffffffffffffff82811691160294506119a285600161199860e08c0160c08d016151a4565b60020b91906131c8565b9350845f6119af86613288565b90506119c461123a60c08c0160a08d01615337565b156119f2576119de875f61125f60c08e0160a08f01615337565b6119e89083615470565b9150819650611a17565b611a07865f61125f60c08e0160a08f01615337565b611a1190826153b5565b90508095505b611a30611a2a60608c0160408d01614ce5565b83612cbb565b611a4061128360208c018c614ce5565b336001600160c01b0386167fc4c20b9c4a5ada3b01b7a391a08dd81a1be01dd8ef63170dd9da44ecee3db11b611a7c60e08e0160c08f016151a4565b6040805160029290920b825267ffffffffffffffff881660208301520160405180910390a3611add611ab3368c90038c018c615402565b848b8b8e5f016080016020810190611acb9190614ce5565b6001600160a01b031693929190613363565b5050505050935093915050565b6001600160c01b0382165f908152600e60205260408120611b0b90836133a3565b9392505050565b61144b83838360405180602001604052805f815250612289565b6001600160c01b0381165f908152600e6020526040812054600160a01b900467ffffffffffffffff161515610c8e565b5f610c8e82612a00565b5f611b7033612a45565b6001600160a01b0382165f818152600d602052604090205490611b92906133d8565b6001600160a01b0384165f908152600d60205260409020819055611bb79082906153ef565b9150611bc68361128c84613288565b50919050565b611bd4613472565b6001600160a01b0381165f818152600f6020526040808220805460ff19169055517f88f58aa68e1f754fecfec41a6758d18d4a53fa15d4e206fd54bbdfe7a9e98da79190a250565b600a8054611c2990615115565b80601f0160208091040260200160405190810160405280929190818152602001828054611c5590615115565b8015611ca05780601f10611c7757610100808354040283529160200191611ca0565b820191905f5260205f20905b815481529060010190602001808311611c8357829003601f168201915b505050505081565b5f6001600160a01b038216611ceb576040517f89c62b640000000000000000000000000000000000000000000000000000000081525f600482015260240161104e565b506001600160a01b03165f9081526002602052604090205490565b611d0e613472565b611d175f61349f565b565b60065433906001600160a01b03168114611d515760405163118cdaa760e01b81526001600160a01b038216600482015260240161104e565b611d5a8161349f565b50565b83421115611d97576040517f1a15a3cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611e147f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad8888611dc7816134b8565b6040805160208101959095526001600160a01b03909316928401929092526060830152608082015260a0810187905260c001604051602081830303815290604052805190602001206134f1565b90505f611e2087611b5c565b9050806001600160a01b0316886001600160a01b031603611e5457604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b0381163b15611f6a57604080516020810186905280820185905260f887901b7fff000000000000000000000000000000000000000000000000000000000000001660608201528151604181830301815260618201928390527f1626ba7e000000000000000000000000000000000000000000000000000000009092526001600160a01b03831691631626ba7e91611ef691869160650161548f565b602060405180830381865afa158015611f11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3591906154a7565b6001600160e01b031916631626ba7e60e01b14611f6557604051638baa579f60e01b815260040160405180910390fd5b611fa7565b806001600160a01b0316611f8083878787613538565b6001600160a01b031614611fa757604051638baa579f60e01b815260040160405180910390fd5b611fb48888836001613564565b5050505050505050565b5f6060805f805f6060611fcf61369f565b611fd76136cc565b604080515f808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b606060018054610ca290615115565b5f611b0b83836014525f526028600c205c90565b612047613472565b6001600160a01b0381165f818152600f6020526040808220805460ff19166001179055517feb73900b98b6a3e2b8b01708fe544760cf570d21e7fbe5225f24e48b5b2b432e9190a250565b606061209e84336136f9565b6040517f15c7afb40000000000000000000000000000000000000000000000000000000081526001600160a01b038516906315c7afb4906120e7903390879087906004016154ea565b5f604051808303815f875af1158015612102573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612129919081019061550c565b9050612133613759565b5f80516020615af08339815191525c6001600160801b0381169060801c8115801561216657506001600160801b03811615155b1561219d576040517f5212cba100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50509392505050565b335f9081526010602090815260408083206001600160a01b03851684528252808320805490849055600d90925282208054919283926121e69084906153ef565b9091555061220090506001600160a01b03831684836137ce565b816001600160a01b0316836001600160a01b0316336001600160a01b03167f1c4f94f28cc9152354d4b98b8614b28c6c828a98d88228fa9577c7b9475e120c8460405161224f91815260200190565b60405180910390a492915050565b6001600160c01b0382165f908152600e60205260408120611b0b90836138ab565b610d553383836138b9565b61229484848461139e565b61143a84848484613970565b60606122ab82612a00565b505f6122b5613a8f565b90505f8151116122d35760405180602001604052805f815250611b0b565b806122dd84613a9e565b6040516020016122ee929190615598565b6040516020818303038152906040529392505050565b6001600160c01b0381165f908152600e60205260408120610c8e90613b3b565b604080516060810182525f808252602080830182905282840182905284841c808352600e909152928120919291602885901c62ffffff169164ffffffffff861691906123718285856131f2565b6040517f329b4a0100000000000000000000000000000000000000000000000000000000815260048101849052600286900b602482015264ffffffffff851660448201529091505f90735489922f8312c812fbb7184ebf70b9dbfaeed9d49063329b4a0190606401602060405180830381865af41580156123f4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612418919061539a565b90506040518060600160405280835f01516001600160a01b031681526020018284602001510367ffffffffffffffff1681526020018267ffffffffffffffff168152509650505050505050919050565b61247133612a45565b801561144b5761248d8361248483613288565b61128c90615364565b6001600160a01b0383165f908152600d6020526040812080548392906124b49084906153ef565b9091555061144b90506001600160a01b03841683836137ce565b6124d6613472565b611d5a81613b48565b600b8054611c2990615115565b6124f4613472565b600680546001600160a01b0383166001600160a01b031990911681179091556125256005546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b606061256a8260206155ac565b67ffffffffffffffff81111561258257612582614faa565b6040519080825280601f01601f1916602001820160405280156125ac576020820181803683370190505b5090505f5b828110156125d25780840154602060018301028301526001810190506125b1565b5092915050565b6001600160c01b0381165f908152600e60205260408120610c8e90613b91565b61260233612a45565b612612604084016020850161515c565b67ffffffffffffffff165f03612654576040517faf6c36ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6126656080850160608601615337565b90505f61267860c0860160a08701615337565b90506126888262ffffff16613b9e565b801561269d575061269d8162ffffff16613b9e565b6126ba57604051637a34030f60e01b815260040160405180910390fd5b5f620f423f19627fffff848116908416010160020b12156126ee57604051637a34030f60e01b815260040160405180910390fd5b5f627fffff83166207a11f190160020b128061271757505f627fffff82166207a11f190160020b125b1561275c5761272b8162ffffff1660171c90565b151561273c8362ffffff1660171c90565b15151461275c57604051637a34030f60e01b815260040160405180910390fd5b5f61276d60a0870160808801614ce5565b9050612781816001600160a01b0316613bce565b6127c2576040517fe65af6a00000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240161104e565b6127e66127d436889003880188615277565b6001600160a01b038316908787613c05565b5f6127f961108536899003890189615277565b6001600160c01b0381165f908152600e60205260409081902090517fab8a7e3f000000000000000000000000000000000000000000000000000000008152919250735489922f8312c812fbb7184ebf70b9dbfaeed9d49163ab8a7e3f91612864918b906004016155c3565b5f6040518083038186803b15801561287a575f80fd5b505af415801561288c573d5f803e3d5ffd5b506128a1925050506060880160408901614ce5565b6001600160a01b03166128b76020890189614ce5565b6001600160a01b03166001600160c01b0383167f803427d75ce3214f82dc7aa4910635170a6655e2c1663dc03429dd04100cba5a6128fb60408c0160208d0161515c565b6040805167ffffffffffffffff909216825262ffffff808b1660208401528916908201526001600160a01b038716606082015260800160405180910390a461295d61294b36899003890189615277565b6001600160a01b038416908888613c43565b50505050505050565b5f6001600160e01b031982167f80ac58cd0000000000000000000000000000000000000000000000000000000014806129c857506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610c8e57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614610c8e565b5f818152600960205260408120546001600160a01b038116610c8e57604051637e27328960e01b81526004810184905260240161104e565b61144b8383836001613564565b5f612a4e613c81565b90506001600160801b035f80516020615af08339815191525c167ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be422015c6001600160a01b0380831690841603612aa357505050565b806001600160a01b0316836001600160a01b031603612ac157505050565b6040517f74d863650000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301528216602482015260440161104e565b612b11838383613cd6565b61144b576001600160a01b038316612b3f57604051637e27328960e01b81526004810182905260240161104e565b6040517f177e802f0000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024810182905260440161104e565b73020000000000000000000000000000000000000084161561143a5761143a63295b52c560e01b33858585604051602401612bc19493929190615693565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b03861690613d56565b5f6207a11f19627fffff851601600281900b82128281612c2557825f03612c27565b825b62ffffff1690505f612c60612c3c83896155ac565b620f424088612c52578581830615151691040190565b808206151586151691040190565b905082612c7557612c7081615364565b612c77565b805b98975050505050505050565b5f612c8f5f835f612f63565b90506001600160a01b038116610d5557604051637e27328960e01b81526004810183905260240161104e565b805f03612cc6575050565b5f612ccf613c81565b90505f612cdd828585613db3565b9050805f03612cf357612cee613dd1565b61143a565b82810361143a5761143a613e04565b730100000000000000000000000000000000000000851615612d8457612d84635125ce9c60e01b3386868686604051602401612d429594939291906156c2565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b03871690613d56565b5050505050565b6207ffff600282900b1380612db05750612da76207ffff61570c565b60020b8160020b125b15611d5a576040517fce8ef7fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8082604051602001612dfa9190614edb565b60408051601f1981840301815291905280516020909101206001600160c01b03169392505050565b8054600160a01b900467ffffffffffffffff16611d5a576040517f1e3636e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73200000000000000000000000000000000000000084161561143a5761143a633fda46bb60e01b33858585604051602401612bc194939291906157c7565b6001600160a01b038216612ed257604051633250574960e11b81525f600482015260240161104e565b5f612ede83835f612f63565b90506001600160a01b0381161561144b576040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081525f600482015260240161104e565b731000000000000000000000000000000000000000851615612d8457612d8463eba8155960e01b3386868686604051602401612d429594939291906157f8565b5f828152600960205260408120546001600160a01b03831615612f8b57612f8b818486612b06565b6001600160a01b03811615612fc557612fa65f855f80613564565b6001600160a01b0381165f90815260026020526040902080545f190190555b6001600160a01b03851615612ff3576001600160a01b0385165f908152600260205260409020805460010190555b5f84815260096020526040902080546001600160a01b0319166001600160a01b03871617905583856001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4949350505050565b5f306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156130ba57507f000000000000000000000000000000000000000000000000000000000000000046145b156130e457507f000000000000000000000000000000000000000000000000000000000000000090565b611459604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b728000000000000000000000000000000000000084161561143a5761143a63827e0eb260e01b33858585604051602401612bc19493929190615830565b5f6131ea606084901b6131dd8660020b613e37565b8082061515851691040190565b949350505050565b604080518082019091525f80825260208201526132108484846140ff565b6040805180820190915290546001600160a01b0381168252600160a01b900467ffffffffffffffff166020820152949350505050565b5f80821215613284576040517fa8ce44320000000000000000000000000000000000000000000000000000000081526004810183905260240161104e565b5090565b5f7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115613284576040517f24775e060000000000000000000000000000000000000000000000000000000081526004810183905260240161104e565b7240000000000000000000000000000000000000851615612d8457612d846348042cf460e01b3386868686604051602401612d42959493929190615858565b73080000000000000000000000000000000000000084161561143a5761143a63fab3c75660e01b33858585604051602401612bc19493929190615917565b730400000000000000000000000000000000000000851615612d8457612d84639eb477b260e01b3386868686604051602401612d42959493929190615948565b5f6133b16005840183614140565b600283900b5f90815260038501602052604090206133ce90614182565b611b0b919061598a565b5f6001600160a01b0382166133ee575047919050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015613449573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c8e91906159ab565b919050565b6005546001600160a01b03163314611d175760405163118cdaa760e01b815233600482015260240161104e565b600680546001600160a01b0319169055611d5a816141c1565b5f8181526009602052604090205460a081901c906134da81600160a01b6153dc565b5f9384526009602052604090932092909255919050565b5f610c8e6134fd613062565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b5f805f8061354888888888614212565b92509250925061355882826142da565b50909695505050505050565b808061357857506001600160a01b03821615155b15613670575f61358784612a00565b90506001600160a01b038316158015906135b35750826001600160a01b0316816001600160a01b031614155b80156135e457506001600160a01b038082165f9081526004602090815260408083209387168352929052205460ff16155b15613626576040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260240161104e565b811561366e5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b50505f90815260036020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60606114597f000000000000000000000000000000000000000000000000000000000000000060076143dd565b60606114597f000000000000000000000000000000000000000000000000000000000000000060086143dd565b5f80516020615af08339815191525c7f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b160026001600160801b038316020183815d82600182015d50600181015f80516020615af08339815191525d505050565b5f80516020615af08339815191525c6001600160801b038116806137845763f1c77ed05f526004601cfd5b7f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b15f19909101600202015f815d5f600182015d50600181035f80516020615af08339815191525d50565b5f6001600160a01b03841661381e575f805f8085875af1905080612cee576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f51141617169150508061143a576040517ff27f64e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611b0b6004840183614486565b6001600160a01b038216613904576040517f5b08ba180000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260240161104e565b6001600160a01b038381165f81815260046020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561143a57604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906139b29033908890879087906004016159c2565b6020604051808303815f875af19250505080156139ec575060408051601f3d908101601f191682019092526139e9918101906154a7565b60015b613a53573d808015613a19576040519150601f19603f3d011682016040523d82523d5f602084013e613a1e565b606091505b5080515f03613a4b57604051633250574960e11b81526001600160a01b038516600482015260240161104e565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14612d8457604051633250574960e11b81526001600160a01b038516600482015260240161104e565b6060600a8054610ca290615115565b60605f613aaa836145b4565b60010190505f8167ffffffffffffffff811115613ac957613ac9614faa565b6040519080825280601f01601f191660200182016040528015613af3576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084613afd57509392505050565b5f610c8e82600401614695565b600c80546001600160a01b0319166001600160a01b0383169081179091556040517fef673bbfc2ac7e4d4b810bffda0b15a1f2b48c2aa4d178d3fca87d0d1f337062905f90a250565b5f610c8e82600401614780565b5f6207a11f19627fffff8316016207a120600282900b1380613bc657506207a11f198160020b125b159392505050565b5f6001600160a01b0382161580610c8e57505072400000000000000000000000000000000000006001600160a01b03909116101590565b73800000000000000000000000000000000000000084161561143a5761143a635df4d91860e01b33858585604051602401612bc194939291906159f3565b73400000000000000000000000000000000000000084161561143a5761143a6371ded94360e01b33858585604051602401612bc194939291906159f3565b5f5f80516020615af08339815191525c6001600160801b031680613ca5575f613cd0565b60025f198201027f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b1015c5b91505090565b5f6001600160a01b038316158015906131ea5750826001600160a01b0316846001600160a01b03161480613d2e57506001600160a01b038085165f9081526004602090815260408083209387168352929052205460ff165b806131ea5750505f908152600360205260409020546001600160a01b03908116911614919050565b5f80613d6284846147c5565b91509150816001600160e01b031916816001600160e01b0319161461143a576040517f1e048e1d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82601452835f526028600c2082815c01915081815d509392505050565b7001000000000000000000000000000000005f80516020615af08339815191525c035f80516020615af08339815191525d565b7001000000000000000000000000000000005f80516020615af08339815191525c015f80516020615af08339815191525d565b5f613e4182612d8b565b815f600282900b8113613e545781613e5d565b613e5d8261570c565b62ffffff8116915060011615613e81576bfff97272373d413259a469909250613e92565b6c0100000000000000000000000092505b6002811615613eb15760606bfff2e50f5f656932ef12357c8402901c92505b6004811615613ed05760606bffe5caca7e10e4e61c3624ea8402901c92505b6008811615613eef5760606bffcb9843d60f6159c9db58838402901c92505b6010811615613f0e5760606bff973b41fa98c081472e68968402901c92505b6020811615613f2d5760606bff2ea16466c96a3843ec78b38402901c92505b6040811615613f4c5760606bfe5dee046a99a2a811c461f18402901c92505b6080811615613f6b5760606bfcbe86c7900a88aedcffc83b8402901c92505b610100811615613f8b5760606bf987a7253ac413176f2b074c8402901c92505b610200811615613fab5760606bf3392b0822b70005940c7a398402901c92505b610400811615613fcb5760606be7159475a2c29b7443b29c7f8402901c92505b610800811615613feb5760606bd097f3bdfd2022b8845ad8f78402901c92505b61100081161561400b5760606ba9f746462d870fdf8a65dc1f8402901c92505b61200081161561402b5760606b70d869a156d2a1b890bb3df68402901c92505b61400081161561404b5760606b31be135f97d08fd9812315058402901c92505b61800081161561406b5760606b09aa508b5b7a84e1c677de548402901c92505b6201000081161561408b5760606a5d6af8dedb81196699c3298402901c92505b620200008116156140aa576060692216e584f5fa1ea926048402901c92505b620400008116156140c757606067048a170391f7dc428402901c92505b5f8260020b13156140f8576140f5837801000000000000000000000000000000000000000000000000615a7c565b92505b5050919050565b600282900b5f9081526003840160205260408120600401805464ffffffffff841690811061412f5761412f615a9b565b905f5260205f200190509392505050565b600281901c623fffff165f818152602084905260408120549091906003841690600685901b60c0161c67ffffffffffffffff1680151590035b95945050505050565b60015f9081526020829052604081205461419e90826004614873565b5f808052602084905260408120546141b7916004614873565b610c8e9190615aaf565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561424b57505f915060039050826142d0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa15801561429c573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b0381166142c757505f9250600191508290506142d0565b92505f91508190505b9450945094915050565b5f8260038111156142ed576142ed615ad0565b036142f6575050565b600182600381111561430a5761430a615ad0565b03614341576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282600381111561435557614355615ad0565b0361438f576040517ffce698f70000000000000000000000000000000000000000000000000000000081526004810182905260240161104e565b60038260038111156143a3576143a3615ad0565b03610d55576040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004810182905260240161104e565b606060ff83146143f7576143f0836148b3565b9050610c8e565b81805461440390615115565b80601f016020809104026020016040519081016040528092919081815260200182805461442f90615115565b801561447a5780601f106144515761010080835404028352916020019161447a565b820191905f5260205f20905b81548152906001019060200180831161445d57829003601f168201915b50505050509050610c8e565b62800000811901600881901c61ffff165f81815260208590526040812054909260ff1690600119821b1680840361458857600883901c80195f9081526020889052604081205460011960ff87161b169081900361455e575f888161450b7f7710c0702d438d37259561c892984b894ff622adfa3d98b5dfe5a9763f94b95460016153dc565b81526020019081526020015f205483600119901b169050805f0361453b57627fffff199650505050505050610c8e565b614544816148f0565b60ff1680195f90815260208b905260409020549093509150505b614567816148f0565b60ff16600883901b179450875f8681526020019081526020015f2054925050505b614591816148f0565b60ff16915062ffffff627fffff19600885901b84170119165b9695505050505050565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106145fc577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310614628576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061464657662386f26fc10000830492506010015b6305f5e100831061465e576305f5e100830492506008015b612710831061467257612710830492506004015b60648310614684576064830492506002015b600a8310610c8e5760010192915050565b5f61469f82614780565b156146d6576040517f4f3d7def00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61471a83826147077f7710c0702d438d37259561c892984b894ff622adfa3d98b5dfe5a9763f94b95460016153dc565b81526020019081526020015f20546148f0565b60ff1690505f61473a845f841981526020019081526020015f20546148f0565b60ff16600883901b1790505f61475f855f8481526020019081526020015f20546148f0565b60ff16905062ffffff627fffff19600884901b831701191695945050505050565b5f81816147ae7f7710c0702d438d37259561c892984b894ff622adfa3d98b5dfe5a9763f94b95460016153dc565b81526020019081526020015f20545f149050919050565b5f805f6147d185614966565b9050602084015192505f80866001600160a01b0316866040516147f49190615ae4565b5f604051808303815f865af19150503d805f811461482d576040519150601f19603f3d011682016040523d82523d5f602084013e614832565b606091505b50915091508161484557614845816149f5565b8080602001905181019061485991906154a7565b9350821561486957614869614a2f565b5050509250929050565b600682901b9290921c915f825b828110156148a857604085901c9467ffffffffffffffff168015019190910190600101614880565b509190039003919050565b60605f6148bf83614a6f565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f8082116148fc575f80fd5b5f7e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff600184190184160260f81c90506040518061012001604052806101008152602001615b106101009139818151811061495757614957615a9b565b016020015160f81c9392505050565b5f6001600160a01b036001600160801b035f80516020615af08339815191525c167ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be422015c1661346d575f80516020615af08339815191525c6001600160801b0316827ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be42282015d50600192915050565b80515f03613a4b576040517f36bc48c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80516020615af08339815191525c6001600160801b03165f7ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be42282015d50565b5f60ff8216601f811115610c8e576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160e01b031981168114611d5a575f80fd5b5f60208284031215614ad4575f80fd5b8135611b0b81614aaf565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611b0b6020830184614adf565b5f60208284031215614b2f575f80fd5b5035919050565b6001600160a01b0381168114611d5a575f80fd5b5f8060408385031215614b5b575f80fd5b8235614b6681614b36565b946020939093013593505050565b5f8083601f840112614b84575f80fd5b50813567ffffffffffffffff811115614b9b575f80fd5b602083019150836020828501011115614bb2575f80fd5b9250929050565b5f805f8385036060811215614bcc575f80fd5b6040811215614bd9575f80fd5b50839250604084013567ffffffffffffffff811115614bf6575f80fd5b614c0286828701614b74565b9497909650939450505050565b5f805f838503610140811215614c23575f80fd5b61012080821215614c32575f80fd5b859450840135905067ffffffffffffffff811115614bf6575f80fd5b5f60c08284031215611bc6575f80fd5b5f60c08284031215614c6e575f80fd5b611b0b8383614c4e565b5f805f60608486031215614c8a575f80fd5b8335614c9581614b36565b92506020840135614ca581614b36565b929592945050506040919091013590565b5f805f60408486031215614cc8575f80fd5b83359250602084013567ffffffffffffffff811115614bf6575f80fd5b5f60208284031215614cf5575f80fd5b8135611b0b81614b36565b5f805f838503610120811215614d14575f80fd5b61010080821215614c32575f80fd5b5f8060408385031215614d34575f80fd5b8235614d3f81614b36565b91506020830135614d4f81614b36565b809150509250929050565b80356001600160c01b038116811461346d575f80fd5b8035600281900b811461346d575f80fd5b5f8060408385031215614d92575f80fd5b614d9b83614d5a565b9150614da960208401614d70565b90509250929050565b5f60208284031215614dc2575f80fd5b611b0b82614d5a565b5f805f805f8060c08789031215614de0575f80fd5b8635614deb81614b36565b95506020870135945060408701359350606087013560ff81168114614e0e575f80fd5b9598949750929560808101359460a0909101359350915050565b7fff00000000000000000000000000000000000000000000000000000000000000881681525f602060e06020840152614e6460e084018a614adf565b8381036040850152614e76818a614adf565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825260208088019350909101905f5b81811015614ec957835183529284019291840191600101614ead565b50909c9b505050505050505050505050565b60c08101610c8e82846001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b5f805f60408486031215614f54575f80fd5b8335614f5f81614b36565b9250602084013567ffffffffffffffff811115614bf6575f80fd5b5f8060408385031215614f8b575f80fd5b8235614f9681614b36565b915060208301358015158114614d4f575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614fe757614fe7614faa565b604052919050565b5f67ffffffffffffffff82111561500857615008614faa565b50601f01601f191660200190565b5f805f8060808587031215615029575f80fd5b843561503481614b36565b9350602085013561504481614b36565b925060408501359150606085013567ffffffffffffffff811115615066575f80fd5b8501601f81018713615076575f80fd5b803561508961508482614fef565b614fbe565b81815288602083850101111561509d575f80fd5b816020840160208301375f6020838301015280935050505092959194509250565b5f80604083850312156150cf575f80fd5b50508035926020909101359150565b5f805f60e084860312156150f0575f80fd5b6150fa8585614c4e565b925060c084013567ffffffffffffffff811115614bf6575f80fd5b600181811c9082168061512957607f821691505b602082108103611bc657634e487b7160e01b5f52602260045260245ffd5b67ffffffffffffffff81168114611d5a575f80fd5b5f6020828403121561516c575f80fd5b8135611b0b81615147565b5f8060408385031215615188575f80fd5b825161519381615147565b6020840151909250614d4f81615147565b5f602082840312156151b4575f80fd5b611b0b82614d70565b803562ffffff8116811461346d575f80fd5b5f60c082840312156151df575f80fd5b60405160c0810181811067ffffffffffffffff8211171561520257615202614faa565b604052905080823561521381614b36565b8152602083013561522381615147565b6020820152604083013561523681614b36565b6040820152615247606084016151bd565b6060820152608083013561525a81614b36565b608082015261526b60a084016151bd565b60a08201525092915050565b5f60c08284031215615287575f80fd5b611b0b83836151cf565b5f61012082840312156152a2575f80fd5b6040516080810181811067ffffffffffffffff821117156152c5576152c5614faa565b6040526152d284846151cf565b81526152e060c08401614d70565b602082015260e08301356152f381615147565b604082015261010083013561530781614b36565b60608201529392505050565b5f60208284031215615323575f80fd5b815164ffffffffff81168114611b0b575f80fd5b5f60208284031215615347575f80fd5b611b0b826151bd565b634e487b7160e01b5f52601160045260245ffd5b5f7f8000000000000000000000000000000000000000000000000000000000000000820361539457615394615350565b505f0390565b5f602082840312156153aa575f80fd5b8151611b0b81615147565b8082018281125f8312801582168215821617156153d4576153d4615350565b505092915050565b80820180821115610c8e57610c8e615350565b81810381811115610c8e57610c8e615350565b5f6101008284031215615413575f80fd5b6040516060810181811067ffffffffffffffff8211171561543657615436614faa565b60405261544384846151cf565b815261545160c08401614d70565b602082015260e083013561546481615147565b60408201529392505050565b8181035f8312801583831316838312821617156125d2576125d2615350565b828152604060208201525f6131ea6040830184614adf565b5f602082840312156154b7575f80fd5b8151611b0b81614aaf565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b0384168152604060208201525f6141796040830184866154c2565b5f6020828403121561551c575f80fd5b815167ffffffffffffffff811115615532575f80fd5b8201601f81018413615542575f80fd5b805161555061508482614fef565b818152856020838501011115615564575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b5f81518060208401855e5f93019283525090919050565b5f6131ea6155a68386615581565b84615581565b8082028115828204841417610c8e57610c8e615350565b82815260e0810182356155d581614b36565b6001600160a01b038082166020850152602085013591506155f582615147565b67ffffffffffffffff821660408501526040850135915061561582614b36565b8082166060850152615629606086016151bd565b915062ffffff80831660808601526080860135925061564783614b36565b81831660a08601528061565c60a088016151bd565b1660c08601525050509392505050565b80358252602081013561567e81615147565b67ffffffffffffffff81166020840152505050565b6001600160a01b03851681526156ac602082018561566c565b608060608201525f6145aa6080830184866154c2565b6001600160a01b03861681526156db602082018661566c565b67ffffffffffffffff8416606082015260a060808201525f61570160a0830184866154c2565b979650505050505050565b5f8160020b627fffff19810361572457615724615350565b5f0392915050565b6157908282516001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b602081015160020b60c0830152604081015167ffffffffffffffff1660e0830152606001516001600160a01b031661010090910152565b5f6101606001600160a01b03871683526157e4602084018761572c565b8061014084015261570181840185876154c2565b5f6101806001600160a01b0388168352615815602084018861572c565b8561014084015280610160840152612c7781840185876154c2565b6001600160a01b0385168152836020820152606060408201525f6145aa6060830184866154c2565b6001600160a01b038616815284602082015267ffffffffffffffff84166040820152608060608201525f6157016080830184866154c2565b6158f48282516001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b602081015160020b60c08301526040015167ffffffffffffffff1660e090910152565b5f6101406001600160a01b03871683526159346020840187615890565b8061012084015261570181840185876154c2565b5f6101606001600160a01b03881683526159656020840188615890565b67ffffffffffffffff861661012084015280610140840152612c7781840185876154c2565b67ffffffffffffffff8281168282160390808211156125d2576125d2615350565b5f602082840312156159bb575f80fd5b5051919050565b5f6001600160a01b038087168352808616602084015250836040830152608060608301526145aa6080830184614adf565b5f6101006001600160a01b0387168352615a6960208401876001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b8060e084015261570181840185876154c2565b5f82615a9657634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffd5b67ffffffffffffffff8181168382160190808211156125d2576125d2615350565b634e487b7160e01b5f52602160045260245ffd5b5f611b0b828461558156fe760a9a962ae3d184e99c0483cf5684fb3170f47116ca4f445c50209da4f4f9070001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a264697066735822122064f09b2cf4df87a40a102856d4e12ddac16787c8abd3963f52a4293d32e4b81064736f6c634300081900330000000000000000000000004587dd6356d7293e5f10db4d853332bd5b218c0b000000000000000000000000cc92364b6b886158e71fd4e4da5c682d33d1491e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000002f68747470733a2f2f736f6e69632e6d61726b65742f6170692f6e66742f636861696e732f3134362f6f72646572732f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c68747470733a2f2f736f6e69632e6d61726b65742f6170692f636f6e74726163742f636861696e732f31343600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022536f6e6963204d61726b6574204f72646572626f6f6b204d616b6572204f726465720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012534f4e49432d4d41524b45542d4f524445520000000000000000000000000000

    Deployed Bytecode

    0x608060405260043610610353575f3560e01c80637ac2ff7b116101bd578063cdc92f2d116100f2578063e8a3d48511610092578063f2fde38b1161006d578063f2fde38b14610bd5578063f86a11b314610bf4578063fcc8fc9b14610c13578063fefc7c5114610c32575f80fd5b8063e8a3d48514610b5c578063e985e9c514610b70578063f035079914610bb7575f80fd5b8063d83747e8116100cd578063d83747e814610ae2578063d9caed1214610b01578063de4478ec14610b20578063e30c397814610b3f575f80fd5b8063cdc92f2d146109dd578063d09ef241146109fc578063d68f4dd114610a58575f80fd5b80639b22917d1161015d578063a179dadc11610138578063a179dadc1461094e578063a22cb46514610980578063b88d4fde1461099f578063c87b56dd146109be575f80fd5b80639b22917d146108335780639ca1799814610910578063a12ef25e1461092f575f80fd5b806393c85a211161019857806393c85a21146107b657806395d89b41146107e15780639611cf6c146107f55780639b19251a14610814575f80fd5b80637ac2ff7b1461075357806384b0196e146107725780638da5cb5b14610799575f80fd5b80633af32abf116102935780636352211e116102335780636c0360eb1161020e5780636c0360eb146106f857806370a082311461070c578063715018a61461072b57806379ba50971461073f575f80fd5b80636352211e146106a75780636a256b29146106c65780636b2cc75c146106d9575f80fd5b806341a8bb881161026e57806341a8bb88146105f857806342842e0e146106305780634c02bf0b1461064f57806355af6a3214610688575f80fd5b80633af32abf146105755780633b9500b0146105a35780633e547b06146105c2575f80fd5b80631dbef488116102fe5780632f584a6d116102d95780632f584a6d146104f057806330adf81f1461050f5780633644e5151461054257806338926b6d14610556575f80fd5b80631dbef488146104665780631ff63f931461049a57806323b872dd146104d1575f80fd5b8063095ea7b31161032e578063095ea7b3146103ea578063141a468c1461040b57806314d6a9eb14610447575f80fd5b806301ffc9a71461035e57806306fdde0314610392578063081812fc146103b3575f80fd5b3661035a57005b5f80fd5b348015610369575f80fd5b5061037d610378366004614ac4565b610c51565b60405190151581526020015b60405180910390f35b34801561039d575f80fd5b506103a6610c94565b6040516103899190614b0d565b3480156103be575f80fd5b506103d26103cd366004614b1f565b610d23565b6040516001600160a01b039091168152602001610389565b3480156103f5575f80fd5b50610409610404366004614b4a565b610d4a565b005b348015610416575f80fd5b50610439610425366004614b1f565b5f9081526009602052604090205460a01c90565b604051908152602001610389565b348015610452575f80fd5b50610439610461366004614bb9565b610d59565b348015610471575f80fd5b50610485610480366004614c0f565b610f9a565b60408051928352602083019190915201610389565b3480156104a5575f80fd5b506104b96104b4366004614c5e565b61138b565b6040516001600160c01b039091168152602001610389565b3480156104dc575f80fd5b506104096104eb366004614c78565b61139e565b3480156104fb575f80fd5b5061040961050a366004614c78565b611440565b34801561051a575f80fd5b506104397f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad81565b34801561054d575f80fd5b50610439611450565b348015610561575f80fd5b50610439610570366004614cb6565b61145e565b348015610580575f80fd5b5061037d61058f366004614ce5565b600f6020525f908152604090205460ff1681565b3480156105ae575f80fd5b506104856105bd366004614d00565b611821565b3480156105cd575f80fd5b506104396105dc366004614d23565b601060209081525f928352604080842090915290825290205481565b348015610603575f80fd5b50610617610612366004614d81565b611aea565b60405167ffffffffffffffff9091168152602001610389565b34801561063b575f80fd5b5061040961064a366004614c78565b611b12565b34801561065a575f80fd5b50604080515f80516020615af08339815191525c6001600160801b038116825260801c602082015201610389565b348015610693575f80fd5b5061037d6106a2366004614db2565b611b2c565b3480156106b2575f80fd5b506103d26106c1366004614b1f565b611b5c565b6104396106d4366004614ce5565b611b66565b3480156106e4575f80fd5b506104096106f3366004614ce5565b611bcc565b348015610703575f80fd5b506103a6611c1c565b348015610717575f80fd5b50610439610726366004614ce5565b611ca8565b348015610736575f80fd5b50610409611d06565b34801561074a575f80fd5b50610409611d19565b34801561075e575f80fd5b5061040961076d366004614dcb565b611d5d565b34801561077d575f80fd5b50610786611fbe565b6040516103899796959493929190614e28565b3480156107a4575f80fd5b506005546001600160a01b03166103d2565b3480156107c1575f80fd5b506104396107d0366004614ce5565b600d6020525f908152604090205481565b3480156107ec575f80fd5b506103a661201c565b348015610800575f80fd5b5061043961080f366004614d23565b61202b565b34801561081f575f80fd5b5061040961082e366004614ce5565b61203f565b34801561083e575f80fd5b5061090361084d366004614db2565b6040805160c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160c01b03165f908152600e6020908152604091829020825160c08101845281546001600160a01b03808216835267ffffffffffffffff600160a01b92839004169483019490945260018301548085169583019590955262ffffff94819004851660608301526002909201549283166080820152910490911660a082015290565b6040516103899190614edb565b34801561091b575f80fd5b506103a661092a366004614f42565b612092565b34801561093a575f80fd5b50610439610949366004614d23565b6121a6565b348015610959575f80fd5b5061096d610968366004614d81565b61225d565b60405160029190910b8152602001610389565b34801561098b575f80fd5b5061040961099a366004614f7a565b61227e565b3480156109aa575f80fd5b506104096109b9366004615016565b612289565b3480156109c9575f80fd5b506103a66109d8366004614b1f565b6122a0565b3480156109e8575f80fd5b5061096d6109f7366004614db2565b612304565b348015610a07575f80fd5b50610a1b610a16366004614b1f565b612324565b6040805182516001600160a01b0316815260208084015167ffffffffffffffff908116918301919091529282015190921690820152606001610389565b348015610a63575f80fd5b50610ac2610a72366004614b1f565b6002027f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b181015c917f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b29091015c90565b604080516001600160a01b03938416815292909116602083015201610389565b348015610aed575f80fd5b50600c546103d2906001600160a01b031681565b348015610b0c575f80fd5b50610409610b1b366004614c78565b612468565b348015610b2b575f80fd5b50610409610b3a366004614ce5565b6124ce565b348015610b4a575f80fd5b506006546001600160a01b03166103d2565b348015610b67575f80fd5b506103a66124df565b348015610b7b575f80fd5b5061037d610b8a366004614d23565b6001600160a01b039182165f90815260046020908152604080832093909416825291909152205460ff1690565b348015610bc2575f80fd5b50610439610bd1366004614b1f565b5490565b348015610be0575f80fd5b50610409610bef366004614ce5565b6124ec565b348015610bff575f80fd5b506103a6610c0e3660046150be565b61255d565b348015610c1e575f80fd5b5061037d610c2d366004614db2565b6125d9565b348015610c3d575f80fd5b50610409610c4c3660046150de565b6125f9565b5f6001600160e01b031982167f6831a4fd000000000000000000000000000000000000000000000000000000001480610c8e5750610c8e82612966565b92915050565b60605f8054610ca290615115565b80601f0160208091040260200160405190810160405280929190818152602001828054610cce90615115565b8015610d195780601f10610cf057610100808354040283529160200191610d19565b820191905f5260205f20905b815481529060010190602001808311610cfc57829003601f168201915b5050505050905090565b5f610d2d82612a00565b505f828152600360205260409020546001600160a01b0316610c8e565b610d55828233612a38565b5050565b5f610d6333612a45565b610d84610d7c85355f9081526009602052604090205490565b338635612b06565b8335604090811c5f908152600e602090815290829020825160c08101845281546001600160a01b03808216835267ffffffffffffffff600160a01b92839004169483019490945260018301548085169583019590955262ffffff9481900485166060830152600283015493841660808301819052930490931660a08401529190610e1090878787612b83565b5f80735489922f8312c812fbb7184ebf70b9dbfaeed9d4633ac502c1858a35610e3f60408d0160208e0161515c565b6040516001600160e01b031960e086901b1681526004810193909352602483019190915267ffffffffffffffff1660448201526064016040805180830381865af4158015610e8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eb39190615177565b91509150826020015167ffffffffffffffff168267ffffffffffffffff16029450610ee7836060015162ffffff1660171c90565b15610f0b5760608301515f90610f049062ffffff16876001612c03565b9590950194505b8067ffffffffffffffff165f03610f2657610f268835612c83565b610f34836040015186612cbb565b60405167ffffffffffffffff831681528835907f0c6ba7ef5064094c17cce013aa4c617a23e2582f867774d07a5931de43b85d729060200160405180910390a26080830151610f8f906001600160a01b031689848a8a612d02565b505050509392505050565b5f80610fa533612a45565b5f610fb861012087016101008801614ce5565b6001600160a01b031614158015610ffd5750600f5f610fdf61012088016101008901614ce5565b6001600160a01b0316815260208101919091526040015f205460ff16155b156110575761101461012086016101008701614ce5565b6040517f962715990000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b61107261106a60e0870160c088016151a4565b60020b612d8b565b5f61108a61108536889003880188615277565b612de7565b6001600160c01b0381165f908152600e602052604090209091506110ad81612e22565b6110e26110bf36899003890189615291565b87876110d160a08c0160808d01614ce5565b6001600160a01b0316929190612e6b565b5f735489922f8312c812fbb7184ebf70b9dbfaeed9d463ffa0afb58361110e60e08c0160c08d016151a4565b61111f6101008d0160e08e0161515c565b6111316101208e016101008f01614ce5565b6040516001600160e01b031960e087901b168152600481019490945260029290920b602484015267ffffffffffffffff1660448301526001600160a01b03166064820152608401602060405180830381865af4158015611193573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b79190615313565b90506111e9836111cd60e08b0160c08c016151a4565b60409190911b60289190911b67ffffff00000000001601820190565b94505f6111fc60408a0160208b0161515c565b67ffffffffffffffff166112176101008b0160e08c0161515c565b67ffffffffffffffff1602945084905061124561123a60808b0160608c01615337565b62ffffff1660171c90565b156112705761126b855f61125f60808d0160608e01615337565b62ffffff169190612c03565b019350835b61129161128360608b0160408c01614ce5565b61128c83615364565b612cbb565b61129b3387612ea9565b336001600160c01b0385167f251db4df45fa692f68b4e3f072919384c5b71995c71bf22888385168930fd22a6112d760e08d0160c08e016151a4565b858d60e00160208101906112eb919061515c565b8e6101000160208101906112ff9190614ce5565b6040805160029590950b855264ffffffffff93909316602085015267ffffffffffffffff91909116838301526001600160a01b03166060830152519081900360800190a361137f611355368b90038b018b615291565b878a8a8d5f01608001602081019061136d9190614ce5565b6001600160a01b031693929190612f23565b50505050935093915050565b5f610c8e61108536849003840184615277565b6001600160a01b0382166113c757604051633250574960e11b81525f600482015260240161104e565b5f6113d3838333612f63565b9050836001600160a01b0316816001600160a01b03161461143a576040517f64283d7b0000000000000000000000000000000000000000000000000000000081526001600160a01b038086166004830152602482018490528216604482015260640161104e565b50505050565b61144b838383612b06565b505050565b5f611459613062565b905090565b5f61146833612a45565b5f84815260096020526040902054611481903386612b06565b604084811c5f908152600e602090815290829020825160c08101845281546001600160a01b03808216835267ffffffffffffffff600160a01b92839004169483019490945260018301548085169583019590955262ffffff94819004851660608301526002830154938416608083018190529304841660a0820152602888901c9093169264ffffffffff88169261151a9089898961318b565b6040517fc49d262100000000000000000000000000000000000000000000000000000000815260048101839052600285900b602482015264ffffffffff841660448201525f90735489922f8312c812fbb7184ebf70b9dbfaeed9d49063c49d262190606401602060405180830381865af415801561159a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115be919061539a565b60208301519091505f90819067ffffffffffffffff8085169116026115e8600289900b82846131c8565b606086015160a0870151919a509061160562ffffff821660171c90565b156116225761161b62ffffff8216846001612c03565b9450611636565b61163362ffffff82168c6001612c03565b93505b6116458262ffffff1660171c90565b1561166c5761165b62ffffff8316846001612c03565b61166590866153b5565b94506116b8565b5f61167d62ffffff84168d83612c03565b905061168981866153b5565b94505f81136116aa5761169b81615364565b6116a5908d6153dc565b6116b4565b6116b4818d6153ef565b9b50505b505f91506116c990508689896131f2565b80519091506001600160a01b0381166116ea5750600c546001600160a01b03165b5f84131561173b576116fb84613246565b6001600160a01b038083165f9081526010602090815260408083208b820151909416835292905290812080549091906117359084906153dc565b90915550505b5f83131561178a5761174c83613246565b6001600160a01b038083165f9081526010602090815260408083208b51909416835292905290812080549091906117849084906153dc565b90915550505b816020015167ffffffffffffffff165f036117a8576117a88d612c83565b85516117b79061128c8c613288565b60405167ffffffffffffffff861681528d907ffc7df80a30ee916cc040221cf6fcfb3c6dc994b3fa4c4ab23e8a0f134de5c0c09060200160405180910390a26080860151611811906001600160a01b03168e878f8f6132e6565b5050505050505050509392505050565b5f8061182c33612a45565b61183f61106a60e0870160c088016151a4565b5f61185261108536889003880188615277565b6001600160c01b0381165f908152600e6020526040902090915061187581612e22565b6118aa61188736899003890189615402565b878761189960a08c0160808d01614ce5565b6001600160a01b0316929190613325565b5f735489922f8312c812fbb7184ebf70b9dbfaeed9d463a151a7e1836118d660e08c0160c08d016151a4565b6118e76101008d0160e08e0161515c565b6040516001600160e01b031960e086901b168152600481019390935260029190910b602483015267ffffffffffffffff166044820152606401602060405180830381865af415801561193b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061195f919061539a565b90506119716040890160208a0161515c565b67ffffffffffffffff82811691160294506119a285600161199860e08c0160c08d016151a4565b60020b91906131c8565b9350845f6119af86613288565b90506119c461123a60c08c0160a08d01615337565b156119f2576119de875f61125f60c08e0160a08f01615337565b6119e89083615470565b9150819650611a17565b611a07865f61125f60c08e0160a08f01615337565b611a1190826153b5565b90508095505b611a30611a2a60608c0160408d01614ce5565b83612cbb565b611a4061128360208c018c614ce5565b336001600160c01b0386167fc4c20b9c4a5ada3b01b7a391a08dd81a1be01dd8ef63170dd9da44ecee3db11b611a7c60e08e0160c08f016151a4565b6040805160029290920b825267ffffffffffffffff881660208301520160405180910390a3611add611ab3368c90038c018c615402565b848b8b8e5f016080016020810190611acb9190614ce5565b6001600160a01b031693929190613363565b5050505050935093915050565b6001600160c01b0382165f908152600e60205260408120611b0b90836133a3565b9392505050565b61144b83838360405180602001604052805f815250612289565b6001600160c01b0381165f908152600e6020526040812054600160a01b900467ffffffffffffffff161515610c8e565b5f610c8e82612a00565b5f611b7033612a45565b6001600160a01b0382165f818152600d602052604090205490611b92906133d8565b6001600160a01b0384165f908152600d60205260409020819055611bb79082906153ef565b9150611bc68361128c84613288565b50919050565b611bd4613472565b6001600160a01b0381165f818152600f6020526040808220805460ff19169055517f88f58aa68e1f754fecfec41a6758d18d4a53fa15d4e206fd54bbdfe7a9e98da79190a250565b600a8054611c2990615115565b80601f0160208091040260200160405190810160405280929190818152602001828054611c5590615115565b8015611ca05780601f10611c7757610100808354040283529160200191611ca0565b820191905f5260205f20905b815481529060010190602001808311611c8357829003601f168201915b505050505081565b5f6001600160a01b038216611ceb576040517f89c62b640000000000000000000000000000000000000000000000000000000081525f600482015260240161104e565b506001600160a01b03165f9081526002602052604090205490565b611d0e613472565b611d175f61349f565b565b60065433906001600160a01b03168114611d515760405163118cdaa760e01b81526001600160a01b038216600482015260240161104e565b611d5a8161349f565b50565b83421115611d97576040517f1a15a3cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611e147f49ecf333e5b8c95c40fdafc95c1ad136e8914a8fb55e9dc8bb01eaa83a2df9ad8888611dc7816134b8565b6040805160208101959095526001600160a01b03909316928401929092526060830152608082015260a0810187905260c001604051602081830303815290604052805190602001206134f1565b90505f611e2087611b5c565b9050806001600160a01b0316886001600160a01b031603611e5457604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b0381163b15611f6a57604080516020810186905280820185905260f887901b7fff000000000000000000000000000000000000000000000000000000000000001660608201528151604181830301815260618201928390527f1626ba7e000000000000000000000000000000000000000000000000000000009092526001600160a01b03831691631626ba7e91611ef691869160650161548f565b602060405180830381865afa158015611f11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3591906154a7565b6001600160e01b031916631626ba7e60e01b14611f6557604051638baa579f60e01b815260040160405180910390fd5b611fa7565b806001600160a01b0316611f8083878787613538565b6001600160a01b031614611fa757604051638baa579f60e01b815260040160405180910390fd5b611fb48888836001613564565b5050505050505050565b5f6060805f805f6060611fcf61369f565b611fd76136cc565b604080515f808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b606060018054610ca290615115565b5f611b0b83836014525f526028600c205c90565b612047613472565b6001600160a01b0381165f818152600f6020526040808220805460ff19166001179055517feb73900b98b6a3e2b8b01708fe544760cf570d21e7fbe5225f24e48b5b2b432e9190a250565b606061209e84336136f9565b6040517f15c7afb40000000000000000000000000000000000000000000000000000000081526001600160a01b038516906315c7afb4906120e7903390879087906004016154ea565b5f604051808303815f875af1158015612102573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612129919081019061550c565b9050612133613759565b5f80516020615af08339815191525c6001600160801b0381169060801c8115801561216657506001600160801b03811615155b1561219d576040517f5212cba100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50509392505050565b335f9081526010602090815260408083206001600160a01b03851684528252808320805490849055600d90925282208054919283926121e69084906153ef565b9091555061220090506001600160a01b03831684836137ce565b816001600160a01b0316836001600160a01b0316336001600160a01b03167f1c4f94f28cc9152354d4b98b8614b28c6c828a98d88228fa9577c7b9475e120c8460405161224f91815260200190565b60405180910390a492915050565b6001600160c01b0382165f908152600e60205260408120611b0b90836138ab565b610d553383836138b9565b61229484848461139e565b61143a84848484613970565b60606122ab82612a00565b505f6122b5613a8f565b90505f8151116122d35760405180602001604052805f815250611b0b565b806122dd84613a9e565b6040516020016122ee929190615598565b6040516020818303038152906040529392505050565b6001600160c01b0381165f908152600e60205260408120610c8e90613b3b565b604080516060810182525f808252602080830182905282840182905284841c808352600e909152928120919291602885901c62ffffff169164ffffffffff861691906123718285856131f2565b6040517f329b4a0100000000000000000000000000000000000000000000000000000000815260048101849052600286900b602482015264ffffffffff851660448201529091505f90735489922f8312c812fbb7184ebf70b9dbfaeed9d49063329b4a0190606401602060405180830381865af41580156123f4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612418919061539a565b90506040518060600160405280835f01516001600160a01b031681526020018284602001510367ffffffffffffffff1681526020018267ffffffffffffffff168152509650505050505050919050565b61247133612a45565b801561144b5761248d8361248483613288565b61128c90615364565b6001600160a01b0383165f908152600d6020526040812080548392906124b49084906153ef565b9091555061144b90506001600160a01b03841683836137ce565b6124d6613472565b611d5a81613b48565b600b8054611c2990615115565b6124f4613472565b600680546001600160a01b0383166001600160a01b031990911681179091556125256005546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b606061256a8260206155ac565b67ffffffffffffffff81111561258257612582614faa565b6040519080825280601f01601f1916602001820160405280156125ac576020820181803683370190505b5090505f5b828110156125d25780840154602060018301028301526001810190506125b1565b5092915050565b6001600160c01b0381165f908152600e60205260408120610c8e90613b91565b61260233612a45565b612612604084016020850161515c565b67ffffffffffffffff165f03612654576040517faf6c36ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6126656080850160608601615337565b90505f61267860c0860160a08701615337565b90506126888262ffffff16613b9e565b801561269d575061269d8162ffffff16613b9e565b6126ba57604051637a34030f60e01b815260040160405180910390fd5b5f620f423f19627fffff848116908416010160020b12156126ee57604051637a34030f60e01b815260040160405180910390fd5b5f627fffff83166207a11f190160020b128061271757505f627fffff82166207a11f190160020b125b1561275c5761272b8162ffffff1660171c90565b151561273c8362ffffff1660171c90565b15151461275c57604051637a34030f60e01b815260040160405180910390fd5b5f61276d60a0870160808801614ce5565b9050612781816001600160a01b0316613bce565b6127c2576040517fe65af6a00000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240161104e565b6127e66127d436889003880188615277565b6001600160a01b038316908787613c05565b5f6127f961108536899003890189615277565b6001600160c01b0381165f908152600e60205260409081902090517fab8a7e3f000000000000000000000000000000000000000000000000000000008152919250735489922f8312c812fbb7184ebf70b9dbfaeed9d49163ab8a7e3f91612864918b906004016155c3565b5f6040518083038186803b15801561287a575f80fd5b505af415801561288c573d5f803e3d5ffd5b506128a1925050506060880160408901614ce5565b6001600160a01b03166128b76020890189614ce5565b6001600160a01b03166001600160c01b0383167f803427d75ce3214f82dc7aa4910635170a6655e2c1663dc03429dd04100cba5a6128fb60408c0160208d0161515c565b6040805167ffffffffffffffff909216825262ffffff808b1660208401528916908201526001600160a01b038716606082015260800160405180910390a461295d61294b36899003890189615277565b6001600160a01b038416908888613c43565b50505050505050565b5f6001600160e01b031982167f80ac58cd0000000000000000000000000000000000000000000000000000000014806129c857506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610c8e57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614610c8e565b5f818152600960205260408120546001600160a01b038116610c8e57604051637e27328960e01b81526004810184905260240161104e565b61144b8383836001613564565b5f612a4e613c81565b90506001600160801b035f80516020615af08339815191525c167ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be422015c6001600160a01b0380831690841603612aa357505050565b806001600160a01b0316836001600160a01b031603612ac157505050565b6040517f74d863650000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301528216602482015260440161104e565b612b11838383613cd6565b61144b576001600160a01b038316612b3f57604051637e27328960e01b81526004810182905260240161104e565b6040517f177e802f0000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024810182905260440161104e565b73020000000000000000000000000000000000000084161561143a5761143a63295b52c560e01b33858585604051602401612bc19493929190615693565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b03861690613d56565b5f6207a11f19627fffff851601600281900b82128281612c2557825f03612c27565b825b62ffffff1690505f612c60612c3c83896155ac565b620f424088612c52578581830615151691040190565b808206151586151691040190565b905082612c7557612c7081615364565b612c77565b805b98975050505050505050565b5f612c8f5f835f612f63565b90506001600160a01b038116610d5557604051637e27328960e01b81526004810183905260240161104e565b805f03612cc6575050565b5f612ccf613c81565b90505f612cdd828585613db3565b9050805f03612cf357612cee613dd1565b61143a565b82810361143a5761143a613e04565b730100000000000000000000000000000000000000851615612d8457612d84635125ce9c60e01b3386868686604051602401612d429594939291906156c2565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526001600160a01b03871690613d56565b5050505050565b6207ffff600282900b1380612db05750612da76207ffff61570c565b60020b8160020b125b15611d5a576040517fce8ef7fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8082604051602001612dfa9190614edb565b60408051601f1981840301815291905280516020909101206001600160c01b03169392505050565b8054600160a01b900467ffffffffffffffff16611d5a576040517f1e3636e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73200000000000000000000000000000000000000084161561143a5761143a633fda46bb60e01b33858585604051602401612bc194939291906157c7565b6001600160a01b038216612ed257604051633250574960e11b81525f600482015260240161104e565b5f612ede83835f612f63565b90506001600160a01b0381161561144b576040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081525f600482015260240161104e565b731000000000000000000000000000000000000000851615612d8457612d8463eba8155960e01b3386868686604051602401612d429594939291906157f8565b5f828152600960205260408120546001600160a01b03831615612f8b57612f8b818486612b06565b6001600160a01b03811615612fc557612fa65f855f80613564565b6001600160a01b0381165f90815260026020526040902080545f190190555b6001600160a01b03851615612ff3576001600160a01b0385165f908152600260205260409020805460010190555b5f84815260096020526040902080546001600160a01b0319166001600160a01b03871617905583856001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4949350505050565b5f306001600160a01b037f000000000000000000000000d4ad5ed9e1436904624b6db8b1be31f36317c636161480156130ba57507f000000000000000000000000000000000000000000000000000000000000009246145b156130e457507fb48fc330d60bb7619feea5289d78c2fd0e5c7576d211c0c0c4e470582e86db3490565b611459604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f75be1fec1bd1466097211759efa67a9b8bbd0c3d59967403e1b47406a219fcdd918101919091527fad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a560608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b728000000000000000000000000000000000000084161561143a5761143a63827e0eb260e01b33858585604051602401612bc19493929190615830565b5f6131ea606084901b6131dd8660020b613e37565b8082061515851691040190565b949350505050565b604080518082019091525f80825260208201526132108484846140ff565b6040805180820190915290546001600160a01b0381168252600160a01b900467ffffffffffffffff166020820152949350505050565b5f80821215613284576040517fa8ce44320000000000000000000000000000000000000000000000000000000081526004810183905260240161104e565b5090565b5f7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821115613284576040517f24775e060000000000000000000000000000000000000000000000000000000081526004810183905260240161104e565b7240000000000000000000000000000000000000851615612d8457612d846348042cf460e01b3386868686604051602401612d42959493929190615858565b73080000000000000000000000000000000000000084161561143a5761143a63fab3c75660e01b33858585604051602401612bc19493929190615917565b730400000000000000000000000000000000000000851615612d8457612d84639eb477b260e01b3386868686604051602401612d42959493929190615948565b5f6133b16005840183614140565b600283900b5f90815260038501602052604090206133ce90614182565b611b0b919061598a565b5f6001600160a01b0382166133ee575047919050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015613449573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c8e91906159ab565b919050565b6005546001600160a01b03163314611d175760405163118cdaa760e01b815233600482015260240161104e565b600680546001600160a01b0319169055611d5a816141c1565b5f8181526009602052604090205460a081901c906134da81600160a01b6153dc565b5f9384526009602052604090932092909255919050565b5f610c8e6134fd613062565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b5f805f8061354888888888614212565b92509250925061355882826142da565b50909695505050505050565b808061357857506001600160a01b03821615155b15613670575f61358784612a00565b90506001600160a01b038316158015906135b35750826001600160a01b0316816001600160a01b031614155b80156135e457506001600160a01b038082165f9081526004602090815260408083209387168352929052205460ff16155b15613626576040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260240161104e565b811561366e5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b50505f90815260036020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60606114597f00000000000000000000000000000000000000000000000000000000000000ff60076143dd565b60606114597f320000000000000000000000000000000000000000000000000000000000000160086143dd565b5f80516020615af08339815191525c7f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b160026001600160801b038316020183815d82600182015d50600181015f80516020615af08339815191525d505050565b5f80516020615af08339815191525c6001600160801b038116806137845763f1c77ed05f526004601cfd5b7f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b15f19909101600202015f815d5f600182015d50600181035f80516020615af08339815191525d50565b5f6001600160a01b03841661381e575f805f8085875af1905080612cee576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f51141617169150508061143a576040517ff27f64e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611b0b6004840183614486565b6001600160a01b038216613904576040517f5b08ba180000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260240161104e565b6001600160a01b038381165f81815260046020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561143a57604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906139b29033908890879087906004016159c2565b6020604051808303815f875af19250505080156139ec575060408051601f3d908101601f191682019092526139e9918101906154a7565b60015b613a53573d808015613a19576040519150601f19603f3d011682016040523d82523d5f602084013e613a1e565b606091505b5080515f03613a4b57604051633250574960e11b81526001600160a01b038516600482015260240161104e565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14612d8457604051633250574960e11b81526001600160a01b038516600482015260240161104e565b6060600a8054610ca290615115565b60605f613aaa836145b4565b60010190505f8167ffffffffffffffff811115613ac957613ac9614faa565b6040519080825280601f01601f191660200182016040528015613af3576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084613afd57509392505050565b5f610c8e82600401614695565b600c80546001600160a01b0319166001600160a01b0383169081179091556040517fef673bbfc2ac7e4d4b810bffda0b15a1f2b48c2aa4d178d3fca87d0d1f337062905f90a250565b5f610c8e82600401614780565b5f6207a11f19627fffff8316016207a120600282900b1380613bc657506207a11f198160020b125b159392505050565b5f6001600160a01b0382161580610c8e57505072400000000000000000000000000000000000006001600160a01b03909116101590565b73800000000000000000000000000000000000000084161561143a5761143a635df4d91860e01b33858585604051602401612bc194939291906159f3565b73400000000000000000000000000000000000000084161561143a5761143a6371ded94360e01b33858585604051602401612bc194939291906159f3565b5f5f80516020615af08339815191525c6001600160801b031680613ca5575f613cd0565b60025f198201027f722b431450ce53c44434ec138439e45a0639fe031b803ee019b776fae5cfa2b1015c5b91505090565b5f6001600160a01b038316158015906131ea5750826001600160a01b0316846001600160a01b03161480613d2e57506001600160a01b038085165f9081526004602090815260408083209387168352929052205460ff165b806131ea5750505f908152600360205260409020546001600160a01b03908116911614919050565b5f80613d6284846147c5565b91509150816001600160e01b031916816001600160e01b0319161461143a576040517f1e048e1d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82601452835f526028600c2082815c01915081815d509392505050565b7001000000000000000000000000000000005f80516020615af08339815191525c035f80516020615af08339815191525d565b7001000000000000000000000000000000005f80516020615af08339815191525c015f80516020615af08339815191525d565b5f613e4182612d8b565b815f600282900b8113613e545781613e5d565b613e5d8261570c565b62ffffff8116915060011615613e81576bfff97272373d413259a469909250613e92565b6c0100000000000000000000000092505b6002811615613eb15760606bfff2e50f5f656932ef12357c8402901c92505b6004811615613ed05760606bffe5caca7e10e4e61c3624ea8402901c92505b6008811615613eef5760606bffcb9843d60f6159c9db58838402901c92505b6010811615613f0e5760606bff973b41fa98c081472e68968402901c92505b6020811615613f2d5760606bff2ea16466c96a3843ec78b38402901c92505b6040811615613f4c5760606bfe5dee046a99a2a811c461f18402901c92505b6080811615613f6b5760606bfcbe86c7900a88aedcffc83b8402901c92505b610100811615613f8b5760606bf987a7253ac413176f2b074c8402901c92505b610200811615613fab5760606bf3392b0822b70005940c7a398402901c92505b610400811615613fcb5760606be7159475a2c29b7443b29c7f8402901c92505b610800811615613feb5760606bd097f3bdfd2022b8845ad8f78402901c92505b61100081161561400b5760606ba9f746462d870fdf8a65dc1f8402901c92505b61200081161561402b5760606b70d869a156d2a1b890bb3df68402901c92505b61400081161561404b5760606b31be135f97d08fd9812315058402901c92505b61800081161561406b5760606b09aa508b5b7a84e1c677de548402901c92505b6201000081161561408b5760606a5d6af8dedb81196699c3298402901c92505b620200008116156140aa576060692216e584f5fa1ea926048402901c92505b620400008116156140c757606067048a170391f7dc428402901c92505b5f8260020b13156140f8576140f5837801000000000000000000000000000000000000000000000000615a7c565b92505b5050919050565b600282900b5f9081526003840160205260408120600401805464ffffffffff841690811061412f5761412f615a9b565b905f5260205f200190509392505050565b600281901c623fffff165f818152602084905260408120549091906003841690600685901b60c0161c67ffffffffffffffff1680151590035b95945050505050565b60015f9081526020829052604081205461419e90826004614873565b5f808052602084905260408120546141b7916004614873565b610c8e9190615aaf565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561424b57505f915060039050826142d0565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa15801561429c573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b0381166142c757505f9250600191508290506142d0565b92505f91508190505b9450945094915050565b5f8260038111156142ed576142ed615ad0565b036142f6575050565b600182600381111561430a5761430a615ad0565b03614341576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600282600381111561435557614355615ad0565b0361438f576040517ffce698f70000000000000000000000000000000000000000000000000000000081526004810182905260240161104e565b60038260038111156143a3576143a3615ad0565b03610d55576040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004810182905260240161104e565b606060ff83146143f7576143f0836148b3565b9050610c8e565b81805461440390615115565b80601f016020809104026020016040519081016040528092919081815260200182805461442f90615115565b801561447a5780601f106144515761010080835404028352916020019161447a565b820191905f5260205f20905b81548152906001019060200180831161445d57829003601f168201915b50505050509050610c8e565b62800000811901600881901c61ffff165f81815260208590526040812054909260ff1690600119821b1680840361458857600883901c80195f9081526020889052604081205460011960ff87161b169081900361455e575f888161450b7f7710c0702d438d37259561c892984b894ff622adfa3d98b5dfe5a9763f94b95460016153dc565b81526020019081526020015f205483600119901b169050805f0361453b57627fffff199650505050505050610c8e565b614544816148f0565b60ff1680195f90815260208b905260409020549093509150505b614567816148f0565b60ff16600883901b179450875f8681526020019081526020015f2054925050505b614591816148f0565b60ff16915062ffffff627fffff19600885901b84170119165b9695505050505050565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106145fc577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310614628576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061464657662386f26fc10000830492506010015b6305f5e100831061465e576305f5e100830492506008015b612710831061467257612710830492506004015b60648310614684576064830492506002015b600a8310610c8e5760010192915050565b5f61469f82614780565b156146d6576040517f4f3d7def00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61471a83826147077f7710c0702d438d37259561c892984b894ff622adfa3d98b5dfe5a9763f94b95460016153dc565b81526020019081526020015f20546148f0565b60ff1690505f61473a845f841981526020019081526020015f20546148f0565b60ff16600883901b1790505f61475f855f8481526020019081526020015f20546148f0565b60ff16905062ffffff627fffff19600884901b831701191695945050505050565b5f81816147ae7f7710c0702d438d37259561c892984b894ff622adfa3d98b5dfe5a9763f94b95460016153dc565b81526020019081526020015f20545f149050919050565b5f805f6147d185614966565b9050602084015192505f80866001600160a01b0316866040516147f49190615ae4565b5f604051808303815f865af19150503d805f811461482d576040519150601f19603f3d011682016040523d82523d5f602084013e614832565b606091505b50915091508161484557614845816149f5565b8080602001905181019061485991906154a7565b9350821561486957614869614a2f565b5050509250929050565b600682901b9290921c915f825b828110156148a857604085901c9467ffffffffffffffff168015019190910190600101614880565b509190039003919050565b60605f6148bf83614a6f565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f8082116148fc575f80fd5b5f7e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff600184190184160260f81c90506040518061012001604052806101008152602001615b106101009139818151811061495757614957615a9b565b016020015160f81c9392505050565b5f6001600160a01b036001600160801b035f80516020615af08339815191525c167ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be422015c1661346d575f80516020615af08339815191525c6001600160801b0316827ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be42282015d50600192915050565b80515f03613a4b576040517f36bc48c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80516020615af08339815191525c6001600160801b03165f7ffcac7593714b88fec0c578a53e9f3f6e4b47eb26c9dcaa7eff23a3ac156be42282015d50565b5f60ff8216601f811115610c8e576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160e01b031981168114611d5a575f80fd5b5f60208284031215614ad4575f80fd5b8135611b0b81614aaf565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611b0b6020830184614adf565b5f60208284031215614b2f575f80fd5b5035919050565b6001600160a01b0381168114611d5a575f80fd5b5f8060408385031215614b5b575f80fd5b8235614b6681614b36565b946020939093013593505050565b5f8083601f840112614b84575f80fd5b50813567ffffffffffffffff811115614b9b575f80fd5b602083019150836020828501011115614bb2575f80fd5b9250929050565b5f805f8385036060811215614bcc575f80fd5b6040811215614bd9575f80fd5b50839250604084013567ffffffffffffffff811115614bf6575f80fd5b614c0286828701614b74565b9497909650939450505050565b5f805f838503610140811215614c23575f80fd5b61012080821215614c32575f80fd5b859450840135905067ffffffffffffffff811115614bf6575f80fd5b5f60c08284031215611bc6575f80fd5b5f60c08284031215614c6e575f80fd5b611b0b8383614c4e565b5f805f60608486031215614c8a575f80fd5b8335614c9581614b36565b92506020840135614ca581614b36565b929592945050506040919091013590565b5f805f60408486031215614cc8575f80fd5b83359250602084013567ffffffffffffffff811115614bf6575f80fd5b5f60208284031215614cf5575f80fd5b8135611b0b81614b36565b5f805f838503610120811215614d14575f80fd5b61010080821215614c32575f80fd5b5f8060408385031215614d34575f80fd5b8235614d3f81614b36565b91506020830135614d4f81614b36565b809150509250929050565b80356001600160c01b038116811461346d575f80fd5b8035600281900b811461346d575f80fd5b5f8060408385031215614d92575f80fd5b614d9b83614d5a565b9150614da960208401614d70565b90509250929050565b5f60208284031215614dc2575f80fd5b611b0b82614d5a565b5f805f805f8060c08789031215614de0575f80fd5b8635614deb81614b36565b95506020870135945060408701359350606087013560ff81168114614e0e575f80fd5b9598949750929560808101359460a0909101359350915050565b7fff00000000000000000000000000000000000000000000000000000000000000881681525f602060e06020840152614e6460e084018a614adf565b8381036040850152614e76818a614adf565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825260208088019350909101905f5b81811015614ec957835183529284019291840191600101614ead565b50909c9b505050505050505050505050565b60c08101610c8e82846001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b5f805f60408486031215614f54575f80fd5b8335614f5f81614b36565b9250602084013567ffffffffffffffff811115614bf6575f80fd5b5f8060408385031215614f8b575f80fd5b8235614f9681614b36565b915060208301358015158114614d4f575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614fe757614fe7614faa565b604052919050565b5f67ffffffffffffffff82111561500857615008614faa565b50601f01601f191660200190565b5f805f8060808587031215615029575f80fd5b843561503481614b36565b9350602085013561504481614b36565b925060408501359150606085013567ffffffffffffffff811115615066575f80fd5b8501601f81018713615076575f80fd5b803561508961508482614fef565b614fbe565b81815288602083850101111561509d575f80fd5b816020840160208301375f6020838301015280935050505092959194509250565b5f80604083850312156150cf575f80fd5b50508035926020909101359150565b5f805f60e084860312156150f0575f80fd5b6150fa8585614c4e565b925060c084013567ffffffffffffffff811115614bf6575f80fd5b600181811c9082168061512957607f821691505b602082108103611bc657634e487b7160e01b5f52602260045260245ffd5b67ffffffffffffffff81168114611d5a575f80fd5b5f6020828403121561516c575f80fd5b8135611b0b81615147565b5f8060408385031215615188575f80fd5b825161519381615147565b6020840151909250614d4f81615147565b5f602082840312156151b4575f80fd5b611b0b82614d70565b803562ffffff8116811461346d575f80fd5b5f60c082840312156151df575f80fd5b60405160c0810181811067ffffffffffffffff8211171561520257615202614faa565b604052905080823561521381614b36565b8152602083013561522381615147565b6020820152604083013561523681614b36565b6040820152615247606084016151bd565b6060820152608083013561525a81614b36565b608082015261526b60a084016151bd565b60a08201525092915050565b5f60c08284031215615287575f80fd5b611b0b83836151cf565b5f61012082840312156152a2575f80fd5b6040516080810181811067ffffffffffffffff821117156152c5576152c5614faa565b6040526152d284846151cf565b81526152e060c08401614d70565b602082015260e08301356152f381615147565b604082015261010083013561530781614b36565b60608201529392505050565b5f60208284031215615323575f80fd5b815164ffffffffff81168114611b0b575f80fd5b5f60208284031215615347575f80fd5b611b0b826151bd565b634e487b7160e01b5f52601160045260245ffd5b5f7f8000000000000000000000000000000000000000000000000000000000000000820361539457615394615350565b505f0390565b5f602082840312156153aa575f80fd5b8151611b0b81615147565b8082018281125f8312801582168215821617156153d4576153d4615350565b505092915050565b80820180821115610c8e57610c8e615350565b81810381811115610c8e57610c8e615350565b5f6101008284031215615413575f80fd5b6040516060810181811067ffffffffffffffff8211171561543657615436614faa565b60405261544384846151cf565b815261545160c08401614d70565b602082015260e083013561546481615147565b60408201529392505050565b8181035f8312801583831316838312821617156125d2576125d2615350565b828152604060208201525f6131ea6040830184614adf565b5f602082840312156154b7575f80fd5b8151611b0b81614aaf565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b0384168152604060208201525f6141796040830184866154c2565b5f6020828403121561551c575f80fd5b815167ffffffffffffffff811115615532575f80fd5b8201601f81018413615542575f80fd5b805161555061508482614fef565b818152856020838501011115615564575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b5f81518060208401855e5f93019283525090919050565b5f6131ea6155a68386615581565b84615581565b8082028115828204841417610c8e57610c8e615350565b82815260e0810182356155d581614b36565b6001600160a01b038082166020850152602085013591506155f582615147565b67ffffffffffffffff821660408501526040850135915061561582614b36565b8082166060850152615629606086016151bd565b915062ffffff80831660808601526080860135925061564783614b36565b81831660a08601528061565c60a088016151bd565b1660c08601525050509392505050565b80358252602081013561567e81615147565b67ffffffffffffffff81166020840152505050565b6001600160a01b03851681526156ac602082018561566c565b608060608201525f6145aa6080830184866154c2565b6001600160a01b03861681526156db602082018661566c565b67ffffffffffffffff8416606082015260a060808201525f61570160a0830184866154c2565b979650505050505050565b5f8160020b627fffff19810361572457615724615350565b5f0392915050565b6157908282516001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b602081015160020b60c0830152604081015167ffffffffffffffff1660e0830152606001516001600160a01b031661010090910152565b5f6101606001600160a01b03871683526157e4602084018761572c565b8061014084015261570181840185876154c2565b5f6101806001600160a01b0388168352615815602084018861572c565b8561014084015280610160840152612c7781840185876154c2565b6001600160a01b0385168152836020820152606060408201525f6145aa6060830184866154c2565b6001600160a01b038616815284602082015267ffffffffffffffff84166040820152608060608201525f6157016080830184866154c2565b6158f48282516001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b602081015160020b60c08301526040015167ffffffffffffffff1660e090910152565b5f6101406001600160a01b03871683526159346020840187615890565b8061012084015261570181840185876154c2565b5f6101606001600160a01b03881683526159656020840188615890565b67ffffffffffffffff861661012084015280610140840152612c7781840185876154c2565b67ffffffffffffffff8281168282160390808211156125d2576125d2615350565b5f602082840312156159bb575f80fd5b5051919050565b5f6001600160a01b038087168352808616602084015250836040830152608060608301526145aa6080830184614adf565b5f6101006001600160a01b0387168352615a6960208401876001600160a01b0380825116835267ffffffffffffffff6020830151166020840152806040830151166040840152606082015162ffffff80821660608601528260808501511660808601528060a08501511660a08601525050505050565b8060e084015261570181840185876154c2565b5f82615a9657634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffd5b67ffffffffffffffff8181168382160190808211156125d2576125d2615350565b634e487b7160e01b5f52602160045260245ffd5b5f611b0b828461558156fe760a9a962ae3d184e99c0483cf5684fb3170f47116ca4f445c50209da4f4f9070001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a264697066735822122064f09b2cf4df87a40a102856d4e12ddac16787c8abd3963f52a4293d32e4b81064736f6c63430008190033

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

    0000000000000000000000004587dd6356d7293e5f10db4d853332bd5b218c0b000000000000000000000000cc92364b6b886158e71fd4e4da5c682d33d1491e00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000002f68747470733a2f2f736f6e69632e6d61726b65742f6170692f6e66742f636861696e732f3134362f6f72646572732f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c68747470733a2f2f736f6e69632e6d61726b65742f6170692f636f6e74726163742f636861696e732f31343600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022536f6e6963204d61726b6574204f72646572626f6f6b204d616b6572204f726465720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012534f4e49432d4d41524b45542d4f524445520000000000000000000000000000

    -----Decoded View---------------
    Arg [0] : owner_ (address): 0x4587dd6356d7293E5f10db4D853332BD5b218C0B
    Arg [1] : defaultProvider_ (address): 0xcC92364b6B886158e71Fd4e4Da5C682D33d1491e
    Arg [2] : baseURI_ (string): https://sonic.market/api/nft/chains/146/orders/
    Arg [3] : contractURI_ (string): https://sonic.market/api/contract/chains/146
    Arg [4] : name_ (string): Sonic Market Orderbook Maker Order
    Arg [5] : symbol_ (string): SONIC-MARKET-ORDER

    -----Encoded View---------------
    17 Constructor Arguments found :
    Arg [0] : 0000000000000000000000004587dd6356d7293e5f10db4d853332bd5b218c0b
    Arg [1] : 000000000000000000000000cc92364b6b886158e71fd4e4da5c682d33d1491e
    Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
    Arg [3] : 0000000000000000000000000000000000000000000000000000000000000120
    Arg [4] : 0000000000000000000000000000000000000000000000000000000000000180
    Arg [5] : 00000000000000000000000000000000000000000000000000000000000001e0
    Arg [6] : 000000000000000000000000000000000000000000000000000000000000002f
    Arg [7] : 68747470733a2f2f736f6e69632e6d61726b65742f6170692f6e66742f636861
    Arg [8] : 696e732f3134362f6f72646572732f0000000000000000000000000000000000
    Arg [9] : 000000000000000000000000000000000000000000000000000000000000002c
    Arg [10] : 68747470733a2f2f736f6e69632e6d61726b65742f6170692f636f6e74726163
    Arg [11] : 742f636861696e732f3134360000000000000000000000000000000000000000
    Arg [12] : 0000000000000000000000000000000000000000000000000000000000000022
    Arg [13] : 536f6e6963204d61726b6574204f72646572626f6f6b204d616b6572204f7264
    Arg [14] : 6572000000000000000000000000000000000000000000000000000000000000
    Arg [15] : 0000000000000000000000000000000000000000000000000000000000000012
    Arg [16] : 534f4e49432d4d41524b45542d4f524445520000000000000000000000000000


    Block Age Transaction Gas Used Reward
    view all blocks ##produced##

    Block Age Uncle Number Difficulty Gas Used Reward
    View All Uncles
    Loading...
    Loading
    Loading...
    Loading

    Validator Index Block Age Amount
    View All Withdrawals

    Transaction Hash Block Age Value Eth2 PubKey Valid
    View All Deposits
    [ 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.