ETH Price: $3,294.74 (-1.10%)

Token

Concave A Token (aCNV) (aCNV)
 

Overview

Max Total Supply

171,859.040958138682675701 aCNV

Holders

2,622

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
30 aCNV

Value
$0.00
0x1C47B2dD29E500e6535592DD617792C3118E1c1C
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
aCNV

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license
/**
 *Submitted for verification at Etherscan.io on 2022-02-02
*/

// SPDX-License-Identifier: WTFPL
pragma solidity >=0.8.0;



/**

     ██████╗ ██████╗ ███╗   ██╗ ██████╗ █████╗ ██╗   ██╗██████╗
    ██╔════╝██╔═══██╗████╗  ██║██╔════╝██╔══██╗██║   ██║╚════██╗
    ██║     ██║   ██║██╔██╗ ██║██║     ███████║██║   ██║ █████╔╝
    ██║     ██║   ██║██║╚██╗██║██║     ██╔══██║╚██╗ ██╔╝ ╚═══██╗
    ╚██████╗╚██████╔╝██║ ╚████║╚██████╗██║  ██║ ╚████╔╝ ██████╔╝
     ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝╚═╝  ╚═╝  ╚═══╝  ╚═════╝

    Concave A Token

*/

/* -------------------------------------------------------------------------- */
/*                                   IMPORTS                                  */
/* -------------------------------------------------------------------------- */

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*///////////////////////////////////////////////////////////////
                                  EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*///////////////////////////////////////////////////////////////
                             METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*///////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*///////////////////////////////////////////////////////////////
                             EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    bytes32 public constant PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*///////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*///////////////////////////////////////////////////////////////
                              ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*///////////////////////////////////////////////////////////////
                              EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            bytes32 digest = keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    DOMAIN_SEPARATOR(),
                    keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                )
            );

            address recoveredAddress = ecrecover(digest, v, r, s);

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*///////////////////////////////////////////////////////////////
                       INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
library SafeTransferLib {
    /*///////////////////////////////////////////////////////////////
                            ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool callStatus;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            callStatus := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(callStatus, "ETH_TRANSFER_FAILED");
    }

    /*///////////////////////////////////////////////////////////////
                           ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool callStatus;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.

            // Call the token and store if it succeeded or not.
            // We use 100 because the calldata length is 4 + 32 * 3.
            callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)
        }

        require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool callStatus;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.

            // Call the token and store if it succeeded or not.
            // We use 68 because the calldata length is 4 + 32 * 2.
            callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
        }

        require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool callStatus;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.

            // Call the token and store if it succeeded or not.
            // We use 68 because the calldata length is 4 + 32 * 2.
            callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
        }

        require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED");
    }

    /*///////////////////////////////////////////////////////////////
                         INTERNAL HELPER LOGIC
    //////////////////////////////////////////////////////////////*/

    function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) {
        assembly {
            // Get how many bytes the call returned.
            let returnDataSize := returndatasize()

            // If the call reverted:
            if iszero(callStatus) {
                // Copy the revert message into memory.
                returndatacopy(0, 0, returnDataSize)

                // Revert with the same message.
                revert(0, returnDataSize)
            }

            switch returnDataSize
            case 32 {
                // Copy the return data into memory.
                returndatacopy(0, 0, returnDataSize)

                // Set success to whether it returned true.
                success := iszero(iszero(mload(0)))
            }
            case 0 {
                // There was no return data.
                success := 1
            }
            default {
                // It returned some malformed input.
                success := 0
            }
        }
    }
}
/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}
/// @notice Concave A Token
/// @author 0xBarista & Dionysus (ConcaveFi)
contract aCNV is ERC20("Concave A Token (aCNV)", "aCNV", 18) {

    /* ---------------------------------------------------------------------- */
    /*                                DEPENDENCIES                            */
    /* ---------------------------------------------------------------------- */

    using SafeTransferLib for ERC20;

    /* ---------------------------------------------------------------------- */
    /*                             IMMUTABLE STATE                            */
    /* ---------------------------------------------------------------------- */

    /// @notice FRAX tokenIn address
    ERC20 public immutable FRAX = ERC20(0x853d955aCEf822Db058eb8505911ED77F175b99e);

    /// @notice DAI tokenIn address
    ERC20 public immutable DAI = ERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);

    /// @notice Error related to amount
    string constant AMOUNT_ERROR = "!AMOUNT";

    /// @notice Error related to token address
    string constant TOKEN_IN_ERROR = "!TOKEN_IN";

    /// @notice Error minting exceeds supply
    string constant EXCEEDS_SUPPLY = "EXCEEDS_SUPPLY";

    /// @notice Error transfers paused
    string constant PAUSED = "PAUSED";

    /* ---------------------------------------------------------------------- */
    /*                              MUTABLE STATE                             */
    /* ---------------------------------------------------------------------- */

    /// @notice Address that is recipient of raised funds + access control
    address public treasury = 0x226e7AF139a0F34c6771DeB252F9988876ac1Ced;

    /// @notice Returns the current merkle root being used
    bytes32 public merkleRoot;

    /// @notice Returns an array of all merkle roots used
    bytes32[] public roots;

    /// @notice Returns the current pCNV price in DAI/FRAX
    uint256 public rate;

    /// @notice Returns the max supply of pCNV that is allowed to be minted (in total)
    uint256 public maxSupply = 333_000 * 1e18;

    /// @notice Returns the total amount of pCNV that has cumulatively been minted
    uint256 public totalMinted;

    /// @notice Returns whether transfers are paused
    bool public transfersPaused = true;

    /* ---------------------------------------------------------------------- */
    /*                              STRUCTURED STATE                          */
    /* ---------------------------------------------------------------------- */

    /// @notice Structure of Participant vesting storage
    struct Participant {
        uint256 purchased; // amount (in total) of pCNV that user has purchased
        uint256 redeemed;  // amount (in total) of pCNV that user has redeemed
    }

    /// @notice             maps an account to vesting storage
    /// address             - account to check
    /// returns Participant - Structured vesting storage
    mapping(address => Participant) public participants;

    /// @notice             amount of DAI/FRAX user has spent for a specific root
    /// bytes32             - merkle root
    /// address             - account to check
    /// returns uint256     - amount in DAI/FRAX (denominated in ether) spent purchasing pCNV
    mapping(bytes32 => mapping(address => uint256)) public spentAmounts;

    /* ---------------------------------------------------------------------- */
    /*                                  EVENTS                                */
    /* ---------------------------------------------------------------------- */

    /// @notice Emitted when treasury changes treasury address
    /// @param  treasury address of new treasury
    event TreasurySet(address treasury);

    /// @notice             Emitted when a new round is set by treasury
    /// @param  merkleRoot  new merkle root
    /// @param  rate        new price of pCNV in DAI/FRAX
    event NewRound(bytes32 merkleRoot, uint256 rate);

    /// @notice             Emitted when maxSupply of pCNV is burned or minted to target
    /// @param  target      target to which to mint pCNV or burn if target = address(0)
    /// @param  amount      amount of pCNV minted to target or burned
    /// @param  totalMinted amount of pCNV minted to target or burned
    event Managed(address target, uint256 amount, uint256 totalMinted);

    /// @notice                 Emitted when pCNV minted via "mint()" or "mintWithPermit"
    /// @param  depositedFrom   address from which DAI/FRAX was deposited
    /// @param  mintedTo        address to which pCNV were minted to
    /// @param  amount          amount of pCNV minted
    /// @param  deposited       amount of DAI/FRAX deposited
    /// @param  totalMinted     total amount of pCNV minted so far
    event Minted(
        address indexed depositedFrom,
        address indexed mintedTo,
        uint256 amount,
        uint256 deposited,
        uint256 totalMinted
    );

    /// @notice                 Emitted when Concave changes max supply
    /// @param  oldMax          old max supply
    /// @param  newMax          new max supply
    event SupplyChanged(uint256 oldMax, uint256 newMax);

    /* ---------------------------------------------------------------------- */
    /*                                MODIFIERS                               */
    /* ---------------------------------------------------------------------- */

    /// @notice only allows Concave treasury
    modifier onlyConcave() {
        require(msg.sender == treasury, "!CONCAVE");
        _;
    }

    /* ---------------------------------------------------------------------- */
    /*                              ONLY CONCAVE                              */
    /* ---------------------------------------------------------------------- */

    /// @notice Set a new treasury address if treasury
    function setTreasury(
        address _treasury
    ) external onlyConcave {
        treasury = _treasury;
        emit TreasurySet(_treasury);
    }

    /// @notice             Update merkle root and rate
    /// @param _merkleRoot  root of merkle tree
    /// @param _rate        price of pCNV in DAI/FRAX
    function setRound(
        bytes32 _merkleRoot,
        uint256 _rate
    ) external onlyConcave {
        // push new root to array of all roots - for viewing
        roots.push(_merkleRoot);
        // update merkle root
        merkleRoot = _merkleRoot;
        // update rate
        rate = _rate;

        emit NewRound(merkleRoot,rate);
    }

    /// @notice         mint amount to target
    /// @param target   address to which to mint; if address(0), will burn
    /// @param amount   to reduce from max supply or mint to "target"
    function manage(
        address target,
        uint256 amount
    ) external onlyConcave {
        uint256 newAmount = totalMinted + amount;
        require(newAmount <= maxSupply,EXCEEDS_SUPPLY);
        totalMinted = newAmount;
        // mint target amount
        _mint(target, amount);
        emit Managed(target, amount, totalMinted);
    }

    /// @notice             manage max supply
    /// @param _maxSupply   new max supply
    function manageSupply(uint256 _maxSupply) external onlyConcave {
        require(_maxSupply >= totalMinted, "LOWER_THAN_MINT");
        emit SupplyChanged(maxSupply, _maxSupply);
        maxSupply = _maxSupply;
    }

    /// @notice         Allows Concave to pause transfers in the event of a bug
    /// @param paused   if transfers should be paused or not
    function setTransfersPaused(bool paused) external onlyConcave {
        transfersPaused = paused;
    }

    /* ---------------------------------------------------------------------- */
    /*                              PUBLIC LOGIC                              */
    /* ---------------------------------------------------------------------- */

    /// @notice               mint pCNV by providing merkle proof and depositing DAI/FRAX
    /// @param to             whitelisted address pCNV will be minted to
    /// @param tokenIn        address of tokenIn user wishes to deposit (DAI/FRAX)
    /// @param maxAmount      max amount of DAI/FRAX sender can deposit for pCNV, to verify merkle proof
    /// @param amountIn       amount of DAI/FRAX sender wishes to deposit for pCNV
    /// @param proof          merkle proof to prove "to" and "maxAmount" are in merkle tree
    function mint(
        address to,
        address tokenIn,
        uint256 maxAmount,
        uint256 amountIn,
        bytes32[] calldata proof
    ) external returns (uint256 amountOut) {
        return _purchase(msg.sender, to, tokenIn, maxAmount, amountIn, proof);
    }

    /// @notice               mint pCNV by providing merkle proof and depositing DAI; uses EIP-2612 permit to save a transaction
    /// @param to             whitelisted address pCNV will be minted to
    /// @param tokenIn        address of tokenIn user wishes to deposit (DAI)
    /// @param maxAmount      max amount of DAI sender can deposit for pCNV, to verify merkle proof
    /// @param amountIn       amount of DAI sender wishes to deposit for pCNV
    /// @param proof          merkle proof to prove "to" and "maxAmount" are in merkle tree
    /// @param permitDeadline EIP-2612 : time when permit is no longer valid
    /// @param v              EIP-2612 : part of EIP-2612 signature
    /// @param r              EIP-2612 : part of EIP-2612 signature
    /// @param s              EIP-2612 : part of EIP-2612 signature
    function mintWithPermit(
        address to,
        address tokenIn,
        uint256 maxAmount,
        uint256 amountIn,
        bytes32[] calldata proof,
        uint256 permitDeadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountOut) {
        // Make sure payment tokenIn is DAI
        require(tokenIn == address(DAI), TOKEN_IN_ERROR);
        // Approve tokens for spender - https://eips.ethereum.org/EIPS/eip-2612
        ERC20(tokenIn).permit(msg.sender, address(this), amountIn, permitDeadline, v, r, s);
        // allow sender to mint for "to"
        return _purchase(msg.sender, to, tokenIn, maxAmount, amountIn, proof);
    }

    /// @notice         transfer "amount" of tokens from msg.sender to "to"
    /// @dev            calls "_beforeTransfer" to update vesting storage for "from" and "to"
    /// @param to       address tokens are being sent to
    /// @param amount   number of tokens being transfered
    function transfer(
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        require(!transfersPaused,PAUSED);
        // default ERC20 transfer
        return super.transfer(to, amount);
    }

    /// @notice         transfer "amount" of tokens from "from" to "to"
    /// @dev            calls "_beforeTransfer" to update vesting storage for "from" and "to"
    /// @param from     address tokens are being transfered from
    /// @param to       address tokens are being sent to
    /// @param amount   number of tokens being transfered
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        require(!transfersPaused,PAUSED);
        // default ERC20 transfer
        return super.transferFrom(from, to, amount);
    }

    /* ---------------------------------------------------------------------- */
    /*                             INTERNAL LOGIC                             */
    /* ---------------------------------------------------------------------- */

    /// @notice               Deposits FRAX/DAI for pCNV if merkle proof exists in specified round
    /// @param sender         address sending transaction
    /// @param to             whitelisted address purchased pCNV will be sent to
    /// @param tokenIn        address of tokenIn user wishes to deposit
    /// @param maxAmount      max amount of DAI/FRAX sender can deposit for pCNV
    /// @param amountIn       amount of DAI/FRAX sender wishes to deposit for pCNV
    /// @param proof          merkle proof to prove address and amount are in tree
    function _purchase(
        address sender,
        address to,
        address tokenIn,
        uint256 maxAmount,
        uint256 amountIn,
        bytes32[] calldata proof
    ) internal returns(uint256 amountOut) {
        // Make sure payment tokenIn is either DAI or FRAX
        require(tokenIn == address(DAI) || tokenIn == address(FRAX), TOKEN_IN_ERROR);

        // Require merkle proof with `to` and `maxAmount` to be successfully verified
        require(MerkleProof.verify(proof, merkleRoot, keccak256(abi.encodePacked(to, maxAmount))), "!PROOF");

        // Verify amount claimed by user does not surpass "maxAmount"
        uint256 newAmount = spentAmounts[merkleRoot][to] + amountIn; // save gas
        require(newAmount <= maxAmount, AMOUNT_ERROR);
        spentAmounts[merkleRoot][to] = newAmount;

        // Calculate rate of pCNV that should be returned for "amountIn"
        amountOut = amountIn * 1e18 / rate;

        // make sure total minted + amount is less than or equal to maximum supply
        require(totalMinted + amountOut <= maxSupply, EXCEEDS_SUPPLY);

        // Interface storage for participant
        Participant storage participant = participants[to];

        // Increase participant.purchased to account for newly purchased tokens
        participant.purchased += amountOut;

        // Increase totalMinted to account for newly minted supply
        totalMinted += amountOut;

        // Transfer amountIn*ratio of tokenIn to treasury address
        ERC20(tokenIn).safeTransferFrom(sender, treasury, amountIn);

        // Mint tokens to address after pulling
        _mint(to, amountOut);

        emit Minted(sender, to, amountOut, amountIn, totalMinted);
    }

    /// @notice         Rescues accidentally sent tokens and ETH
    /// @param token    address of token to rescue, if address(0) rescue ETH
    function rescue(address token) external onlyConcave {
        if (token == address(0)) payable(treasury).transfer( address(this).balance );
        else ERC20(token).transfer(treasury, ERC20(token).balanceOf(address(this)));
    }
}

/**

    "someone spent a lot of computational power and time to bruteforce that contract address
    so basically to have that many leading zeros
    you can't just create a contract and get that, the odds are 1 in trillions to get something like that
    there's a way to guess which contract address you will get, using a script.. and you have to bruteforce for a very long time to get that many leading 0's
    fun fact, the more leading 0's a contract has, the cheaper gas will be for users to interact with the contract"

        - some solidity dev

    © 2022 WTFPL – Do What the Fuck You Want to Public License.
*/

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalMinted","type":"uint256"}],"name":"Managed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositedFrom","type":"address"},{"indexed":true,"internalType":"address","name":"mintedTo","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deposited","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalMinted","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"}],"name":"NewRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMax","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMax","type":"uint256"}],"name":"SupplyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"treasury","type":"address"}],"name":"TreasurySet","type":"event"},{"inputs":[],"name":"DAI","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRAX","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"manage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"manageSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"maxAmount","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"maxAmount","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"permitDeadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"mintWithPermit","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"participants","outputs":[{"internalType":"uint256","name":"purchased","type":"uint256"},{"internalType":"uint256","name":"redeemed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","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":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"roots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setTransfersPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"spentAmounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transfersPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

61012060405273853d955acef822db058eb8505911ed77f175b99e60e052736b175474e89094c44da98b954eedeac495271d0f61010052600680546001600160a01b03191673226e7af139a0f34c6771deb252f9988876ac1ced179055694683f7570a6296200000600a55600c805460ff191660011790553480156200008457600080fd5b50604080518082018252601681527f436f6e63617665204120546f6b656e202861434e56290000000000000000000060208083019182528351808501909452600484526330a1a72b60e11b908401528151919291601291620000ea9160009190620001bf565b50815162000100906001906020850190620001bf565b5060ff81166080524660a0526200011662000123565b60c0525062000346915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620001579190620002a2565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b828054620001cd9062000265565b90600052602060002090601f016020900481019282620001f157600085556200023c565b82601f106200020c57805160ff19168380011785556200023c565b828001600101855582156200023c579182015b828111156200023c5782518255916020019190600101906200021f565b506200024a9291506200024e565b5090565b5b808211156200024a57600081556001016200024f565b600181811c908216806200027a57607f821691505b602082108114156200029c57634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c915080831680620002bf57607f831692505b6020808410821415620002e057634e487b7160e01b86526022600452602486fd5b818015620002f75760018114620003095762000338565b60ff1986168952848901965062000338565b60008a81526020902060005b86811015620003305781548b82015290850190830162000315565b505084890196505b509498975050505050505050565b60805160a05160c05160e05161010051611c16620003a0600039600081816104ea01528181610a0f0152611131015260008181610443015261116c015260006108410152600061080c0152600061032d0152611c166000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806370a082311161010f578063c2b40ae4116100a2578063d5abeb0111610071578063d5abeb01146104b1578063dd62ed3e146104ba578063e0bab4c4146104e5578063f0f442601461050c57600080fd5b8063c2b40ae414610465578063c89380fd14610478578063cc9d3ddb1461048b578063d505accf1461049e57600080fd5b806396fb8b10116100de57806396fb8b101461040f578063a2309ff814610422578063a9059cbb1461042b578063b0e4556f1461043e57600080fd5b806370a08231146103b45780637ecebe00146103d4578063839006f2146103f457806395d89b411461040757600080fd5b80632c4e722e116101875780633644e515116101565780633644e5151461036157806344e46dff146103695780634563f30a1461037c57806361d027b31461038957600080fd5b80632c4e722e146102ef5780632eb4a7ab146102f857806330adf81f14610301578063313ce5671461032857600080fd5b80630cf5e156116101c35780630cf5e15614610287578063103a34721461029a57806318160ddd146102d357806323b872dd146102dc57600080fd5b806306fdde03146101f5578063095ea7b31461021357806309e69ede146102365780630b0eee3014610272575b600080fd5b6101fd61051f565b60405161020a9190611667565b60405180910390f35b6102266102213660046116d8565b6105ad565b604051901515815260200161020a565b61025d610244366004611702565b600d602052600090815260409020805460019091015482565b6040805192835260208301919091520161020a565b6102856102803660046116d8565b610619565b005b61028561029536600461171d565b61070a565b6102c56102a836600461173f565b600e60209081526000928352604080842090915290825290205481565b60405190815260200161020a565b6102c560025481565b6102266102ea36600461176b565b6107b0565b6102c560095481565b6102c560075481565b6102c57f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b61034f7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161020a565b6102c5610808565b6102856103773660046117b5565b610863565b600c546102269060ff1681565b60065461039c906001600160a01b031681565b6040516001600160a01b03909116815260200161020a565b6102c56103c2366004611702565b60036020526000908152604090205481565b6102c56103e2366004611702565b60056020526000908152604090205481565b610285610402366004611702565b6108a0565b6101fd6109fe565b6102c561041d36600461182f565b610a0b565b6102c5600b5481565b6102266104393660046116d8565b610b25565b61039c7f000000000000000000000000000000000000000000000000000000000000000081565b6102c56104733660046118d5565b610b7b565b6102c56104863660046118ee565b610b9c565b6102856104993660046118d5565b610bb8565b6102856104ac366004611966565b610c67565b6102c5600a5481565b6102c56104c83660046119d0565b600460209081526000928352604080842090915290825290205481565b61039c7f000000000000000000000000000000000000000000000000000000000000000081565b61028561051a366004611702565b610eb8565b6000805461052c906119fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610558906119fa565b80156105a55780601f1061057a576101008083540402835291602001916105a5565b820191906000526020600020905b81548152906001019060200180831161058857829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106089086815260200190565b60405180910390a350600192915050565b6006546001600160a01b0316331461064c5760405162461bcd60e51b815260040161064390611a35565b60405180910390fd5b600081600b5461065c9190611a6d565b9050600a548111156040518060400160405280600e81526020016d455843454544535f535550504c5960901b815250906106a95760405162461bcd60e51b81526004016106439190611667565b50600b8190556106b98383610f36565b600b54604080516001600160a01b03861681526020810185905280820192909252517fc5c33ab5e6467a87a001b77efc45aa27f6890b08565b99b7101becae3d82320e9181900360600190a1505050565b6006546001600160a01b031633146107345760405162461bcd60e51b815260040161064390611a35565b600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018290556007829055600981905560408051838152602081018390527fc9714d3f318877e8200732d0c1e80981c397cbde2518a4b32c68d9ba1eab3b50910160405180910390a15050565b600c5460408051808201909152600681526514105554d15160d21b602082015260009160ff16156107f45760405162461bcd60e51b81526004016106439190611667565b50610800848484610fa1565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461083e57610839611093565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6006546001600160a01b0316331461088d5760405162461bcd60e51b815260040161064390611a35565b600c805460ff1916911515919091179055565b6006546001600160a01b031633146108ca5760405162461bcd60e51b815260040161064390611a35565b6001600160a01b038116610915576006546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610911573d6000803e3d6000fd5b5050565b6006546040516370a0823160e01b81523060048201526001600160a01b038381169263a9059cbb9291169083906370a0823190602401602060405180830381865afa158015610968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098c9190611a85565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109119190611a9e565b50565b6001805461052c906119fa565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168a6001600160a01b0316146040518060400160405280600981526020016810aa27a5a2a72fa4a760b91b81525090610a825760405162461bcd60e51b81526004016106439190611667565b5060405163d505accf60e01b8152336004820152306024820152604481018990526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b038b169063d505accf9060e401600060405180830381600087803b158015610aef57600080fd5b505af1158015610b03573d6000803e3d6000fd5b50505050610b16338c8c8c8c8c8c61112d565b9b9a5050505050505050505050565b600c5460408051808201909152600681526514105554d15160d21b602082015260009160ff1615610b695760405162461bcd60e51b81526004016106439190611667565b50610b74838361148a565b9392505050565b60088181548110610b8b57600080fd5b600091825260209091200154905081565b6000610bad3388888888888861112d565b979650505050505050565b6006546001600160a01b03163314610be25760405162461bcd60e51b815260040161064390611a35565b600b54811015610c265760405162461bcd60e51b815260206004820152600f60248201526e1313d5d15497d512105397d3525395608a1b6044820152606401610643565b600a5460408051918252602082018390527fed89e864eaa767d73408242ff6a09be53504bda6578087e3cc94dc198390488c910160405180910390a1600a55565b42841015610cb75760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610643565b6000610cc1610808565b6001600160a01b0389811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015610dda573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610e105750886001600160a01b0316816001600160a01b0316145b610e4d5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610643565b6001600160a01b0390811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6006546001600160a01b03163314610ee25760405162461bcd60e51b815260040161064390611a35565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527f3c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f9060200160405180910390a150565b8060026000828254610f489190611a6d565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610ffd57610fd88382611abb565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290611025908490611abb565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906110809087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516110c59190611ad2565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614806111a057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b0316145b6040518060400160405280600981526020016810aa27a5a2a72fa4a760b91b815250906111e05760405162461bcd60e51b81526004016106439190611667565b5061125e838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506007546040516bffffffffffffffffffffffff1960608e901b166020820152603481018b9052909250605401905060405160208183030381529060405280519060200120611502565b6112935760405162461bcd60e51b815260206004820152600660248201526510a82927a7a360d11b6044820152606401610643565b6007546000908152600e602090815260408083206001600160a01b038b1684529091528120546112c4908690611a6d565b9050858111156040518060400160405280600781526020016608505353d5539560ca1b815250906113085760405162461bcd60e51b81526004016106439190611667565b506007546000908152600e602090815260408083206001600160a01b038c168452909152902081905560095461134686670de0b6b3a7640000611b6e565b6113509190611b8d565b9150600a5482600b546113639190611a6d565b11156040518060400160405280600e81526020016d455843454544535f535550504c5960901b815250906113aa5760405162461bcd60e51b81526004016106439190611667565b506001600160a01b0388166000908152600d602052604081208054909184918391906113d7908490611a6d565b9250508190555082600b60008282546113f09190611a6d565b9091555050600654611411906001600160a01b038a8116918d911689611518565b61141b8984610f36565b886001600160a01b03168a6001600160a01b03167f68c721f9a38584842eb66945b43c95066397ce5f2576fcc0588471c85d209d0c8589600b54604051611475939291909283526020830191909152604082015260600190565b60405180910390a35050979650505050505050565b336000908152600360205260408120805483919083906114ab908490611abb565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906106089086815260200190565b60008261150f85846115ac565b14949350505050565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af191505061156281611620565b6115a55760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610643565b5050505050565b600081815b84518110156116185760008582815181106115ce576115ce611baf565b602002602001015190508083116115f45760008381526020829052604090209250611605565b600081815260208490526040902092505b508061161081611bc5565b9150506115b1565b509392505050565b60003d8261163257806000803e806000fd5b806020811461164a57801561165b5760009250611660565b816000803e60005115159250611660565b600192505b5050919050565b600060208083528351808285015260005b8181101561169457858101830151858201604001528201611678565b818111156116a6576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146116d357600080fd5b919050565b600080604083850312156116eb57600080fd5b6116f4836116bc565b946020939093013593505050565b60006020828403121561171457600080fd5b610b74826116bc565b6000806040838503121561173057600080fd5b50508035926020909101359150565b6000806040838503121561175257600080fd5b82359150611762602084016116bc565b90509250929050565b60008060006060848603121561178057600080fd5b611789846116bc565b9250611797602085016116bc565b9150604084013590509250925092565b80151581146109fb57600080fd5b6000602082840312156117c757600080fd5b8135610b74816117a7565b60008083601f8401126117e457600080fd5b50813567ffffffffffffffff8111156117fc57600080fd5b6020830191508360208260051b850101111561181757600080fd5b9250929050565b803560ff811681146116d357600080fd5b6000806000806000806000806000806101208b8d03121561184f57600080fd5b6118588b6116bc565b995061186660208c016116bc565b985060408b0135975060608b0135965060808b013567ffffffffffffffff81111561189057600080fd5b61189c8d828e016117d2565b90975095505060a08b013593506118b560c08c0161181e565b925060e08b013591506101008b013590509295989b9194979a5092959850565b6000602082840312156118e757600080fd5b5035919050565b60008060008060008060a0878903121561190757600080fd5b611910876116bc565b955061191e602088016116bc565b94506040870135935060608701359250608087013567ffffffffffffffff81111561194857600080fd5b61195489828a016117d2565b979a9699509497509295939492505050565b600080600080600080600060e0888a03121561198157600080fd5b61198a886116bc565b9650611998602089016116bc565b955060408801359450606088013593506119b46080890161181e565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156119e357600080fd5b6119ec836116bc565b9150611762602084016116bc565b600181811c90821680611a0e57607f821691505b60208210811415611a2f57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526008908201526721434f4e4341564560c01b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611a8057611a80611a57565b500190565b600060208284031215611a9757600080fd5b5051919050565b600060208284031215611ab057600080fd5b8151610b74816117a7565b600082821015611acd57611acd611a57565b500390565b600080835481600182811c915080831680611aee57607f831692505b6020808410821415611b0e57634e487b7160e01b86526022600452602486fd5b818015611b225760018114611b3357611b60565b60ff19861689528489019650611b60565b60008a81526020902060005b86811015611b585781548b820152908501908301611b3f565b505084890196505b509498975050505050505050565b6000816000190483118215151615611b8857611b88611a57565b500290565b600082611baa57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611bd957611bd9611a57565b506001019056fea264697066735822122024da44e9750308f2d69fff0dedf0be4fc4d6018a2c6e023be96c87ebd431cc9464736f6c634300080b0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806370a082311161010f578063c2b40ae4116100a2578063d5abeb0111610071578063d5abeb01146104b1578063dd62ed3e146104ba578063e0bab4c4146104e5578063f0f442601461050c57600080fd5b8063c2b40ae414610465578063c89380fd14610478578063cc9d3ddb1461048b578063d505accf1461049e57600080fd5b806396fb8b10116100de57806396fb8b101461040f578063a2309ff814610422578063a9059cbb1461042b578063b0e4556f1461043e57600080fd5b806370a08231146103b45780637ecebe00146103d4578063839006f2146103f457806395d89b411461040757600080fd5b80632c4e722e116101875780633644e515116101565780633644e5151461036157806344e46dff146103695780634563f30a1461037c57806361d027b31461038957600080fd5b80632c4e722e146102ef5780632eb4a7ab146102f857806330adf81f14610301578063313ce5671461032857600080fd5b80630cf5e156116101c35780630cf5e15614610287578063103a34721461029a57806318160ddd146102d357806323b872dd146102dc57600080fd5b806306fdde03146101f5578063095ea7b31461021357806309e69ede146102365780630b0eee3014610272575b600080fd5b6101fd61051f565b60405161020a9190611667565b60405180910390f35b6102266102213660046116d8565b6105ad565b604051901515815260200161020a565b61025d610244366004611702565b600d602052600090815260409020805460019091015482565b6040805192835260208301919091520161020a565b6102856102803660046116d8565b610619565b005b61028561029536600461171d565b61070a565b6102c56102a836600461173f565b600e60209081526000928352604080842090915290825290205481565b60405190815260200161020a565b6102c560025481565b6102266102ea36600461176b565b6107b0565b6102c560095481565b6102c560075481565b6102c57f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b61034f7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161020a565b6102c5610808565b6102856103773660046117b5565b610863565b600c546102269060ff1681565b60065461039c906001600160a01b031681565b6040516001600160a01b03909116815260200161020a565b6102c56103c2366004611702565b60036020526000908152604090205481565b6102c56103e2366004611702565b60056020526000908152604090205481565b610285610402366004611702565b6108a0565b6101fd6109fe565b6102c561041d36600461182f565b610a0b565b6102c5600b5481565b6102266104393660046116d8565b610b25565b61039c7f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e81565b6102c56104733660046118d5565b610b7b565b6102c56104863660046118ee565b610b9c565b6102856104993660046118d5565b610bb8565b6102856104ac366004611966565b610c67565b6102c5600a5481565b6102c56104c83660046119d0565b600460209081526000928352604080842090915290825290205481565b61039c7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f81565b61028561051a366004611702565b610eb8565b6000805461052c906119fa565b80601f0160208091040260200160405190810160405280929190818152602001828054610558906119fa565b80156105a55780601f1061057a576101008083540402835291602001916105a5565b820191906000526020600020905b81548152906001019060200180831161058857829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106089086815260200190565b60405180910390a350600192915050565b6006546001600160a01b0316331461064c5760405162461bcd60e51b815260040161064390611a35565b60405180910390fd5b600081600b5461065c9190611a6d565b9050600a548111156040518060400160405280600e81526020016d455843454544535f535550504c5960901b815250906106a95760405162461bcd60e51b81526004016106439190611667565b50600b8190556106b98383610f36565b600b54604080516001600160a01b03861681526020810185905280820192909252517fc5c33ab5e6467a87a001b77efc45aa27f6890b08565b99b7101becae3d82320e9181900360600190a1505050565b6006546001600160a01b031633146107345760405162461bcd60e51b815260040161064390611a35565b600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018290556007829055600981905560408051838152602081018390527fc9714d3f318877e8200732d0c1e80981c397cbde2518a4b32c68d9ba1eab3b50910160405180910390a15050565b600c5460408051808201909152600681526514105554d15160d21b602082015260009160ff16156107f45760405162461bcd60e51b81526004016106439190611667565b50610800848484610fa1565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000001461461083e57610839611093565b905090565b507f2555e92d6bf1d6a3c838720495aa66e7b5c46f5aabaf84b6a4948c027de7557390565b6006546001600160a01b0316331461088d5760405162461bcd60e51b815260040161064390611a35565b600c805460ff1916911515919091179055565b6006546001600160a01b031633146108ca5760405162461bcd60e51b815260040161064390611a35565b6001600160a01b038116610915576006546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610911573d6000803e3d6000fd5b5050565b6006546040516370a0823160e01b81523060048201526001600160a01b038381169263a9059cbb9291169083906370a0823190602401602060405180830381865afa158015610968573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098c9190611a85565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109119190611a9e565b50565b6001805461052c906119fa565b60007f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b03168a6001600160a01b0316146040518060400160405280600981526020016810aa27a5a2a72fa4a760b91b81525090610a825760405162461bcd60e51b81526004016106439190611667565b5060405163d505accf60e01b8152336004820152306024820152604481018990526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b038b169063d505accf9060e401600060405180830381600087803b158015610aef57600080fd5b505af1158015610b03573d6000803e3d6000fd5b50505050610b16338c8c8c8c8c8c61112d565b9b9a5050505050505050505050565b600c5460408051808201909152600681526514105554d15160d21b602082015260009160ff1615610b695760405162461bcd60e51b81526004016106439190611667565b50610b74838361148a565b9392505050565b60088181548110610b8b57600080fd5b600091825260209091200154905081565b6000610bad3388888888888861112d565b979650505050505050565b6006546001600160a01b03163314610be25760405162461bcd60e51b815260040161064390611a35565b600b54811015610c265760405162461bcd60e51b815260206004820152600f60248201526e1313d5d15497d512105397d3525395608a1b6044820152606401610643565b600a5460408051918252602082018390527fed89e864eaa767d73408242ff6a09be53504bda6578087e3cc94dc198390488c910160405180910390a1600a55565b42841015610cb75760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610643565b6000610cc1610808565b6001600160a01b0389811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015610dda573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610e105750886001600160a01b0316816001600160a01b0316145b610e4d5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610643565b6001600160a01b0390811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6006546001600160a01b03163314610ee25760405162461bcd60e51b815260040161064390611a35565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527f3c864541ef71378c6229510ed90f376565ee42d9c5e0904a984a9e863e6db44f9060200160405180910390a150565b8060026000828254610f489190611a6d565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610ffd57610fd88382611abb565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290611025908490611abb565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906110809087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516110c59190611ad2565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60007f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f6001600160a01b0316866001600160a01b031614806111a057507f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e6001600160a01b0316866001600160a01b0316145b6040518060400160405280600981526020016810aa27a5a2a72fa4a760b91b815250906111e05760405162461bcd60e51b81526004016106439190611667565b5061125e838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506007546040516bffffffffffffffffffffffff1960608e901b166020820152603481018b9052909250605401905060405160208183030381529060405280519060200120611502565b6112935760405162461bcd60e51b815260206004820152600660248201526510a82927a7a360d11b6044820152606401610643565b6007546000908152600e602090815260408083206001600160a01b038b1684529091528120546112c4908690611a6d565b9050858111156040518060400160405280600781526020016608505353d5539560ca1b815250906113085760405162461bcd60e51b81526004016106439190611667565b506007546000908152600e602090815260408083206001600160a01b038c168452909152902081905560095461134686670de0b6b3a7640000611b6e565b6113509190611b8d565b9150600a5482600b546113639190611a6d565b11156040518060400160405280600e81526020016d455843454544535f535550504c5960901b815250906113aa5760405162461bcd60e51b81526004016106439190611667565b506001600160a01b0388166000908152600d602052604081208054909184918391906113d7908490611a6d565b9250508190555082600b60008282546113f09190611a6d565b9091555050600654611411906001600160a01b038a8116918d911689611518565b61141b8984610f36565b886001600160a01b03168a6001600160a01b03167f68c721f9a38584842eb66945b43c95066397ce5f2576fcc0588471c85d209d0c8589600b54604051611475939291909283526020830191909152604082015260600190565b60405180910390a35050979650505050505050565b336000908152600360205260408120805483919083906114ab908490611abb565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906106089086815260200190565b60008261150f85846115ac565b14949350505050565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af191505061156281611620565b6115a55760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610643565b5050505050565b600081815b84518110156116185760008582815181106115ce576115ce611baf565b602002602001015190508083116115f45760008381526020829052604090209250611605565b600081815260208490526040902092505b508061161081611bc5565b9150506115b1565b509392505050565b60003d8261163257806000803e806000fd5b806020811461164a57801561165b5760009250611660565b816000803e60005115159250611660565b600192505b5050919050565b600060208083528351808285015260005b8181101561169457858101830151858201604001528201611678565b818111156116a6576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146116d357600080fd5b919050565b600080604083850312156116eb57600080fd5b6116f4836116bc565b946020939093013593505050565b60006020828403121561171457600080fd5b610b74826116bc565b6000806040838503121561173057600080fd5b50508035926020909101359150565b6000806040838503121561175257600080fd5b82359150611762602084016116bc565b90509250929050565b60008060006060848603121561178057600080fd5b611789846116bc565b9250611797602085016116bc565b9150604084013590509250925092565b80151581146109fb57600080fd5b6000602082840312156117c757600080fd5b8135610b74816117a7565b60008083601f8401126117e457600080fd5b50813567ffffffffffffffff8111156117fc57600080fd5b6020830191508360208260051b850101111561181757600080fd5b9250929050565b803560ff811681146116d357600080fd5b6000806000806000806000806000806101208b8d03121561184f57600080fd5b6118588b6116bc565b995061186660208c016116bc565b985060408b0135975060608b0135965060808b013567ffffffffffffffff81111561189057600080fd5b61189c8d828e016117d2565b90975095505060a08b013593506118b560c08c0161181e565b925060e08b013591506101008b013590509295989b9194979a5092959850565b6000602082840312156118e757600080fd5b5035919050565b60008060008060008060a0878903121561190757600080fd5b611910876116bc565b955061191e602088016116bc565b94506040870135935060608701359250608087013567ffffffffffffffff81111561194857600080fd5b61195489828a016117d2565b979a9699509497509295939492505050565b600080600080600080600060e0888a03121561198157600080fd5b61198a886116bc565b9650611998602089016116bc565b955060408801359450606088013593506119b46080890161181e565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156119e357600080fd5b6119ec836116bc565b9150611762602084016116bc565b600181811c90821680611a0e57607f821691505b60208210811415611a2f57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526008908201526721434f4e4341564560c01b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611a8057611a80611a57565b500190565b600060208284031215611a9757600080fd5b5051919050565b600060208284031215611ab057600080fd5b8151610b74816117a7565b600082821015611acd57611acd611a57565b500390565b600080835481600182811c915080831680611aee57607f831692505b6020808410821415611b0e57634e487b7160e01b86526022600452602486fd5b818015611b225760018114611b3357611b60565b60ff19861689528489019650611b60565b60008a81526020902060005b86811015611b585781548b820152908501908301611b3f565b505084890196505b509498975050505050505050565b6000816000190483118215151615611b8857611b88611a57565b500290565b600082611baa57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611bd957611bd9611a57565b506001019056fea264697066735822122024da44e9750308f2d69fff0dedf0be4fc4d6018a2c6e023be96c87ebd431cc9464736f6c634300080b0033

Deployed Bytecode Sourcemap

16061:14490:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2310:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3946:217;;;;;;:::i;:::-;;:::i;:::-;;;1218:14:1;;1211:22;1193:41;;1181:2;1166:18;3946:217:0;1053:187:1;18993:51:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;1610:25:1;;;1666:2;1651:18;;1644:34;;;;1583:18;18993:51:0;1436:248:1;22858:359:0;;;;;;:::i;:::-;;:::i;:::-;;22296:360;;;;;;:::i;:::-;;:::i;19322:67::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;2347:25:1;;;2335:2;2320:18;19322:67:0;2201:177:1;2594:26:0;;;;;;27313:277;;;;;;:::i;:::-;;:::i;17939:19::-;;;;;;17755:25;;;;;;2945:146;;2996:95;2945:146;;2366:31;;;;;;;;3070:4:1;3058:17;;;3040:36;;3028:2;3013:18;2366:31:0;2898:184:1;6404:179:0;;;:::i;23687:105::-;;;;;;:::i;:::-;;:::i;18278:34::-;;;;;;;;;17618:68;;;;;-1:-1:-1;;;;;17618:68:0;;;;;;-1:-1:-1;;;;;3620:32:1;;;3602:51;;3590:2;3575:18;17618:68:0;3456:203:1;2629:44:0;;;;;;:::i;:::-;;;;;;;;;;;;;;3212:41;;;;;;:::i;:::-;;;;;;;;;;;;;;30315:233;;;;;;:::i;:::-;;:::i;2337:20::-;;;:::i;25712:705::-;;;;;;:::i;:::-;;:::i;18189:26::-;;;;;;26714:240;;;;;;:::i;:::-;;:::i;16705:79::-;;;;;17848:22;;;;;;:::i;:::-;;:::i;24580:283::-;;;;;;:::i;:::-;;:::i;23316:220::-;;;;;;:::i;:::-;;:::i;5373:1023::-;;;;;;:::i;:::-;;:::i;18055:41::-;;;;;;2682:64;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;16830:78;;;;;21973:154;;;;;;:::i;:::-;;:::i;2310:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3946:217::-;4047:10;4020:4;4037:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;4037:30:0;;;;;;;;;;:39;;;4094:37;4020:4;;4037:30;;4094:37;;;;4070:6;2347:25:1;;2335:2;2320:18;;2201:177;4094:37:0;;;;;;;;-1:-1:-1;4151:4:0;3946:217;;;;:::o;22858:359::-;21620:8;;-1:-1:-1;;;;;21620:8:0;21606:10;:22;21598:43;;;;-1:-1:-1;;;21598:43:0;;;;;;;:::i;:::-;;;;;;;;;22963:17:::1;22997:6;22983:11;;:20;;;;:::i;:::-;22963:40;;23035:9;;23022;:22;;23045:14;;;;;;;;;;;;;-1:-1:-1::0;;;23045:14:0::1;;::::0;23014:46:::1;;;;;-1:-1:-1::0;;;23014:46:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;23071:11:0::1;:23:::0;;;23136:21:::1;23142:6:::0;23150;23136:5:::1;:21::i;:::-;23197:11;::::0;23173:36:::1;::::0;;-1:-1:-1;;;;;8419:32:1;;8401:51;;8483:2;8468:18;;8461:34;;;8511:18;;;8504:34;;;;23173:36:0;::::1;::::0;;;;8389:2:1;23173:36:0;;::::1;22952:265;22858:359:::0;;:::o;22296:360::-;21620:8;;-1:-1:-1;;;;;21620:8:0;21606:10;:22;21598:43;;;;-1:-1:-1;;;21598:43:0;;;;;;;:::i;:::-;22469:5:::1;:23:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;22469:23:0;;;;;::::1;::::0;;;22534:10:::1;:24:::0;;;22593:4:::1;:12:::0;;;22623:25:::1;::::0;;1610::1;;;1666:2;1651:18;;1644:34;;;22623:25:0::1;::::0;1583:18:1;22623:25:0::1;;;;;;;22296:360:::0;;:::o;27313:277::-;27470:15;;27486:6;;;;;;;;;;;;-1:-1:-1;;;27486:6:0;;;;27444:4;;27470:15;;27469:16;27461:32;;;;-1:-1:-1;;;27461:32:0;;;;;;;;:::i;:::-;;27546:36;27565:4;27571:2;27575:6;27546:18;:36::i;:::-;27539:43;27313:277;-1:-1:-1;;;;27313:277:0:o;6404:179::-;6461:7;6505:16;6488:13;:33;:87;;6551:24;:22;:24::i;:::-;6481:94;;6404:179;:::o;6488:87::-;-1:-1:-1;6524:24:0;;6404:179::o;23687:105::-;21620:8;;-1:-1:-1;;;;;21620:8:0;21606:10;:22;21598:43;;;;-1:-1:-1;;;21598:43:0;;;;;;;:::i;:::-;23760:15:::1;:24:::0;;-1:-1:-1;;23760:24:0::1;::::0;::::1;;::::0;;;::::1;::::0;;23687:105::o;30315:233::-;21620:8;;-1:-1:-1;;;;;21620:8:0;21606:10;:22;21598:43;;;;-1:-1:-1;;;21598:43:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;30382:19:0;::::1;30378:162;;30411:8;::::0;30403:51:::1;::::0;-1:-1:-1;;;;;30411:8:0;;::::1;::::0;30431:21:::1;30403:51:::0;::::1;;;::::0;30411:8:::1;30403:51:::0;30411:8;30403:51;30431:21;30411:8;30403:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;30315:233:::0;:::o;30378:162::-:1;30492:8;::::0;30502:37:::1;::::0;-1:-1:-1;;;30502:37:0;;30533:4:::1;30502:37;::::0;::::1;3602:51:1::0;-1:-1:-1;;;;;30470:21:0;;::::1;::::0;::::1;::::0;30492:8;::::1;::::0;30470:21;;30502:22:::1;::::0;3575:18:1;;30502:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30470:70;::::0;-1:-1:-1;;;;;;30470:70:0::1;::::0;;;;;;-1:-1:-1;;;;;9183:32:1;;;30470:70:0::1;::::0;::::1;9165:51:1::0;9232:18;;;9225:34;9138:18;;30470:70:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;30378:162::-;30315:233:::0;:::o;2337:20::-;;;;;;;:::i;25712:705::-;25989:17;26091:3;-1:-1:-1;;;;;26072:23:0;:7;-1:-1:-1;;;;;26072:23:0;;26097:14;;;;;;;;;;;;;-1:-1:-1;;;26097:14:0;;;26064:48;;;;;-1:-1:-1;;;26064:48:0;;;;;;;;:::i;:::-;-1:-1:-1;26204:83:0;;-1:-1:-1;;;26204:83:0;;26226:10;26204:83;;;9869:34:1;26246:4:0;9919:18:1;;;9912:43;9971:18;;;9964:34;;;10014:18;;;10007:34;;;10090:4;10078:17;;10057:19;;;10050:46;10112:19;;;10105:35;;;10156:19;;;10149:35;;;-1:-1:-1;;;;;26204:21:0;;;;;9803:19:1;;26204:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26347:62;26357:10;26369:2;26373:7;26382:9;26393:8;26403:5;;26347:9;:62::i;:::-;26340:69;25712:705;-1:-1:-1;;;;;;;;;;;25712:705:0:o;26714:240::-;26844:15;;26860:6;;;;;;;;;;;;-1:-1:-1;;;26860:6:0;;;;26818:4;;26844:15;;26843:16;26835:32;;;;-1:-1:-1;;;26835:32:0;;;;;;;;:::i;:::-;;26920:26;26935:2;26939:6;26920:14;:26::i;:::-;26913:33;26714:240;-1:-1:-1;;;26714:240:0:o;17848:22::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17848:22:0;:::o;24580:283::-;24756:17;24793:62;24803:10;24815:2;24819:7;24828:9;24839:8;24849:5;;24793:9;:62::i;:::-;24786:69;24580:283;-1:-1:-1;;;;;;;24580:283:0:o;23316:220::-;21620:8;;-1:-1:-1;;;;;21620:8:0;21606:10;:22;21598:43;;;;-1:-1:-1;;;21598:43:0;;;;;;;:::i;:::-;23412:11:::1;;23398:10;:25;;23390:53;;;::::0;-1:-1:-1;;;23390:53:0;;10397:2:1;23390:53:0::1;::::0;::::1;10379:21:1::0;10436:2;10416:18;;;10409:30;-1:-1:-1;;;10455:18:1;;;10448:45;10510:18;;23390:53:0::1;10195:339:1::0;23390:53:0::1;23473:9;::::0;23459:36:::1;::::0;;1610:25:1;;;1666:2;1651:18;;1644:34;;;23459:36:0::1;::::0;1583:18:1;23459:36:0::1;;;;;;;23506:9;:22:::0;23316:220::o;5373:1023::-;5601:15;5589:8;:27;;5581:63;;;;-1:-1:-1;;;5581:63:0;;10741:2:1;5581:63:0;;;10723:21:1;10780:2;10760:18;;;10753:30;10819:25;10799:18;;;10792:53;10862:18;;5581:63:0;10539:347:1;5581:63:0;5814:14;5931:18;:16;:18::i;:::-;-1:-1:-1;;;;;6033:13:0;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;5982:77;;2996:95;5982:77;;;11178:25:1;11257:18;;;11250:43;;;;11329:15;;;11309:18;;;11302:43;11361:18;;;11354:34;;;11404:19;;;11397:35;;;;11448:19;;;;11441:35;;;5982:77:0;;;;;;;;;;11150:19:1;;;5982:77:0;;;5972:88;;;;;;;;-1:-1:-1;;;5859:220:0;;;11745:27:1;11788:11;;;11781:27;;;;11824:12;;;11817:28;;;;11861:12;;5859:220:0;;;-1:-1:-1;;5859:220:0;;;;;;;;;5831:263;;5859:220;5831:263;;;;6111:24;6138:26;;;;;;;;;12111:25:1;;;12184:4;12172:17;;12152:18;;;12145:45;;;;12206:18;;;12199:34;;;12249:18;;;12242:34;;;5831:263:0;;-1:-1:-1;6111:24:0;6138:26;;12083:19:1;;6138:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6138:26:0;;-1:-1:-1;;6138:26:0;;;-1:-1:-1;;;;;;;6189:30:0;;;;;;:59;;;6243:5;-1:-1:-1;;;;;6223:25:0;:16;-1:-1:-1;;;;;6223:25:0;;6189:59;6181:86;;;;-1:-1:-1;;;6181:86:0;;12489:2:1;6181:86:0;;;12471:21:1;12528:2;12508:18;;;12501:30;-1:-1:-1;;;12547:18:1;;;12540:44;12601:18;;6181:86:0;12287:338:1;6181:86:0;-1:-1:-1;;;;;6284:27:0;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;6357:31;2347:25:1;;;6284:36:0;;-1:-1:-1;6357:31:0;;;;;;2320:18:1;6357:31:0;;;;;;;5373:1023;;;;;;;:::o;21973:154::-;21620:8;;-1:-1:-1;;;;;21620:8:0;21606:10;:22;21598:43;;;;-1:-1:-1;;;21598:43:0;;;;;;;:::i;:::-;22061:8:::1;:20:::0;;-1:-1:-1;;;;;;22061:20:0::1;-1:-1:-1::0;;;;;22061:20:0;::::1;::::0;;::::1;::::0;;;22097:22:::1;::::0;3602:51:1;;;22097:22:0::1;::::0;3590:2:1;3575:18;22097:22:0::1;;;;;;;21973:154:::0;:::o;7248:335::-;7334:6;7319:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;7491:13:0;;;;;;:9;:13;;;;;;;;:23;;;;;;7543:32;2347:25:1;;;7543:32:0;;2320:18:1;7543:32:0;;;;;;;7248:335;;:::o;4564:612::-;-1:-1:-1;;;;;4721:15:0;;4686:4;4721:15;;;:9;:15;;;;;;;;4737:10;4721:27;;;;;;;;-1:-1:-1;;4801:28:0;;4797:80;;4861:16;4871:6;4861:7;:16;:::i;:::-;-1:-1:-1;;;;;4831:15:0;;;;;;:9;:15;;;;;;;;4847:10;4831:27;;;;;;;:46;4797:80;-1:-1:-1;;;;;4890:15:0;;;;;;:9;:15;;;;;:25;;4909:6;;4890:15;:25;;4909:6;;4890:25;:::i;:::-;;;;-1:-1:-1;;;;;;;5066:13:0;;;;;;;:9;:13;;;;;;;:23;;;;;;5118:26;5066:13;;5118:26;;;;;;;5083:6;2347:25:1;;2335:2;2320:18;;2201:177;5118:26:0;;;;;;;;-1:-1:-1;5164:4:0;;4564:612;-1:-1:-1;;;;4564:612:0:o;6591:457::-;6656:7;6757:95;6891:4;6875:22;;;;;;:::i;:::-;;;;;;;;;;6724:301;;;14257:25:1;;;;14298:18;;14291:34;;;;6920:14:0;14341:18:1;;;14334:34;6957:13:0;14384:18:1;;;14377:34;7001:4:0;14427:19:1;;;14420:61;14229:19;;6724:301:0;;;;;;;;;;;;6696:344;;;;;;6676:364;;6591:457;:::o;28410:1753::-;28615:17;28732:3;-1:-1:-1;;;;;28713:23:0;:7;-1:-1:-1;;;;;28713:23:0;;:51;;;;28759:4;-1:-1:-1;;;;;28740:24:0;:7;-1:-1:-1;;;;;28740:24:0;;28713:51;28766:14;;;;;;;;;;;;;-1:-1:-1;;;28766:14:0;;;28705:76;;;;;-1:-1:-1;;;28705:76:0;;;;;;;;:::i;:::-;;28889:81;28908:5;;28889:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;28915:10:0;;28937:31;;-1:-1:-1;;14669:2:1;14665:15;;;14661:53;28937:31:0;;;14649:66:1;14731:12;;;14724:28;;;28915:10:0;;-1:-1:-1;14768:12:1;;;-1:-1:-1;28937:31:0;;;;;;;;;;;;28927:42;;;;;;28889:18;:81::i;:::-;28881:100;;;;-1:-1:-1;;;28881:100:0;;14993:2:1;28881:100:0;;;14975:21:1;15032:1;15012:18;;;15005:29;-1:-1:-1;;;15050:18:1;;;15043:36;15096:18;;28881:100:0;14791:329:1;28881:100:0;29098:10;;29065:17;29085:24;;;:12;:24;;;;;;;;-1:-1:-1;;;;;29085:28:0;;;;;;;;;;:39;;29116:8;;29085:39;:::i;:::-;29065:59;;29168:9;29155;:22;;29179:12;;;;;;;;;;;;;-1:-1:-1;;;29179:12:0;;;29147:45;;;;;-1:-1:-1;;;29147:45:0;;;;;;;;:::i;:::-;-1:-1:-1;29216:10:0;;29203:24;;;;:12;:24;;;;;;;;-1:-1:-1;;;;;29203:28:0;;;;;;;;;:40;;;29360:4;;29342:15;:8;29353:4;29342:15;:::i;:::-;:22;;;;:::i;:::-;29330:34;;29496:9;;29483;29469:11;;:23;;;;:::i;:::-;:36;;29507:14;;;;;;;;;;;;;-1:-1:-1;;;29507:14:0;;;29461:61;;;;;-1:-1:-1;;;29461:61:0;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;29615:16:0;;29581:31;29615:16;;;:12;:16;;;;;29725:34;;29615:16;;29750:9;;29615:16;;29581:31;29725:34;;29750:9;;29725:34;:::i;:::-;;;;;;;;29855:9;29840:11;;:24;;;;;;;:::i;:::-;;;;-1:-1:-1;;29984:8:0;;29944:59;;-1:-1:-1;;;;;29944:31:0;;;;29976:6;;29984:8;29994;29944:31;:59::i;:::-;30065:20;30071:2;30075:9;30065:5;:20::i;:::-;30118:2;-1:-1:-1;;;;;30103:52:0;30110:6;-1:-1:-1;;;;;30103:52:0;;30122:9;30133:8;30143:11;;30103:52;;;;;;;15722:25:1;;;15778:2;15763:18;;15756:34;;;;15821:2;15806:18;;15799:34;15710:2;15695:18;;15520:319;30103:52:0;;;;;;;;28634:1529;;28410:1753;;;;;;;;;:::o;4171:385::-;4268:10;4241:4;4258:21;;;:9;:21;;;;;:31;;4283:6;;4258:21;4241:4;;4258:31;;4283:6;;4258:31;:::i;:::-;;;;-1:-1:-1;;;;;;;4440:13:0;;;;;;:9;:13;;;;;;;:23;;;;;;4492:32;4501:10;;4492:32;;;;4457:6;2347:25:1;;2335:2;2320:18;;2201:177;14522:190:0;14647:4;14700;14671:25;14684:5;14691:4;14671:12;:25::i;:::-;:33;;14522:190;-1:-1:-1;;;;14522:190:0:o;9125:1242::-;9269:15;9403:4;9397:11;-1:-1:-1;;;9504:17:0;9497:93;-1:-1:-1;;;;;9679:4:0;9675:53;9671:1;9652:17;9648:25;9641:88;-1:-1:-1;;;;;9822:2:0;9818:51;9813:2;9794:17;9790:26;9783:87;9957:6;9952:2;9933:17;9929:26;9922:42;10257:1;10254;10249:3;10230:17;10227:1;10220:5;10213;10208:51;10194:65;;;10290:44;10323:10;10290:32;:44::i;:::-;10282:77;;;;-1:-1:-1;;;10282:77:0;;16046:2:1;10282:77:0;;;16028:21:1;16085:2;16065:18;;;16058:30;-1:-1:-1;;;16104:18:1;;;16097:50;16164:18;;10282:77:0;15844:344:1;10282:77:0;9258:1109;9125:1242;;;;:::o;15074:675::-;15157:7;15200:4;15157:7;15215:497;15239:5;:12;15235:1;:16;15215:497;;;15273:20;15296:5;15302:1;15296:8;;;;;;;;:::i;:::-;;;;;;;15273:31;;15339:12;15323;:28;15319:382;;15825:13;15875:15;;;15911:4;15904:15;;;15958:4;15942:21;;15451:57;;15319:382;;;15825:13;15875:15;;;15911:4;15904:15;;;15958:4;15942:21;;15628:57;;15319:382;-1:-1:-1;15253:3:0;;;;:::i;:::-;;;;15215:497;;;-1:-1:-1;15729:12:0;15074:675;-1:-1:-1;;;15074:675:0:o;12710:1072::-;12791:12;12916:16;12996:10;12986:244;;13105:14;13102:1;13099;13084:36;13200:14;13197:1;13190:25;12986:244;13253:14;13286:2;13281:248;;;;13543:99;;;;13748:1;13737:12;;13246:518;;13281:248;13383:14;13380:1;13377;13362:36;13510:1;13504:8;13497:16;13490:24;13479:35;;13281:248;;13543:99;13626:1;13615:12;;13246:518;;;12710:1072;;;:::o;14:597:1:-;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;452:6;449:1;446:13;443:91;;;522:1;517:2;508:6;497:9;493:22;489:31;482:42;443:91;-1:-1:-1;595:2:1;574:15;-1:-1:-1;;570:29:1;555:45;;;;602:2;551:54;;14:597;-1:-1:-1;;;14:597:1:o;616:173::-;684:20;;-1:-1:-1;;;;;733:31:1;;723:42;;713:70;;779:1;776;769:12;713:70;616:173;;;:::o;794:254::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;1038:2;1023:18;;;;1010:32;;-1:-1:-1;;;794:254:1:o;1245:186::-;1304:6;1357:2;1345:9;1336:7;1332:23;1328:32;1325:52;;;1373:1;1370;1363:12;1325:52;1396:29;1415:9;1396:29;:::i;1689:248::-;1757:6;1765;1818:2;1806:9;1797:7;1793:23;1789:32;1786:52;;;1834:1;1831;1824:12;1786:52;-1:-1:-1;;1857:23:1;;;1927:2;1912:18;;;1899:32;;-1:-1:-1;1689:248:1:o;1942:254::-;2010:6;2018;2071:2;2059:9;2050:7;2046:23;2042:32;2039:52;;;2087:1;2084;2077:12;2039:52;2123:9;2110:23;2100:33;;2152:38;2186:2;2175:9;2171:18;2152:38;:::i;:::-;2142:48;;1942:254;;;;;:::o;2383:328::-;2460:6;2468;2476;2529:2;2517:9;2508:7;2504:23;2500:32;2497:52;;;2545:1;2542;2535:12;2497:52;2568:29;2587:9;2568:29;:::i;:::-;2558:39;;2616:38;2650:2;2639:9;2635:18;2616:38;:::i;:::-;2606:48;;2701:2;2690:9;2686:18;2673:32;2663:42;;2383:328;;;;;:::o;3087:118::-;3173:5;3166:13;3159:21;3152:5;3149:32;3139:60;;3195:1;3192;3185:12;3210:241;3266:6;3319:2;3307:9;3298:7;3294:23;3290:32;3287:52;;;3335:1;3332;3325:12;3287:52;3374:9;3361:23;3393:28;3415:5;3393:28;:::i;3664:367::-;3727:8;3737:6;3791:3;3784:4;3776:6;3772:17;3768:27;3758:55;;3809:1;3806;3799:12;3758:55;-1:-1:-1;3832:20:1;;3875:18;3864:30;;3861:50;;;3907:1;3904;3897:12;3861:50;3944:4;3936:6;3932:17;3920:29;;4004:3;3997:4;3987:6;3984:1;3980:14;3972:6;3968:27;3964:38;3961:47;3958:67;;;4021:1;4018;4011:12;3958:67;3664:367;;;;;:::o;4036:156::-;4102:20;;4162:4;4151:16;;4141:27;;4131:55;;4182:1;4179;4172:12;4197:1001;4353:6;4361;4369;4377;4385;4393;4401;4409;4417;4425;4478:3;4466:9;4457:7;4453:23;4449:33;4446:53;;;4495:1;4492;4485:12;4446:53;4518:29;4537:9;4518:29;:::i;:::-;4508:39;;4566:38;4600:2;4589:9;4585:18;4566:38;:::i;:::-;4556:48;;4651:2;4640:9;4636:18;4623:32;4613:42;;4702:2;4691:9;4687:18;4674:32;4664:42;;4757:3;4746:9;4742:19;4729:33;4785:18;4777:6;4774:30;4771:50;;;4817:1;4814;4807:12;4771:50;4856:70;4918:7;4909:6;4898:9;4894:22;4856:70;:::i;:::-;4945:8;;-1:-1:-1;4830:96:1;-1:-1:-1;;5027:3:1;5012:19;;4999:33;;-1:-1:-1;5051:37:1;5083:3;5068:19;;5051:37;:::i;:::-;5041:47;;5135:3;5124:9;5120:19;5107:33;5097:43;;5187:3;5176:9;5172:19;5159:33;5149:43;;4197:1001;;;;;;;;;;;;;:::o;5424:180::-;5483:6;5536:2;5524:9;5515:7;5511:23;5507:32;5504:52;;;5552:1;5549;5542:12;5504:52;-1:-1:-1;5575:23:1;;5424:180;-1:-1:-1;5424:180:1:o;5609:723::-;5731:6;5739;5747;5755;5763;5771;5824:3;5812:9;5803:7;5799:23;5795:33;5792:53;;;5841:1;5838;5831:12;5792:53;5864:29;5883:9;5864:29;:::i;:::-;5854:39;;5912:38;5946:2;5935:9;5931:18;5912:38;:::i;:::-;5902:48;;5997:2;5986:9;5982:18;5969:32;5959:42;;6048:2;6037:9;6033:18;6020:32;6010:42;;6103:3;6092:9;6088:19;6075:33;6131:18;6123:6;6120:30;6117:50;;;6163:1;6160;6153:12;6117:50;6202:70;6264:7;6255:6;6244:9;6240:22;6202:70;:::i;:::-;5609:723;;;;-1:-1:-1;5609:723:1;;-1:-1:-1;5609:723:1;;6291:8;;5609:723;-1:-1:-1;;;5609:723:1:o;6337:606::-;6448:6;6456;6464;6472;6480;6488;6496;6549:3;6537:9;6528:7;6524:23;6520:33;6517:53;;;6566:1;6563;6556:12;6517:53;6589:29;6608:9;6589:29;:::i;:::-;6579:39;;6637:38;6671:2;6660:9;6656:18;6637:38;:::i;:::-;6627:48;;6722:2;6711:9;6707:18;6694:32;6684:42;;6773:2;6762:9;6758:18;6745:32;6735:42;;6796:37;6828:3;6817:9;6813:19;6796:37;:::i;:::-;6786:47;;6880:3;6869:9;6865:19;6852:33;6842:43;;6932:3;6921:9;6917:19;6904:33;6894:43;;6337:606;;;;;;;;;;:::o;6948:260::-;7016:6;7024;7077:2;7065:9;7056:7;7052:23;7048:32;7045:52;;;7093:1;7090;7083:12;7045:52;7116:29;7135:9;7116:29;:::i;:::-;7106:39;;7164:38;7198:2;7187:9;7183:18;7164:38;:::i;7213:380::-;7292:1;7288:12;;;;7335;;;7356:61;;7410:4;7402:6;7398:17;7388:27;;7356:61;7463:2;7455:6;7452:14;7432:18;7429:38;7426:161;;;7509:10;7504:3;7500:20;7497:1;7490:31;7544:4;7541:1;7534:15;7572:4;7569:1;7562:15;7426:161;;7213:380;;;:::o;7598:331::-;7800:2;7782:21;;;7839:1;7819:18;;;7812:29;-1:-1:-1;;;7872:2:1;7857:18;;7850:38;7920:2;7905:18;;7598:331::o;7934:127::-;7995:10;7990:3;7986:20;7983:1;7976:31;8026:4;8023:1;8016:15;8050:4;8047:1;8040:15;8066:128;8106:3;8137:1;8133:6;8130:1;8127:13;8124:39;;;8143:18;;:::i;:::-;-1:-1:-1;8179:9:1;;8066:128::o;8802:184::-;8872:6;8925:2;8913:9;8904:7;8900:23;8896:32;8893:52;;;8941:1;8938;8931:12;8893:52;-1:-1:-1;8964:16:1;;8802:184;-1:-1:-1;8802:184:1:o;9270:245::-;9337:6;9390:2;9378:9;9369:7;9365:23;9361:32;9358:52;;;9406:1;9403;9396:12;9358:52;9438:9;9432:16;9457:28;9479:5;9457:28;:::i;12630:125::-;12670:4;12698:1;12695;12692:8;12689:34;;;12703:18;;:::i;:::-;-1:-1:-1;12740:9:1;;12630:125::o;12889:1104::-;13019:3;13048:1;13081:6;13075:13;13111:3;13133:1;13161:9;13157:2;13153:18;13143:28;;13221:2;13210:9;13206:18;13243;13233:61;;13287:4;13279:6;13275:17;13265:27;;13233:61;13313:2;13361;13353:6;13350:14;13330:18;13327:38;13324:165;;;-1:-1:-1;;;13388:33:1;;13444:4;13441:1;13434:15;13474:4;13395:3;13462:17;13324:165;13505:18;13532:104;;;;13650:1;13645:323;;;;13498:470;;13532:104;-1:-1:-1;;13565:24:1;;13553:37;;13610:16;;;;-1:-1:-1;13532:104:1;;13645:323;12836:1;12829:14;;;12873:4;12860:18;;13743:1;13757:165;13771:6;13768:1;13765:13;13757:165;;;13849:14;;13836:11;;;13829:35;13892:16;;;;13786:10;;13757:165;;;13761:3;;13951:6;13946:3;13942:16;13935:23;;13498:470;-1:-1:-1;13984:3:1;;12889:1104;-1:-1:-1;;;;;;;;12889:1104:1:o;15125:168::-;15165:7;15231:1;15227;15223:6;15219:14;15216:1;15213:21;15208:1;15201:9;15194:17;15190:45;15187:71;;;15238:18;;:::i;:::-;-1:-1:-1;15278:9:1;;15125:168::o;15298:217::-;15338:1;15364;15354:132;;15408:10;15403:3;15399:20;15396:1;15389:31;15443:4;15440:1;15433:15;15471:4;15468:1;15461:15;15354:132;-1:-1:-1;15500:9:1;;15298:217::o;16193:127::-;16254:10;16249:3;16245:20;16242:1;16235:31;16285:4;16282:1;16275:15;16309:4;16306:1;16299:15;16325:135;16364:3;-1:-1:-1;;16385:17:1;;16382:43;;;16405:18;;:::i;:::-;-1:-1:-1;16452:1:1;16441:13;;16325:135::o

Swarm Source

ipfs://24da44e9750308f2d69fff0dedf0be4fc4d6018a2c6e023be96c87ebd431cc94
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.