ETH Price: $2,875.75 (-9.16%)
Gas: 15 Gwei

Token

ERC20 ***
 

Overview

Max Total Supply

579.436555 ERC20 ***

Holders

5

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 6 Decimals)

Balance
10.249655 ERC20 ***

Value
$0.00
0x9bb98140F36553dB71fe4a570aC0b1401BC61B4F
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x3393f10c...7259A0A1B
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
ERC5095

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : Exception.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.16;

/// @dev A single custom error capable of indicating a wide range of detected errors by providing
/// an error code value whose string representation is documented in errors.txt, and any possible other values
/// that are pertinent to the error.
error Exception(uint8, uint256, uint256, address, address);

File 2 of 13 : IERC20.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.16;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Returns the number of decimals the token uses - e.g. 8, means to
     * divide the token amount by 100000000 to get its user representation.
     */
    function decimals() external view returns (uint8);

    /**
     * @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
    );
}

File 3 of 13 : IERC20Metadata.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.16;

import 'src/interfaces/IERC20.sol';

interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 4 of 13 : IERC2612.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.16;

import 'src/interfaces/IERC20Metadata.sol';

/**
 * @dev Interface of the ERC2612 standard as defined in the EIP.
 *
 * Adds the {permit} method, which can be used to change one's
 * {IERC20-allowance} without having to send a transaction, by signing a
 * message. This allows users to spend tokens without having to hold Ether.
 *
 * See https://eips.ethereum.org/EIPS/eip-2612.
 */
interface IERC2612 is IERC20Metadata {
    /**
     * @dev Sets `amount` as the allowance of `spender` over `owner`'s tokens,
     * given `owner`'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current ERC2612 nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);
}

File 5 of 13 : IERC5095.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.16;

import 'src/interfaces/IERC2612.sol';

interface IERC5095 is IERC2612 {
    function maturity() external view returns (uint256);

    function underlying() external view returns (address);

    function convertToUnderlying(uint256) external view returns (uint256);

    function convertToShares(uint256) external view returns (uint256);

    function maxRedeem(address) external view returns (uint256);

    function previewRedeem(uint256) external view returns (uint256);

    function maxWithdraw(address) external view returns (uint256);

    function previewWithdraw(uint256) external view returns (uint256);

    function previewDeposit(uint256) external view returns (uint256);

    function withdraw(
        uint256,
        address,
        address
    ) external returns (uint256);

    function redeem(
        uint256,
        address,
        address
    ) external returns (uint256);

    function deposit(uint256, address) external returns (uint256);

    function mint(uint256, address) external returns (uint256);

    function authMint(address, uint256) external returns (bool);

    function authBurn(address, uint256) external returns (bool);

    function authApprove(
        address,
        address,
        uint256
    ) external returns (bool);
}

File 6 of 13 : IMarketPlace.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.16;

interface IMarketPlace {
    function markets(
        address,
        uint256,
        uint256
    ) external returns (address);

    function pools(address, uint256) external view returns (address);

    function sellPrincipalToken(
        address,
        uint256,
        uint128,
        uint128
    ) external returns (uint128);

    function buyPrincipalToken(
        address,
        uint256,
        uint128,
        uint128
    ) external returns (uint128);

    function sellUnderlying(
        address,
        uint256,
        uint128,
        uint128
    ) external returns (uint128);

    function buyUnderlying(
        address,
        uint256,
        uint128,
        uint128
    ) external returns (uint128);

    function redeemer() external view returns (address);
}

File 7 of 13 : IRedeemer.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.16;

interface IRedeemer {
    function authRedeem(
        address underlying,
        uint256 maturity,
        address from,
        address to,
        uint256 amount
    ) external returns (uint256);

    function approve(address p) external;

    function holdings(address u, uint256 m) external view returns (uint256);
}

File 8 of 13 : IYield.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity 0.8.16;

import 'src/interfaces/IERC20.sol';

interface IYield {
    function maturity() external view returns (uint32);

    function base() external view returns (IERC20);

    function sellBase(address, uint128) external returns (uint128);

    function sellBasePreview(uint128) external view returns (uint128);

    function fyToken() external returns (address);

    function sellFYToken(address, uint128) external returns (uint128);

    function sellFYTokenPreview(uint128) external view returns (uint128);

    function buyBase(
        address,
        uint128,
        uint128
    ) external returns (uint128);

    function buyBasePreview(uint128) external view returns (uint128);

    function buyFYToken(
        address,
        uint128,
        uint128
    ) external returns (uint128);

    function buyFYTokenPreview(uint128) external view returns (uint128);
}

File 9 of 13 : Cast.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.13;

library Cast {
    /// @dev Safely cast an uint256 to an uint128
    /// @param n the u256 to cast to u128
    function u128(uint256 n) internal pure returns (uint128) {
        if (n > type(uint128).max) {
            revert();
        }
        return uint128(n);
    }
}

File 10 of 13 : Safe.sol
// SPDX-License-Identifier: UNLICENSED
// Adapted from: https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol

pragma solidity ^0.8.13;

import 'src/interfaces/IERC20.sol';

/**
  @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
  @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 Safe {
    /// @param e Erc20 token to execute the call with
    /// @param t To address
    /// @param a Amount being transferred
    function transfer(
        IERC20 e,
        address t,
        uint256 a
    ) internal {
        bool result;

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

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(
                pointer,
                0xa9059cbb00000000000000000000000000000000000000000000000000000000
            ) // Begin with the function selector.
            mstore(
                add(pointer, 4),
                and(t, 0xffffffffffffffffffffffffffffffffffffffff)
            ) // Mask and append the "to" argument.
            mstore(add(pointer, 36), a) // 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.
            result := call(gas(), e, 0, pointer, 68, 0, 0)
        }

        require(success(result), 'transfer failed');
    }

    /// @param e Erc20 token to execute the call with
    /// @param f From address
    /// @param t To address
    /// @param a Amount being transferred
    function transferFrom(
        IERC20 e,
        address f,
        address t,
        uint256 a
    ) internal {
        bool result;

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

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(
                pointer,
                0x23b872dd00000000000000000000000000000000000000000000000000000000
            ) // Begin with the function selector.
            mstore(
                add(pointer, 4),
                and(f, 0xffffffffffffffffffffffffffffffffffffffff)
            ) // Mask and append the "from" argument.
            mstore(
                add(pointer, 36),
                and(t, 0xffffffffffffffffffffffffffffffffffffffff)
            ) // Mask and append the "to" argument.
            mstore(add(pointer, 68), a) // 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.
            result := call(gas(), e, 0, pointer, 100, 0, 0)
        }

        require(success(result), 'transfer from failed');
    }

    /// @notice normalize the acceptable values of true or null vs the unacceptable value of false (or something malformed)
    /// @param r Return value from the assembly `call()` to Erc20['selector']
    function success(bool r) private pure returns (bool) {
        bool result;

        assembly {
            // Get how many bytes the call returned.
            let returnDataSize := returndatasize()

            // If the call reverted:
            if iszero(r) {
                // 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.
                result := iszero(iszero(mload(0)))
            }
            case 0 {
                // There was no return data.
                result := 1
            }
            default {
                // It returned some malformed input.
                result := 0
            }
        }

        return result;
    }

    function approve(
        IERC20 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)
    {
        bool result;
        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.
                result := iszero(iszero(mload(0)))
            }
            case 0 {
                // There was no return data.
                result := 1
            }
            default {
                // It returned some malformed input.
                result := 0
            }
        }

        return result;
    }
}

File 11 of 13 : ERC20.sol
// SPDX-License-Identifier: MIT
// Inspired on token.sol from DappHub. Natspec adpated from OpenZeppelin.
pragma solidity 0.8.16;

import 'src/interfaces/IERC20Metadata.sol';

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Calls to {transferFrom} do not check for allowance if the caller is the owner
 * of the funds. This allows to reduce the number of approvals that are necessary.
 *
 * Finally, {transferFrom} does not decrease the allowance if it is set to
 * type(uint256).max. This reduces the gas costs without any likely impact.
 */
contract ERC20 is IERC20Metadata {
    uint256 internal _totalSupply;
    mapping(address => uint256) internal _balanceOf;
    mapping(address => mapping(address => uint256)) internal _allowance;
    string public override name = '???';
    string public override symbol = '???';
    uint8 public override decimals = 18;

    /**
     *  @dev Sets the values for {name}, {symbol} and {decimals}.
     */
    constructor(
        string memory name_,
        string memory symbol_,
        uint8 decimals_
    ) {
        name = name_;
        symbol = symbol_;
        decimals = decimals_;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() external view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address guy)
        external
        view
        virtual
        override
        returns (uint256)
    {
        return _balanceOf[guy];
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender)
        external
        view
        virtual
        override
        returns (uint256)
    {
        return _allowance[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     */
    function approve(address spender, uint256 wad)
        external
        virtual
        override
        returns (bool)
    {
        return _setAllowance(msg.sender, spender, wad);
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - the caller must have a balance of at least `wad`.
     */
    function transfer(address dst, uint256 wad)
        external
        virtual
        override
        returns (bool)
    {
        return _transfer(msg.sender, dst, wad);
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `src` must have a balance of at least `wad`.
     * - the caller is not `src`, it must have allowance for ``src``'s tokens of at least
     * `wad`.
     */
    /// if_succeeds {:msg "TransferFrom - decrease allowance"} msg.sender != src ==> old(_allowance[src][msg.sender]) >= wad;
    function transferFrom(
        address src,
        address dst,
        uint256 wad
    ) external virtual override returns (bool) {
        _decreaseAllowance(src, wad);

        return _transfer(src, dst, wad);
    }

    /**
     * @dev Moves tokens `wad` from `src` to `dst`.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `src` must have a balance of at least `amount`.
     */
    /// if_succeeds {:msg "Transfer - src decrease"} old(_balanceOf[src]) >= _balanceOf[src];
    /// if_succeeds {:msg "Transfer - dst increase"} _balanceOf[dst] >= old(_balanceOf[dst]);
    /// if_succeeds {:msg "Transfer - supply"} old(_balanceOf[src]) + old(_balanceOf[dst]) == _balanceOf[src] + _balanceOf[dst];
    function _transfer(
        address src,
        address dst,
        uint256 wad
    ) internal virtual returns (bool) {
        require(_balanceOf[src] >= wad, 'ERC20: Insufficient balance');
        unchecked {
            _balanceOf[src] = _balanceOf[src] - wad;
        }
        _balanceOf[dst] = _balanceOf[dst] + wad;

        emit Transfer(src, dst, wad);

        return true;
    }

    /**
     * @dev Sets the allowance granted to `spender` by `owner`.
     *
     * Emits an {Approval} event indicating the updated allowance.
     */
    function _setAllowance(
        address owner,
        address spender,
        uint256 wad
    ) internal virtual returns (bool) {
        _allowance[owner][spender] = wad;
        emit Approval(owner, spender, wad);

        return true;
    }

    /**
     * @dev Decreases the allowance granted to the caller by `src`, unless src == msg.sender or _allowance[src][msg.sender] == MAX
     *
     * Emits an {Approval} event indicating the updated allowance, if the allowance is updated.
     *
     * Requirements:
     *
     * - `spender` must have allowance for the caller of at least
     * `wad`, unless src == msg.sender
     */
    /// if_succeeds {:msg "Decrease allowance - underflow"} old(_allowance[src][msg.sender]) <= _allowance[src][msg.sender];
    function _decreaseAllowance(address src, uint256 wad)
        internal
        virtual
        returns (bool)
    {
        if (src != msg.sender) {
            uint256 allowed = _allowance[src][msg.sender];
            if (allowed != type(uint256).max) {
                require(allowed >= wad, 'ERC20: Insufficient approval');
                unchecked {
                    _setAllowance(src, msg.sender, allowed - wad);
                }
            }
        }

        return true;
    }

    /** @dev Creates `wad` tokens and assigns them to `dst`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     */
    /// if_succeeds {:msg "Mint - balance overflow"} old(_balanceOf[dst]) >= _balanceOf[dst];
    /// if_succeeds {:msg "Mint - supply overflow"} old(_totalSupply) >= _totalSupply;
    function _mint(address dst, uint256 wad) internal virtual returns (bool) {
        _balanceOf[dst] = _balanceOf[dst] + wad;
        _totalSupply = _totalSupply + wad;
        emit Transfer(address(0), dst, wad);

        return true;
    }

    /**
     * @dev Destroys `wad` tokens from `src`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `src` must have at least `wad` tokens.
     */
    /// if_succeeds {:msg "Burn - balance underflow"} old(_balanceOf[src]) <= _balanceOf[src];
    /// if_succeeds {:msg "Burn - supply underflow"} old(_totalSupply) <= _totalSupply;
    function _burn(address src, uint256 wad) internal virtual returns (bool) {
        unchecked {
            require(_balanceOf[src] >= wad, 'ERC20: Insufficient balance');
            _balanceOf[src] = _balanceOf[src] - wad;
            _totalSupply = _totalSupply - wad;
            emit Transfer(src, address(0), wad);
        }

        return true;
    }
}

File 12 of 13 : ERC20Permit.sol
// SPDX-License-Identifier: MIT
// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol
pragma solidity 0.8.16;

import 'src/tokens/ERC20.sol';
import 'src/interfaces/IERC2612.sol';

/**
 * @dev Extension of {ERC20} that allows token holders to use their tokens
 * without sending any transactions by setting {IERC20-allowance} with a
 * signature using the {permit} method, and then spend them via
 * {IERC20-transferFrom}.
 *
 * The {permit} signature mechanism conforms to the {IERC2612} interface.
 */
abstract contract ERC20Permit is ERC20, IERC2612 {
    mapping(address => uint256) public override nonces;

    bytes32 public immutable PERMIT_TYPEHASH =
        keccak256(
            'Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'
        );
    bytes32 private immutable _DOMAIN_SEPARATOR;
    uint256 public immutable deploymentChainId;

    constructor(
        string memory name_,
        string memory symbol_,
        uint8 decimals_
    ) ERC20(name_, symbol_, decimals_) {
        deploymentChainId = block.chainid;
        _DOMAIN_SEPARATOR = _calculateDomainSeparator(block.chainid);
    }

    /// @dev Calculate the DOMAIN_SEPARATOR.
    function _calculateDomainSeparator(uint256 chainId)
        private
        view
        returns (bytes32)
    {
        return
            keccak256(
                abi.encode(
                    keccak256(
                        'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
                    ),
                    keccak256(bytes(name)),
                    keccak256(bytes(version())),
                    chainId,
                    address(this)
                )
            );
    }

    /// @dev Return the DOMAIN_SEPARATOR.
    function DOMAIN_SEPARATOR() external view returns (bytes32) {
        return
            block.chainid == deploymentChainId
                ? _DOMAIN_SEPARATOR
                : _calculateDomainSeparator(block.chainid);
    }

    /// @dev Setting the version as a function so that it can be overriden
    function version() public pure virtual returns (string memory) {
        return '1';
    }

    /**
     * @dev See {IERC2612-permit}.
     *
     * In cases where the free option is not a concern, deadline can simply be
     * set to uint(-1), so it should be seen as an optional parameter
     */
    function permit(
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override {
        require(deadline >= block.timestamp, 'ERC20Permit: expired deadline');

        bytes32 hashStruct = keccak256(
            abi.encode(
                PERMIT_TYPEHASH,
                owner,
                spender,
                amount,
                nonces[owner]++,
                deadline
            )
        );

        bytes32 hash = keccak256(
            abi.encodePacked(
                '\x19\x01',
                block.chainid == deploymentChainId
                    ? _DOMAIN_SEPARATOR
                    : _calculateDomainSeparator(block.chainid),
                hashStruct
            )
        );

        address signer = ecrecover(hash, v, r, s);
        require(
            signer != address(0) && signer == owner,
            'ERC20Permit: invalid signature'
        );

        _setAllowance(owner, spender, amount);
    }
}

File 13 of 13 : ERC5095.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import 'src/tokens/ERC20Permit.sol';
import 'src/interfaces/IERC5095.sol';
import 'src/interfaces/IRedeemer.sol';
import 'src/interfaces/IMarketPlace.sol';
import 'src/interfaces/IYield.sol';
import 'src/errors/Exception.sol';

import 'src/lib/Cast.sol';
import 'src/lib/Safe.sol';

contract ERC5095 is ERC20Permit, IERC5095 {
    /// @dev unix timestamp when the ERC5095 token can be redeemed
    uint256 public immutable override maturity;
    /// @dev address of the ERC20 token that is returned on ERC5095 redemption
    address public immutable override underlying;
    /// @dev address of the minting authority
    address public immutable lender;
    /// @dev address of the "marketplace" YieldSpace AMM router
    address public immutable marketplace;
    ///@dev Interface to interact with the pool
    address public pool;

    /// @dev address and interface for an external custody contract (necessary for some project's backwards compatability)
    address public immutable redeemer;

    /// @notice ensures that only a certain address can call the function
    /// @param a address that msg.sender must be to be authorized
    modifier authorized(address a) {
        if (msg.sender != a) {
            revert Exception(0, 0, 0, msg.sender, a);
        }
        _;
    }

    constructor(
        address _underlying,
        uint256 _maturity,
        address _redeemer,
        address _lender,
        address _marketplace,
        string memory name_,
        string memory symbol_,
        uint8 decimals_
    ) ERC20Permit(name_, symbol_, decimals_) {
        underlying = _underlying;
        maturity = _maturity;
        redeemer = _redeemer;
        lender = _lender;
        marketplace = _marketplace;
        pool = address(0);
    }

    /// @notice Allows the marketplace to set the pool
    /// @param p Address of the pool
    /// @return bool True if successful
    function setPool(address p)
        external
        authorized(marketplace)
        returns (bool)
    {
        pool = p;
        return true;
    }

    /// @notice Allows the marketplace to spend underlying, principal tokens held by the token
    /// @dev This is necessary when MarketPlace calls pool methods to swap tokens
    /// @return True if successful
    function approveMarketPlace()
        external
        authorized(marketplace)
        returns (bool)
    {
        // Approve the marketplace to spend the token's underlying
        Safe.approve(IERC20(underlying), marketplace, type(uint256).max);

        // Approve the marketplace to spend illuminate PTs
        Safe.approve(IERC20(address(this)), marketplace, type(uint256).max);

        return true;
    }

    /// @notice Post or at maturity, converts an amount of principal tokens to an amount of underlying that would be returned.
    /// @param s The amount of principal tokens to convert
    /// @return uint256 The amount of underlying tokens returned by the conversion
    function convertToUnderlying(uint256 s)
        external
        view
        override
        returns (uint256)
    {
        if (block.timestamp < maturity) {
            return previewRedeem(s);
        }
        return s;
    }

    /// @notice Post or at maturity, converts a desired amount of underlying tokens returned to principal tokens needed.
    /// @param a The amount of underlying tokens to convert
    /// @return uint256 The amount of principal tokens returned by the conversion
    function convertToShares(uint256 a)
        external
        view
        override
        returns (uint256)
    {
        if (block.timestamp < maturity) {
            return previewWithdraw(a);
        }
        return a;
    }

    /// @notice Returns user's PT balance
    /// @param o The address of the owner for which redemption is calculated
    /// @return uint256 The maximum amount of principal tokens that `owner` can redeem.
    function maxRedeem(address o) external view override returns (uint256) {
        return _balanceOf[o];
    }

    /// @notice Post or at maturity, returns user's PT balance. Prior to maturity, returns a previewRedeem for owner's PT balance.
    /// @param  o The address of the owner for which withdrawal is calculated
    /// @return uint256 maximum amount of underlying tokens that `owner` can withdraw.
    function maxWithdraw(address o) external view override returns (uint256) {
        if (block.timestamp < maturity) {
            return previewRedeem(_balanceOf[o]);
        }
        return _balanceOf[o];
    }

    /// @notice After maturity, returns 0. Prior to maturity, returns the amount of `shares` when spending `a` in underlying on a YieldSpace AMM.
    /// @param a The amount of underlying spent
    /// @return uint256 The amount of PT purchased by spending `a` of underlying
    function previewDeposit(uint256 a) public view returns (uint256) {
        if (block.timestamp < maturity) {
            return IYield(pool).sellBasePreview(Cast.u128(a));
        }
        return 0;
    }

    /// @notice After maturity, returns 0. Prior to maturity, returns the amount of `assets` in underlying spent on a purchase of `s` in PT on a YieldSpace AMM.
    /// @param s The amount of principal tokens bought in the simulation
    /// @return uint256 The amount of underlying required to purchase `s` of PT
    function previewMint(uint256 s) public view returns (uint256) {
        if (block.timestamp < maturity) {
            return IYield(pool).buyFYTokenPreview(Cast.u128(s));
        }
        return 0;
    }

    /// @notice Post or at maturity, simulates the effects of redemption. Prior to maturity, returns the amount of `assets` from a sale of `s` PTs on a YieldSpace AMM.
    /// @param s The amount of principal tokens redeemed in the simulation
    /// @return uint256 The amount of underlying returned by `s` of PT redemption
    function previewRedeem(uint256 s) public view override returns (uint256) {
        if (block.timestamp >= maturity) {
            // After maturity, the amount redeemed is based on the Redeemer contract's holdings of the underlying
            return
                Cast.u128(
                    s *
                        Cast.u128(
                            IRedeemer(redeemer).holdings(underlying, maturity)
                        )
                ) / _totalSupply;
        }

        // Prior to maturity, return a a preview of a swap on the pool
        return IYield(pool).sellFYTokenPreview(Cast.u128(s));
    }

    /// @notice Post or at maturity, simulates the effects of withdrawal at the current block. Prior to maturity, simulates the amount of PTs necessary to receive `a` in underlying from the sale of PTs on a YieldSpace AMM.
    /// @param a The amount of underlying tokens withdrawn in the simulation
    /// @return uint256 The amount of principal tokens required for the withdrawal of `a`
    function previewWithdraw(uint256 a) public view override returns (uint256) {
        if (block.timestamp >= maturity) {
            // After maturity, the amount redeemed is based on the Redeemer contract's holdings of the underlying
            return
                (a * _totalSupply) /
                IRedeemer(redeemer).holdings(underlying, maturity);
        }

        // Prior to maturity, return a a preview of a swap on the pool
        return IYield(pool).buyBasePreview(Cast.u128(a));
    }

    /// @notice Before maturity spends `a` of underlying, and sends PTs to `r`. Post or at maturity, reverts.
    /// @param a The amount of underlying tokens deposited
    /// @param r The receiver of the principal tokens
    /// @param m Minimum number of shares that the user will receive
    /// @return uint256 The amount of principal tokens purchased
    function deposit(
        uint256 a,
        address r,
        uint256 m
    ) external returns (uint256) {
        // Execute the deposit
        return _deposit(r, a, m);
    }

    /// @notice Before maturity spends `assets` of underlying, and sends `shares` of PTs to `receiver`. Post or at maturity, reverts.
    /// @param a The amount of underlying tokens deposited
    /// @param r The receiver of the principal tokens
    /// @return uint256 The amount of principal tokens burnt by the withdrawal
    function deposit(uint256 a, address r) external override returns (uint256) {
        // Execute the deposit
        return _deposit(r, a, 0);
    }

    /// @notice Before maturity mints `s` of PTs to `r` by spending underlying. Post or at maturity, reverts.
    /// @param s The amount of shares being minted
    /// @param r The receiver of the underlying tokens being withdrawn
    /// @param m Maximum amount of underlying that the user will spend
    /// @return uint256 The amount of principal tokens purchased
    function mint(
        uint256 s,
        address r,
        uint256 m
    ) external returns (uint256) {
        // Execute the mint
        return _mint(r, s, m);
    }

    /// @notice Before maturity mints `shares` of PTs to `receiver` by spending underlying. Post or at maturity, reverts.
    /// @param s The amount of shares being minted
    /// @param r The receiver of the underlying tokens being withdrawn
    /// @return uint256 The amount of principal tokens purchased
    function mint(uint256 s, address r) external override returns (uint256) {
        // Execute the mint
        return _mint(r, s, type(uint128).max);
    }

    /// @notice At or after maturity, burns PTs from owner and sends `a` underlying to `r`. Before maturity, sends `a` by selling shares of PT on a YieldSpace AMM.
    /// @param a The amount of underlying tokens withdrawn
    /// @param r The receiver of the underlying tokens being withdrawn
    /// @param o The owner of the underlying tokens
    /// @param m Maximum amount of PTs to be sold
    /// @return uint256 The amount of principal tokens burnt by the withdrawal
    function withdraw(
        uint256 a,
        address r,
        address o,
        uint256 m
    ) external returns (uint256) {
        // Execute the withdrawal
        return _withdraw(a, r, o, m);
    }

    /// @notice At or after maturity, burns PTs from owner and sends `a` underlying to `r`. Before maturity, sends `a` by selling shares of PT on a YieldSpace AMM.
    /// @param a The amount of underlying tokens withdrawn
    /// @param r The receiver of the underlying tokens being withdrawn
    /// @param o The owner of the underlying tokens
    /// @return uint256 The amount of principal tokens burnt by the withdrawal
    function withdraw(
        uint256 a,
        address r,
        address o
    ) external override returns (uint256) {
        // Execute the withdrawal
        return _withdraw(a, r, o, type(uint128).max);
    }

    /// @notice At or after maturity, burns exactly `s` of Principal Tokens from `o` and sends underlying tokens to `r`. Before maturity, sends underlying by selling `s` of PT on a YieldSpace AMM.
    /// @param s The number of shares to be burned in exchange for the underlying asset
    /// @param r The receiver of the underlying tokens being withdrawn
    /// @param o Address of the owner of the shares being burned
    /// @param m Minimum amount of underlying that must be received
    /// @return uint256 The amount of underlying tokens distributed by the redemption
    function redeem(
        uint256 s,
        address r,
        address o,
        uint256 m
    ) external returns (uint256) {
        // Execute the redemption
        return _redeem(s, r, o, m);
    }

    /// @notice At or after maturity, burns exactly `shares` of Principal Tokens from `owner` and sends `assets` of underlying tokens to `receiver`. Before maturity, sells `s` of PT on a YieldSpace AMM.
    /// @param s The number of shares to be burned in exchange for the underlying asset
    /// @param r The receiver of the underlying tokens being withdrawn
    /// @param o Address of the owner of the shares being burned
    /// @return uint256 The amount of underlying tokens distributed by the redemption
    function redeem(
        uint256 s,
        address r,
        address o
    ) external override returns (uint256) {
        // Execute the redemption
        return _redeem(s, r, o, 0);
    }

    /// @param f Address to burn from
    /// @param a Amount to burn
    /// @return bool true if successful
    function authBurn(address f, uint256 a)
        external
        authorized(redeemer)
        returns (bool)
    {
        _burn(f, a);
        return true;
    }

    /// @param t Address recieving the minted amount
    /// @param a The amount to mint
    /// @return bool True if successful
    function authMint(address t, uint256 a)
        external
        authorized(lender)
        returns (bool)
    {
        _mint(t, a);
        return true;
    }

    /// @param o Address of the owner of the tokens
    /// @param s Address of the spender
    /// @param a Amount to be approved
    function authApprove(
        address o,
        address s,
        uint256 a
    ) external authorized(redeemer) returns (bool) {
        _allowance[o][s] = a;
        return true;
    }

    function _deposit(
        address r,
        uint256 a,
        uint256 m
    ) internal returns (uint256) {
        // Revert if called at or after maturity
        if (block.timestamp >= maturity) {
            revert Exception(
                21,
                block.timestamp,
                maturity,
                address(0),
                address(0)
            );
        }

        // Receive the funds from the sender
        Safe.transferFrom(IERC20(underlying), msg.sender, address(this), a);

        // Sell the underlying assets for PTs
        uint128 returned = IMarketPlace(marketplace).sellUnderlying(
            underlying,
            maturity,
            Cast.u128(a),
            Cast.u128(m)
        );

        // Pass the received shares onto the intended receiver
        _transfer(address(this), r, returned);

        return returned;
    }

    function _mint(
        address r,
        uint256 s,
        uint256 m
    ) internal returns (uint256) {
        // Revert if called at or after maturity
        if (block.timestamp >= maturity) {
            revert Exception(
                21,
                block.timestamp,
                maturity,
                address(0),
                address(0)
            );
        }

        // Determine how many underlying tokens are needed to mint the shares
        uint256 required = IYield(pool).buyFYTokenPreview(Cast.u128(s));

        // Transfer the underlying to the token
        Safe.transferFrom(
            IERC20(underlying),
            msg.sender,
            address(this),
            required
        );

        // Swap the underlying for principal tokens via the pool
        uint128 sold = IMarketPlace(marketplace).buyPrincipalToken(
            underlying,
            maturity,
            Cast.u128(s),
            Cast.u128(m)
        );

        // Transfer the principal tokens to the desired receiver
        _transfer(address(this), r, s);

        return sold;
    }

    function _withdraw(
        uint256 a,
        address r,
        address o,
        uint256 m
    ) internal returns (uint256) {
        // Determine how many principal tokens are needed to purchase the underlying
        uint256 needed = previewWithdraw(a);

        // Pre maturity
        if (block.timestamp < maturity) {
            // Receive the shares from the caller
            _transfer(o, address(this), needed);

            // If owner is the sender, sell PT without allowance check
            if (o == msg.sender) {
                uint128 returned = IMarketPlace(marketplace).buyUnderlying(
                    underlying,
                    maturity,
                    Cast.u128(a),
                    Cast.u128(m)
                );

                // Transfer the underlying to the desired receiver
                Safe.transfer(IERC20(underlying), r, a);

                return returned;
            } else {
                // Else, sell PT with allowance check
                // Get the allowance of the user spending the tokens
                uint256 allowance = _allowance[o][msg.sender];

                // Check for sufficient allowance
                if (allowance < needed) {
                    revert Exception(20, allowance, a, address(0), address(0));
                }

                // Update the caller's allowance
                _allowance[o][msg.sender] = allowance - needed;

                // Sell the principal tokens for underlying
                uint128 returned = IMarketPlace(marketplace).buyUnderlying(
                    underlying,
                    maturity,
                    Cast.u128(a),
                    Cast.u128(m)
                );

                // Transfer the underlying to the desired receiver
                Safe.transfer(IERC20(underlying), r, returned);

                return returned;
            }
        }
        // Post maturity
        else {
            // If owner is the sender, redeem PT without allowance check
            if (o == msg.sender) {
                // Execute the redemption to the desired receiver
                return
                    IRedeemer(redeemer).authRedeem(
                        underlying,
                        maturity,
                        msg.sender,
                        r,
                        needed
                    );
            } else {
                // Get the allowance of the user spending the tokens
                uint256 allowance = _allowance[o][msg.sender];

                // Check for sufficient allowance
                if (allowance < needed) {
                    revert Exception(
                        20,
                        allowance,
                        needed,
                        address(0),
                        address(0)
                    );
                }

                // Update the callers's allowance
                _allowance[o][msg.sender] = allowance - needed;

                // Execute the redemption to the desired receiver
                return
                    IRedeemer(redeemer).authRedeem(
                        underlying,
                        maturity,
                        o,
                        r,
                        needed
                    );
            }
        }
    }

    function _redeem(
        uint256 s,
        address r,
        address o,
        uint256 m
    ) internal returns (uint256) {
        // Pre-maturity
        if (block.timestamp < maturity) {
            // Receive the funds from the user
            _transfer(o, address(this), s);

            // If owner is the sender, sell PT without allowance check
            if (o == msg.sender) {
                // Swap principal tokens for the underlying asset
                uint128 returned = IMarketPlace(marketplace).sellPrincipalToken(
                    underlying,
                    maturity,
                    Cast.u128(s),
                    Cast.u128(m)
                );

                // Transfer underlying to the desired receiver
                Safe.transfer(IERC20(underlying), r, returned);
                return returned;
                // Else, sell PT with allowance check
            } else {
                // Get the allowance of the user spending the tokens
                uint256 allowance = _allowance[o][msg.sender];

                // Check for sufficient allowance
                if (allowance < s) {
                    revert Exception(20, allowance, s, address(0), address(0));
                }

                // Update the caller's allowance
                _allowance[o][msg.sender] = allowance - s;

                // Sell the principal tokens for the underlying
                uint128 returned = IMarketPlace(marketplace).sellPrincipalToken(
                    underlying,
                    maturity,
                    Cast.u128(s),
                    Cast.u128(m)
                );

                // Transfer the underlying to the desired receiver
                Safe.transfer(IERC20(underlying), r, returned);
                return returned;
            }
            // Post-maturity
        } else {
            // If owner is the sender, redeem PT without allowance check
            if (o == msg.sender) {
                // Execute the redemption to the desired receiver
                return
                    IRedeemer(redeemer).authRedeem(
                        underlying,
                        maturity,
                        msg.sender,
                        r,
                        s
                    );
            } else {
                // Get the allowance of the user spending the tokens
                uint256 allowance = _allowance[o][msg.sender];

                // Check for sufficient allowance
                if (allowance < s) {
                    revert Exception(20, allowance, s, address(0), address(0));
                }

                // Update the caller's allowance
                _allowance[o][msg.sender] = allowance - s;

                // Execute the redemption to the desired receiver
                return
                    IRedeemer(redeemer).authRedeem(
                        underlying,
                        maturity,
                        o,
                        r,
                        s
                    );
            }
        }
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"uint256","name":"_maturity","type":"uint256"},{"internalType":"address","name":"_redeemer","type":"address"},{"internalType":"address","name":"_lender","type":"address"},{"internalType":"address","name":"_marketplace","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"Exception","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","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":"value","type":"uint256"}],"name":"Transfer","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":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"approveMarketPlace","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"o","type":"address"},{"internalType":"address","name":"s","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"}],"name":"authApprove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"f","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"}],"name":"authBurn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"t","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"}],"name":"authMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guy","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"convertToUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketplace","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"o","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"o","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","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":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","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":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"p","type":"address"}],"name":"setPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"},{"internalType":"uint256","name":"m","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"address","name":"r","type":"address"},{"internalType":"address","name":"o","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]

61018080604052346200074d576200359c803803809162000021828562000752565b83398101906101009182828203126200074d576200003f8262000776565b91602081015191620000546040830162000776565b92620000636060840162000776565b91620000726080850162000776565b60a08501519094906001600160401b0381116200074d5782620000979183016200078b565b60c08201519092906001600160401b0381116200074d5760e091620000be9184016200078b565b9101519160ff831683036200074d57620000da60035462000802565b90601f918281116200071d575b506006623f3f3f60e81b01806003556200010360045462000802565b838111620006dc575b506004556005805460ff191660121790558051906001600160401b038211620004bf5781906200013e60035462000802565b848111620006a7575b506020908483116001146200062d5760009262000621575b50508160011b916000199060031b1c1916176003555b8151916001600160401b038311620004bf576200019460045462000802565b828111620005e1575b506020918311600114620005525760ff9392916000918362000546575b50508160011b916000199060031b1c1916176004555b1660ff1960055416176005557f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c96080524660c05260405194600060035496620002198862000802565b80825281602081019360019a8b81169081600014620005285750600114620004d5575b6200024a9250038262000752565b51902060408051919791908101906001600160401b03821181831017620004bf5760209160405282815201603160f81b815220956040519660208801917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8352604089015260608801524660808801523060a088015260a0875260c087019680881060018060401b03891117620004bf57604088905251902060a052865260e052610160928352610120908152610140918252600780546001600160a01b0319169055612d2394856200085986396080518581816108ba0152611647015260a05185818161093c01526116ea015260c0518581816109140152818161157e01526116c1015260e05185818161073201528181610a7c01528181610cf2015281816110470152818161143301528181611ca901528181611cdf01528181611d1201528181611d9401528181611e5201528181611f20015281816120bf0152818161234701528181612778015281816129c80152612b6d015251848181610ab901528181610c1101528181610d9401528181610ff1015281816110ea0152818161146e01528181611fd001528181612168015281816123a4015281816124e6015281816126080152818161270a015281816127cf015281816128730152818161292c01528181612a2801528181612ae401528181612b4101528181612bcf01528181612c670152612cc50152518381816105d6015261151701525182818161099801528181610b4701528181610e0f01528181610fbf0152818161136b015281816123f1015261252f01525181818161087201528181610f13015281816112300152818161201e015281816121a601526126340152f35b634e487b7160e01b600052604160045260246000fd5b506003600090815290918a6000805160206200357c8339815191525b8284106200050d575050509060206200024a928201016200023c565b6020929450805483858801015201910190918a8493620004f1565b60ff19168652506200024a92151560051b820160200190506200023c565b015190503880620001ba565b600460009081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b929190601f198516905b818110620005c8575091600193918560ff97969410620005ae575b505050811b01600455620001d0565b015160001960f88460031b161c191690553880806200059f565b9293602060018192878601518155019501930162000584565b6200061090600460005260206000208480870160051c8201926020881062000617575b0160051c01906200083f565b386200019d565b9250819262000604565b0151905038806200015f565b600360009081526000805160206200357c8339815191529350601f198516905b8181106200068e575090846001959493921062000674575b505050811b0160035562000175565b015160001960f88460031b161c1916905538808062000665565b929360206001819287860151815501950193016200064d565b620006d590600360005260206000208680860160051c8201926020871062000617570160051c01906200083f565b3862000147565b60046000526200071690840160051c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b908101906200083f565b386200010c565b60036000526200074690830160051c6000805160206200357c833981519152908101906200083f565b38620000e7565b600080fd5b601f909101601f19168101906001600160401b03821190821017620004bf57604052565b51906001600160a01b03821682036200074d57565b919080601f840112156200074d578251906001600160401b038211620004bf5760405191602091620007c7601f8301601f191684018562000752565b8184528282870101116200074d5760005b818110620007ee57508260009394955001015290565b8581018301518482018401528201620007d8565b90600182811c9216801562000834575b60208310146200081e57565b634e487b7160e01b600052602260045260246000fd5b91607f169162000812565b8181106200084b575050565b600081556001016200083f56fe60806040526004361015610013575b600080fd5b60003560e01c806306fdde0314610352578063095ea7b3146103495780630a28a477146103405780630fa9d3b11461033757806316f0115b1461032e57806318160ddd146103255780631dc7f5211461031c578063204f83f91461031357806323b872dd1461030a5780632ba29d381461030157806330adf81f146102f8578063313ce567146102ef5780633644e515146102e65780634437152a146102dd5780634cdad506146102d457806354fd4d50146102cb5780636e553f65146102c25780636f307dc3146102b957806370a08231146101fc5780637ecebe00146102b0578063836a1040146102a757806388ba33df1461029e57806392450f201461029557806394bf804d1461028c57806395d89b41146102835780639b3906841461027a5780639f40a7b314610271578063a318c1a414610268578063a9059cbb1461025f578063abc8c7af14610256578063b3d7f6b91461024d578063b460af9414610244578063ba0876521461023b578063bc157ac114610232578063bcead63e14610229578063c6e6f59214610220578063cd0d009614610217578063ce96cb771461020e578063d505accf14610205578063d905777e146101fc578063dd62ed3e146101f35763ef8b30f7146101eb57600080fd5b61000e61181f565b5061000e6117c6565b5061000e610c40565b5061000e6115c5565b5061000e6115a1565b5061000e611565565b5061000e611546565b5061000e611500565b5061000e611422565b5061000e611408565b5061000e6113ee565b5061000e61139a565b5061000e611354565b5061000e61132b565b5061000e61130e565b5061000e6112f1565b5061000e61121f565b5061000e611177565b5061000e611027565b5061000e610fa3565b5061000e610ee9565b5061000e610ce0565b5061000e610c7b565b5061000e610bfa565b5061000e610a5d565b5061000e610a22565b5061000e610a03565b5061000e610973565b5061000e6108ff565b5061000e6108dd565b5061000e6108a1565b5061000e61085b565b5061000e61078a565b5061000e610719565b5061000e6106fa565b5061000e6106db565b5061000e6106b1565b5061000e6105ac565b5061000e610585565b5061000e610552565b5061000e610440565b90600182811c9216801561038b575b602083101461037557565b634e487b7160e01b600052602260045260246000fd5b91607f169161036a565b50634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176103c857604052565b6103d0610395565b604052565b90601f8019910116810190811067ffffffffffffffff8211176103c857604052565b6020808252825181830181905290939260005b82811061042c57505060409293506000838284010152601f8019910116010190565b81810186015184820160400152850161040a565b503461000e576000806003193601126105235760405190806003546104648161035b565b808552916001918083169081156104f9575060011461049e575b61049a8561048e818703826103d5565b604051918291826103f7565b0390f35b9250600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b8284106104e157505050810160200161048e8261049a61047e565b805460208587018101919091529093019281016104c6565b86955061049a9693506020925061048e94915060ff191682840152151560051b820101929361047e565b80fd5b600435906001600160a01b038216820361000e57565b602435906001600160a01b038216820361000e57565b503461000e57604036600319011261000e57602061057b610571610526565b6024359033611954565b6040519015158152f35b503461000e57602036600319011261000e5760206105a46004356120bd565b604051908152f35b503461000e5760408060031936011261000e576105c7610526565b602435906001600160a01b03907f00000000000000000000000000000000000000000000000000000000000000008281163303610690575016907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef610669600092848452600160205285842054818101809111610683575b8585526001602052868520558354818101809111610676575b845585519081529081906020820190565b0390a35160018152602090f35b61067e61188a565b610658565b61068b61188a565b61063f565b8451636d4c6c8960e01b81529081906106ad903360048401611bcb565b0390fd5b503461000e57600036600319011261000e576007546040516001600160a01b039091168152602090f35b503461000e57600036600319011261000e576020600054604051908152f35b503461000e57602036600319011261000e5760206105a4600435611ca7565b503461000e57600036600319011261000e5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b606090600319011261000e576001600160a01b0390600435828116810361000e5791602435908116810361000e579060443590565b503461000e5761079936610755565b906001600160a01b0383163381036107cc575b61049a6107ba8484876118a1565b60405190151581529081906020820190565b600090815260026020908152604080832033845290915290205460018101156107ac5791908183106108165761049a9361080c836107ba95033383611954565b50935090916107ac565b60405162461bcd60e51b815260206004820152601c60248201527f45524332303a20496e73756666696369656e7420617070726f76616c000000006044820152606490fd5b503461000e57600036600319011261000e576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461000e57600036600319011261000e5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b503461000e57600036600319011261000e57602060ff60055416604051908152f35b503461000e57600036600319011261000e57467f0000000000000000000000000000000000000000000000000000000000000000036109635760207f0000000000000000000000000000000000000000000000000000000000000000604051908152f35b602061096e466119a7565b6105a4565b503461000e57602036600319011261000e5761098d610526565b6001600160a01b03907f000000000000000000000000000000000000000000000000000000000000000082811633036109e55750166bffffffffffffffffffffffff60a01b6007541617600755602060405160018152f35b604051636d4c6c8960e01b81529081906106ad903360048401611bcb565b503461000e57602036600319011261000e5760206105a4600435611f1e565b503461000e57600036600319011261000e5761049a604051610a43816103ac565b60018152603160f81b6020820152604051918291826103f7565b503461000e57604036600319011261000e57600435610a7a61053c565b7f00000000000000000000000000000000000000000000000000000000000000009182421015610bc6576001600160801b03610b4360208095610b83947f0000000000000000000000000000000000000000000000000000000000000000916000610af960018060a01b0393610af4813033888a16612273565b611e3c565b60405162771d7560e11b81526001600160a01b03909516600486015260248501929092526001600160801b0390911660448401526000606484015291938492839182906084820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af1908115610bb9575b600091610b8c575b50168092306118a1565b50604051908152f35b610bac9150853d8111610bb2575b610ba481836103d5565b810190611d73565b38610b79565b503d610b9a565b610bc1611b72565b610b71565b604051636d4c6c8960e01b81526015600482015242602482015260448101849052600060648201819052608482015260a490fd5b503461000e57600036600319011261000e576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461000e57602036600319011261000e576001600160a01b03610c62610526565b1660005260016020526020604060002054604051908152f35b503461000e57602036600319011261000e576001600160a01b03610c9d610526565b1660005260066020526020604060002054604051908152f35b606090600319011261000e57600435906024356001600160a01b038116810361000e579060443590565b503461000e57610cef36610cb6565b917f00000000000000000000000000000000000000000000000000000000000000009081421015610eb557600754610d3d90610d31906001600160a01b031681565b6001600160a01b031690565b92610d7d610d4a83611e3c565b60405163fdb0732d60e01b81526001600160801b0390911660048201526020969095879283918891829081906024820190565b03915afa958615610ea8575b600096610e89575b507f0000000000000000000000000000000000000000000000000000000000000000956001600160801b03956001600160a01b0391610dd69088163033858c16612273565b6000610dea610de488611e3c565b94611e3c565b98610e0b6040519a8b9687958694636ba06f1b60e01b865260048601612241565b03927f0000000000000000000000000000000000000000000000000000000000000000165af1938415610e7c575b600094610e57575b5090610e4d91306118a1565b5060405191168152f35b610e4d92919450610e7490863d8811610bb257610ba481836103d5565b939091610e41565b610e84611b72565b610e39565b610ea1919650823d8411610bb257610ba481836103d5565b9438610d91565b610eb0611b72565b610d89565b604051636d4c6c8960e01b81526015600482015242602482015260448101839052600060648201819052608482015260a490fd5b503461000e5760408060031936011261000e57610f04610526565b602435906001600160a01b03907f000000000000000000000000000000000000000000000000000000000000000082811633036106905750167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6106696000938385526001602052610f7b8187872054101561183e565b8385526001602052808686205403868620558085540385558551918291829190602083019252565b503461000e57600036600319011261000e576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081811633036109e5576110168161101c937f000000000000000000000000000000000000000000000000000000000000000016611bf9565b30611bf9565b602060405160018152f35b503461000e57604036600319011261000e5760043561104461053c565b907f00000000000000000000000000000000000000000000000000000000000000009081421015610eb557600754610e0b92919061108c90610d31906001600160a01b031681565b936110ca61109983611e3c565b60405163fdb0732d60e01b81526001600160801b039091166004820152602096879283918391829081906024820190565b03915afa90811561116a575b60009161114d575b506001600160801b03947f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0391906111249088163033858716612273565b600061112f87611e3c565b604051636ba06f1b60e01b8152998a95869485939160048501612213565b6111649150823d8411610bb257610ba481836103d5565b386110de565b611172611b72565b6110d6565b503461000e5760008060031936011261052357604051908060045461119b8161035b565b808552916001918083169081156104f957506001146111c45761049a8561048e818703826103d5565b9250600483527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b82841061120757505050810160200161048e8261049a61047e565b805460208587018101919091529093019281016111ec565b503461000e5761122e36610755565b7f0000000000000000000000000000000000000000000000000000000000000000929091906001600160a01b0390818516330361129c5761129093945016600052600260205260406000209060018060a01b0316600052602052604060002090565b55602060405160018152f35b604051636d4c6c8960e01b8152806106ad873360048401611bcb565b608090600319011261000e57600435906001600160a01b0390602435828116810361000e5791604435908116810361000e579060643590565b503461000e5760206105a4611305366112b8565b92919091612b69565b503461000e5760206105a4611322366112b8565b92919091612768565b503461000e57604036600319011261000e57602061057b61134a610526565b60243590336118a1565b503461000e57600036600319011261000e576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461000e57602036600319011261000e5760206105a4600435611e50565b606090600319011261000e57600435906001600160a01b0390602435828116810361000e5791604435908116810361000e5790565b503461000e5760206105a4611402366113b9565b9161233b565b503461000e5760206105a461141c366113b9565b916129c5565b503461000e5761143136610cb6565b7f000000000000000000000000000000000000000000000000000000000000000092834210156114cc5760209384610b83936001600160801b03937f00000000000000000000000000000000000000000000000000000000000000009360006114ac610de460018060a01b0394610af4813033898d16612273565b95610b436040519788968795869462771d7560e11b865260048601612241565b604051636d4c6c8960e01b81526015600482015242602482015260448101859052600060648201819052608482015260a490fd5b503461000e57600036600319011261000e576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461000e57602036600319011261000e5760206105a4600435611cdd565b503461000e57600036600319011261000e5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b503461000e57602036600319011261000e5760206105a46115c0610526565b611d10565b503461000e5760e036600319011261000e576115df610526565b6115e761053c565b604435906064359260843560ff8116810361000e5760006020916116a761173161173d61179c9961161a42821015611b0a565b6001600160a01b03881660009081526006602052604090209081549161163f83611b56565b9055604080517f00000000000000000000000000000000000000000000000000000000000000008a82019081526001600160a01b03808d1660208301528d1692810192909252606082018d9052608082019390935260a08101919091529093849060c0830190565b03936116bb601f19958681018352826103d5565b519020927f0000000000000000000000000000000000000000000000000000000000000000461486146117b7577f0000000000000000000000000000000000000000000000000000000000000000935b6040519384918983019687909160429261190160f01b8352600283015260228201520190565b039081018352826103d5565b5190206040805191825260ff92909216602082015260a4359181019190915260c435606082015281805260809060015afa156117aa575b600051611797906001600160a01b03908116801515918261179e575b5050611b7f565b611954565b005b84161490503880611790565b6117b2611b72565b611774565b6117c0466119a7565b9361170b565b503461000e57604036600319011261000e5760206118166117e5610526565b6117ed61053c565b6001600160a01b0391821660009081526002855260408082209290931681526020919091522090565b54604051908152f35b503461000e57602036600319011261000e5760206105a4600435611d92565b1561184557565b60405162461bcd60e51b815260206004820152601b60248201527f45524332303a20496e73756666696369656e742062616c616e636500000000006044820152606490fd5b50634e487b7160e01b600052601160045260246000fd5b60207fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9160018060a01b038091169384600052600183526118e986604060002054101561183e565b60008581526001808552604080832080548a900390556001600160a01b0384168352602091909152902054868101809111611947575b6001600160a01b03821660009081526001602052604090205b556040519586521693a3600190565b61194f61188a565b61191f565b6001600160a01b0390811660008181526002602090815260408083208686168452825290912091937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259391928690611938565b604051600354600092916119ba8261035b565b9384825260209485830193600190878282169182600014611acd575050600114611a6a575b5050906119f281611a64949303826103d5565b51902092611a56611a01611aed565b805190830120604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f948101948552602085019790975283015260608201939093523060808201529291829060a0850190565b03601f1981018352826103d5565b51902090565b86919493925060036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b946000915b818310611ab65750939450919250908201016119f2826119df565b865485840185015295860195889390920191611a9b565b60ff1916875292151560051b850190920192506119f291508390506119df565b60405190611afa826103ac565b60018252603160f81b6020830152565b15611b1157565b60405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b6001906000198114611b66570190565b611b6e61188a565b0190565b506040513d6000823e3d90fd5b15611b8657565b60405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606490fd5b60008082526020820181905260408201526001600160a01b0391821660608201529116608082015260a00190565b60405163095ea7b360e01b81526001600160a01b0390921660048301526000196024830152611c3391600091829160449183905af1611c70565b15611c3a57565b60405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b6044820152606490fd5b6000903d9015611ca0579081602014611c93575015611c8e57600090565b600190565b9050602081803e51151590565b908181803efd5b7f00000000000000000000000000000000000000000000000000000000000000004210611cd15790565b611cda90611f1e565b90565b7f00000000000000000000000000000000000000000000000000000000000000004210611d075790565b611cda906120bd565b7f00000000000000000000000000000000000000000000000000000000000000004210611d52576001600160a01b031660009081526001602052604090205490565b6001600160a01b0316600090815260016020526040902054611cda90611f1e565b9081602091031261000e57516001600160801b038116810361000e5790565b7f00000000000000000000000000000000000000000000000000000000000000004210611dbf5750600090565b6007546001600160a01b031690602490602090611ddb90611e3c565b92604051928380926304f9ef2360e21b82526001600160801b0380971660048301525afa908115611e2f575b600091611e1357501690565b611e2b915060203d8111610bb257610ba481836103d5565b1690565b611e37611b72565b611e07565b6001600160801b039081811161000e571690565b7f00000000000000000000000000000000000000000000000000000000000000004210611e7d5750600090565b6007546001600160a01b031690602490602090611e9990611e3c565b926040519283809263fdb0732d60e01b82526001600160801b0380971660048301525afa908115611e2f57600091611e1357501690565b9081602091031261000e575190565b8060001904821181151516611ef2570290565b611efa61188a565b0290565b8115611f08570490565b634e487b7160e01b600052601260045260246000fd5b7f000000000000000000000000000000000000000000000000000000000000000080421015611fb95750611fa260206001600160801b0392611f76611f70610d31610d3160075460018060a01b031690565b91611e3c565b6040516327bab06360e01b81526001600160801b03909116600482015292839190829081906024820190565b03915afa908115611e2f57600091611e1357501690565b6040516391b46a9160e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201526024810191909152611cda9161207091610af4919061206a9061205e90602081806044810103817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156120b0575b600091612082575b50611e3c565b6001600160801b031690565b90611edf565b6001600160801b036000549116611efe565b6120a3915060203d81116120a9575b61209b81836103d5565b810190611ed0565b38612058565b503d612091565b6120b8611b72565b612050565b7f00000000000000000000000000000000000000000000000000000000000000008042101561213b5750611fa260206001600160801b039261210f611f70610d31610d3160075460018060a01b031690565b60405163b0f2892160e01b81526001600160801b03909116600482015292839190829081906024820190565b6121a2906020612151611cda9460005490611edf565b6040516391b46a9160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016600482015260248101939093529192839081906044820190565b03817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa918215612206575b6000926121e6575b50611efe565b6121ff91925060203d81116120a95761209b81836103d5565b90386121e0565b61220e611b72565b6121d8565b606091949392608082019560018060a01b0316825260208201526001600160801b0380931660408201520152565b6001600160a01b03909116815260208101919091526001600160801b0391821660408201529116606082015260800190565b600092836064926122af968295604051946323b872dd60e01b865260018060a01b03809216600487015216602485015260448401525af1611c70565b156122b657565b60405162461bcd60e51b81526020600482015260146024820152731d1c985b9cd9995c88199c9bdb4819985a5b195960621b6044820152606490fd5b919082039182116122ff57565b61230761188a565b565b6001600160a01b0391821681526020810192909252918216604082015291166060820152608081019190915260a00190565b90612345826120bd565b7f0000000000000000000000000000000000000000000000000000000000000000938442106000146125cd5761237c8230836118a1565b506001600160a01b0391818316330361245e575050916123ea916001600160801b03949360207f0000000000000000000000000000000000000000000000000000000000000000956123cd85611e3c565b604051637ef1c17560e11b81529687928392908a60048501612213565b03816000857f0000000000000000000000000000000000000000000000000000000000000000165af1938415612451575b60009461242f575b50611e2b939416612954565b611e2b945061244b9060203d8111610bb257610ba481836103d5565b93612423565b612459611b72565b61241b565b6001600160a01b03821660009081526002602052604090209295926124979033905b9060018060a01b0316600052602052604060002090565b5481811061259757611cda9594936001600160801b03936124e06124c0612528956020956122f2565b6001600160a01b0390921660009081526002602052604090203390612480565b5561250b7f000000000000000000000000000000000000000000000000000000000000000096611e3c565b604051637ef1c17560e11b81529384928392908960048501612213565b038160008a7f0000000000000000000000000000000000000000000000000000000000000000165af190811561258a575b60009161256c575b501693849216612954565b612584915060203d8111610bb257610ba481836103d5565b38612561565b612592611b72565b612559565b604051636d4c6c8960e01b815260146004820152602481019190915260448101869052600060648201819052608482015260a490fd5b6001600160a01b039594919350858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f000000000000000000000000000000000000000000000000000000000000000060048701612309565b03927f0000000000000000000000000000000000000000000000000000000000000000165af1908115612681575b600091612669575090565b611cda915060203d81116120a95761209b81836103d5565b612689611b72565b61265e565b6001600160a01b03811660009081526002602052604090209195916126b4903390612480565b54848110612732578495966126cd6020966000936122f2565b6001600160a01b03841660009081526002602052604090206126f0903390612480565b55612630604051978896879586946370a03ced60e01b86527f000000000000000000000000000000000000000000000000000000000000000060048701612309565b604051636d4c6c8960e01b815260146004820152602481019190915260448101859052600060648201819052608482015260a490fd5b92919092612775816120bd565b937f0000000000000000000000000000000000000000000000000000000000000000928342106000146128ee576127ad8630836118a1565b506001600160a01b0395818716330361281b5750506001600160801b039460207f0000000000000000000000000000000000000000000000000000000000000000956127fb611f7086611e3c565b956123ea6040519788938493637ef1c17560e11b85528b60048601612241565b6001600160a01b03821660009081526002602052604090209395929493612843903390612480565b548181106128b85792611cda9695949261286a6124c06020946001600160801b03976122f2565b55612898611f707f000000000000000000000000000000000000000000000000000000000000000097611e3c565b926125286040519485938493637ef1c17560e11b85528a60048601612241565b604051636d4c6c8960e01b815260146004820152602481019190915260448101879052600060648201819052608482015260a490fd5b6001600160a01b039695945090929150858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f000000000000000000000000000000000000000000000000000000000000000060048701612309565b6044600092838093612987966040519363a9059cbb60e01b855260018060a01b0316600485015260248401525af1611c70565b1561298e57565b60405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b907f0000000000000000000000000000000000000000000000000000000000000000804210600014612b09576129fc8330866118a1565b506001600160a01b03938085163303612a925750906001600160801b036125286020611cda9594612a4d7f000000000000000000000000000000000000000000000000000000000000000096611e3c565b60405163d744e26960e01b81526001600160a01b038816600482015260248101929092526001600160801b031660448201526000606482015291829081906084820190565b6001600160a01b0381166000908152600260205260409020612ab5903390612480565b548481106127325760208594936001600160801b0393612ade6124c0611cda99612528966122f2565b55612a4d7f000000000000000000000000000000000000000000000000000000000000000096611e3c565b6001600160a01b039493858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f000000000000000000000000000000000000000000000000000000000000000060048701612309565b91927f000000000000000000000000000000000000000000000000000000000000000090814210600014612c8c57612ba28430876118a1565b506001600160a01b03948086163303612c145750611cda93929160206001600160801b0392612bf4611f707f000000000000000000000000000000000000000000000000000000000000000097611e3c565b92612528604051948593849363d744e26960e01b85528a60048601612241565b6001600160a01b0381166000908152600260205260409020612c37903390612480565b54858110612597576001600160801b039286959492612c5e6124c0611cda996020956122f2565b55612bf4611f707f000000000000000000000000000000000000000000000000000000000000000097611e3c565b506001600160a01b039493858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f00000000000000000000000000000000000000000000000000000000000000006004870161230956fea26469706673582212208530e193d9391de7f27e9397e62718fc6cde8627999f6fa7228b7435e6f7b91564736f6c63430008100033c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000064a20f800000000000000000000000004ea57ef203e91ae8c7d9822aa09cc719a9c01ac6000000000000000000000000429b47c4aeadd42bbcb118651c8984086bfc4551000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000012697074555344432d313638383334323430300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d697074555344432d4a554e323300000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361015610013575b600080fd5b60003560e01c806306fdde0314610352578063095ea7b3146103495780630a28a477146103405780630fa9d3b11461033757806316f0115b1461032e57806318160ddd146103255780631dc7f5211461031c578063204f83f91461031357806323b872dd1461030a5780632ba29d381461030157806330adf81f146102f8578063313ce567146102ef5780633644e515146102e65780634437152a146102dd5780634cdad506146102d457806354fd4d50146102cb5780636e553f65146102c25780636f307dc3146102b957806370a08231146101fc5780637ecebe00146102b0578063836a1040146102a757806388ba33df1461029e57806392450f201461029557806394bf804d1461028c57806395d89b41146102835780639b3906841461027a5780639f40a7b314610271578063a318c1a414610268578063a9059cbb1461025f578063abc8c7af14610256578063b3d7f6b91461024d578063b460af9414610244578063ba0876521461023b578063bc157ac114610232578063bcead63e14610229578063c6e6f59214610220578063cd0d009614610217578063ce96cb771461020e578063d505accf14610205578063d905777e146101fc578063dd62ed3e146101f35763ef8b30f7146101eb57600080fd5b61000e61181f565b5061000e6117c6565b5061000e610c40565b5061000e6115c5565b5061000e6115a1565b5061000e611565565b5061000e611546565b5061000e611500565b5061000e611422565b5061000e611408565b5061000e6113ee565b5061000e61139a565b5061000e611354565b5061000e61132b565b5061000e61130e565b5061000e6112f1565b5061000e61121f565b5061000e611177565b5061000e611027565b5061000e610fa3565b5061000e610ee9565b5061000e610ce0565b5061000e610c7b565b5061000e610bfa565b5061000e610a5d565b5061000e610a22565b5061000e610a03565b5061000e610973565b5061000e6108ff565b5061000e6108dd565b5061000e6108a1565b5061000e61085b565b5061000e61078a565b5061000e610719565b5061000e6106fa565b5061000e6106db565b5061000e6106b1565b5061000e6105ac565b5061000e610585565b5061000e610552565b5061000e610440565b90600182811c9216801561038b575b602083101461037557565b634e487b7160e01b600052602260045260246000fd5b91607f169161036a565b50634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff8211176103c857604052565b6103d0610395565b604052565b90601f8019910116810190811067ffffffffffffffff8211176103c857604052565b6020808252825181830181905290939260005b82811061042c57505060409293506000838284010152601f8019910116010190565b81810186015184820160400152850161040a565b503461000e576000806003193601126105235760405190806003546104648161035b565b808552916001918083169081156104f9575060011461049e575b61049a8561048e818703826103d5565b604051918291826103f7565b0390f35b9250600383527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b8284106104e157505050810160200161048e8261049a61047e565b805460208587018101919091529093019281016104c6565b86955061049a9693506020925061048e94915060ff191682840152151560051b820101929361047e565b80fd5b600435906001600160a01b038216820361000e57565b602435906001600160a01b038216820361000e57565b503461000e57604036600319011261000e57602061057b610571610526565b6024359033611954565b6040519015158152f35b503461000e57602036600319011261000e5760206105a46004356120bd565b604051908152f35b503461000e5760408060031936011261000e576105c7610526565b602435906001600160a01b03907f000000000000000000000000429b47c4aeadd42bbcb118651c8984086bfc45518281163303610690575016907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef610669600092848452600160205285842054818101809111610683575b8585526001602052868520558354818101809111610676575b845585519081529081906020820190565b0390a35160018152602090f35b61067e61188a565b610658565b61068b61188a565b61063f565b8451636d4c6c8960e01b81529081906106ad903360048401611bcb565b0390fd5b503461000e57600036600319011261000e576007546040516001600160a01b039091168152602090f35b503461000e57600036600319011261000e576020600054604051908152f35b503461000e57602036600319011261000e5760206105a4600435611ca7565b503461000e57600036600319011261000e5760206040517f0000000000000000000000000000000000000000000000000000000064a20f808152f35b606090600319011261000e576001600160a01b0390600435828116810361000e5791602435908116810361000e579060443590565b503461000e5761079936610755565b906001600160a01b0383163381036107cc575b61049a6107ba8484876118a1565b60405190151581529081906020820190565b600090815260026020908152604080832033845290915290205460018101156107ac5791908183106108165761049a9361080c836107ba95033383611954565b50935090916107ac565b60405162461bcd60e51b815260206004820152601c60248201527f45524332303a20496e73756666696369656e7420617070726f76616c000000006044820152606490fd5b503461000e57600036600319011261000e576040517f0000000000000000000000004ea57ef203e91ae8c7d9822aa09cc719a9c01ac66001600160a01b03168152602090f35b503461000e57600036600319011261000e5760206040517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98152f35b503461000e57600036600319011261000e57602060ff60055416604051908152f35b503461000e57600036600319011261000e57467f0000000000000000000000000000000000000000000000000000000000000001036109635760207f92a2ffc3a64d5ee40b314237b14b10daa95fafa1cdb6176a6dddda6cbb9db4c2604051908152f35b602061096e466119a7565b6105a4565b503461000e57602036600319011261000e5761098d610526565b6001600160a01b03907f000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f82811633036109e55750166bffffffffffffffffffffffff60a01b6007541617600755602060405160018152f35b604051636d4c6c8960e01b81529081906106ad903360048401611bcb565b503461000e57602036600319011261000e5760206105a4600435611f1e565b503461000e57600036600319011261000e5761049a604051610a43816103ac565b60018152603160f81b6020820152604051918291826103f7565b503461000e57604036600319011261000e57600435610a7a61053c565b7f0000000000000000000000000000000000000000000000000000000064a20f809182421015610bc6576001600160801b03610b4360208095610b83947f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48916000610af960018060a01b0393610af4813033888a16612273565b611e3c565b60405162771d7560e11b81526001600160a01b03909516600486015260248501929092526001600160801b0390911660448401526000606484015291938492839182906084820190565b03927f000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f165af1908115610bb9575b600091610b8c575b50168092306118a1565b50604051908152f35b610bac9150853d8111610bb2575b610ba481836103d5565b810190611d73565b38610b79565b503d610b9a565b610bc1611b72565b610b71565b604051636d4c6c8960e01b81526015600482015242602482015260448101849052600060648201819052608482015260a490fd5b503461000e57600036600319011261000e576040517f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03168152602090f35b503461000e57602036600319011261000e576001600160a01b03610c62610526565b1660005260016020526020604060002054604051908152f35b503461000e57602036600319011261000e576001600160a01b03610c9d610526565b1660005260066020526020604060002054604051908152f35b606090600319011261000e57600435906024356001600160a01b038116810361000e579060443590565b503461000e57610cef36610cb6565b917f0000000000000000000000000000000000000000000000000000000064a20f809081421015610eb557600754610d3d90610d31906001600160a01b031681565b6001600160a01b031690565b92610d7d610d4a83611e3c565b60405163fdb0732d60e01b81526001600160801b0390911660048201526020969095879283918891829081906024820190565b03915afa958615610ea8575b600096610e89575b507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48956001600160801b03956001600160a01b0391610dd69088163033858c16612273565b6000610dea610de488611e3c565b94611e3c565b98610e0b6040519a8b9687958694636ba06f1b60e01b865260048601612241565b03927f000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f165af1938415610e7c575b600094610e57575b5090610e4d91306118a1565b5060405191168152f35b610e4d92919450610e7490863d8811610bb257610ba481836103d5565b939091610e41565b610e84611b72565b610e39565b610ea1919650823d8411610bb257610ba481836103d5565b9438610d91565b610eb0611b72565b610d89565b604051636d4c6c8960e01b81526015600482015242602482015260448101839052600060648201819052608482015260a490fd5b503461000e5760408060031936011261000e57610f04610526565b602435906001600160a01b03907f0000000000000000000000004ea57ef203e91ae8c7d9822aa09cc719a9c01ac682811633036106905750167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6106696000938385526001602052610f7b8187872054101561183e565b8385526001602052808686205403868620558085540385558551918291829190602083019252565b503461000e57600036600319011261000e576001600160a01b037f000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f81811633036109e5576110168161101c937f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816611bf9565b30611bf9565b602060405160018152f35b503461000e57604036600319011261000e5760043561104461053c565b907f0000000000000000000000000000000000000000000000000000000064a20f809081421015610eb557600754610e0b92919061108c90610d31906001600160a01b031681565b936110ca61109983611e3c565b60405163fdb0732d60e01b81526001600160801b039091166004820152602096879283918391829081906024820190565b03915afa90811561116a575b60009161114d575b506001600160801b03947f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48916001600160a01b0391906111249088163033858716612273565b600061112f87611e3c565b604051636ba06f1b60e01b8152998a95869485939160048501612213565b6111649150823d8411610bb257610ba481836103d5565b386110de565b611172611b72565b6110d6565b503461000e5760008060031936011261052357604051908060045461119b8161035b565b808552916001918083169081156104f957506001146111c45761049a8561048e818703826103d5565b9250600483527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b82841061120757505050810160200161048e8261049a61047e565b805460208587018101919091529093019281016111ec565b503461000e5761122e36610755565b7f0000000000000000000000004ea57ef203e91ae8c7d9822aa09cc719a9c01ac6929091906001600160a01b0390818516330361129c5761129093945016600052600260205260406000209060018060a01b0316600052602052604060002090565b55602060405160018152f35b604051636d4c6c8960e01b8152806106ad873360048401611bcb565b608090600319011261000e57600435906001600160a01b0390602435828116810361000e5791604435908116810361000e579060643590565b503461000e5760206105a4611305366112b8565b92919091612b69565b503461000e5760206105a4611322366112b8565b92919091612768565b503461000e57604036600319011261000e57602061057b61134a610526565b60243590336118a1565b503461000e57600036600319011261000e576040517f000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f6001600160a01b03168152602090f35b503461000e57602036600319011261000e5760206105a4600435611e50565b606090600319011261000e57600435906001600160a01b0390602435828116810361000e5791604435908116810361000e5790565b503461000e5760206105a4611402366113b9565b9161233b565b503461000e5760206105a461141c366113b9565b916129c5565b503461000e5761143136610cb6565b7f0000000000000000000000000000000000000000000000000000000064a20f8092834210156114cc5760209384610b83936001600160801b03937f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489360006114ac610de460018060a01b0394610af4813033898d16612273565b95610b436040519788968795869462771d7560e11b865260048601612241565b604051636d4c6c8960e01b81526015600482015242602482015260448101859052600060648201819052608482015260a490fd5b503461000e57600036600319011261000e576040517f000000000000000000000000429b47c4aeadd42bbcb118651c8984086bfc45516001600160a01b03168152602090f35b503461000e57602036600319011261000e5760206105a4600435611cdd565b503461000e57600036600319011261000e5760206040517f00000000000000000000000000000000000000000000000000000000000000018152f35b503461000e57602036600319011261000e5760206105a46115c0610526565b611d10565b503461000e5760e036600319011261000e576115df610526565b6115e761053c565b604435906064359260843560ff8116810361000e5760006020916116a761173161173d61179c9961161a42821015611b0a565b6001600160a01b03881660009081526006602052604090209081549161163f83611b56565b9055604080517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a82019081526001600160a01b03808d1660208301528d1692810192909252606082018d9052608082019390935260a08101919091529093849060c0830190565b03936116bb601f19958681018352826103d5565b519020927f0000000000000000000000000000000000000000000000000000000000000001461486146117b7577f92a2ffc3a64d5ee40b314237b14b10daa95fafa1cdb6176a6dddda6cbb9db4c2935b6040519384918983019687909160429261190160f01b8352600283015260228201520190565b039081018352826103d5565b5190206040805191825260ff92909216602082015260a4359181019190915260c435606082015281805260809060015afa156117aa575b600051611797906001600160a01b03908116801515918261179e575b5050611b7f565b611954565b005b84161490503880611790565b6117b2611b72565b611774565b6117c0466119a7565b9361170b565b503461000e57604036600319011261000e5760206118166117e5610526565b6117ed61053c565b6001600160a01b0391821660009081526002855260408082209290931681526020919091522090565b54604051908152f35b503461000e57602036600319011261000e5760206105a4600435611d92565b1561184557565b60405162461bcd60e51b815260206004820152601b60248201527f45524332303a20496e73756666696369656e742062616c616e636500000000006044820152606490fd5b50634e487b7160e01b600052601160045260246000fd5b60207fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9160018060a01b038091169384600052600183526118e986604060002054101561183e565b60008581526001808552604080832080548a900390556001600160a01b0384168352602091909152902054868101809111611947575b6001600160a01b03821660009081526001602052604090205b556040519586521693a3600190565b61194f61188a565b61191f565b6001600160a01b0390811660008181526002602090815260408083208686168452825290912091937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259391928690611938565b604051600354600092916119ba8261035b565b9384825260209485830193600190878282169182600014611acd575050600114611a6a575b5050906119f281611a64949303826103d5565b51902092611a56611a01611aed565b805190830120604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f948101948552602085019790975283015260608201939093523060808201529291829060a0850190565b03601f1981018352826103d5565b51902090565b86919493925060036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b946000915b818310611ab65750939450919250908201016119f2826119df565b865485840185015295860195889390920191611a9b565b60ff1916875292151560051b850190920192506119f291508390506119df565b60405190611afa826103ac565b60018252603160f81b6020830152565b15611b1157565b60405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b6001906000198114611b66570190565b611b6e61188a565b0190565b506040513d6000823e3d90fd5b15611b8657565b60405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606490fd5b60008082526020820181905260408201526001600160a01b0391821660608201529116608082015260a00190565b60405163095ea7b360e01b81526001600160a01b0390921660048301526000196024830152611c3391600091829160449183905af1611c70565b15611c3a57565b60405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b6044820152606490fd5b6000903d9015611ca0579081602014611c93575015611c8e57600090565b600190565b9050602081803e51151590565b908181803efd5b7f0000000000000000000000000000000000000000000000000000000064a20f804210611cd15790565b611cda90611f1e565b90565b7f0000000000000000000000000000000000000000000000000000000064a20f804210611d075790565b611cda906120bd565b7f0000000000000000000000000000000000000000000000000000000064a20f804210611d52576001600160a01b031660009081526001602052604090205490565b6001600160a01b0316600090815260016020526040902054611cda90611f1e565b9081602091031261000e57516001600160801b038116810361000e5790565b7f0000000000000000000000000000000000000000000000000000000064a20f804210611dbf5750600090565b6007546001600160a01b031690602490602090611ddb90611e3c565b92604051928380926304f9ef2360e21b82526001600160801b0380971660048301525afa908115611e2f575b600091611e1357501690565b611e2b915060203d8111610bb257610ba481836103d5565b1690565b611e37611b72565b611e07565b6001600160801b039081811161000e571690565b7f0000000000000000000000000000000000000000000000000000000064a20f804210611e7d5750600090565b6007546001600160a01b031690602490602090611e9990611e3c565b926040519283809263fdb0732d60e01b82526001600160801b0380971660048301525afa908115611e2f57600091611e1357501690565b9081602091031261000e575190565b8060001904821181151516611ef2570290565b611efa61188a565b0290565b8115611f08570490565b634e487b7160e01b600052601260045260246000fd5b7f0000000000000000000000000000000000000000000000000000000064a20f8080421015611fb95750611fa260206001600160801b0392611f76611f70610d31610d3160075460018060a01b031690565b91611e3c565b6040516327bab06360e01b81526001600160801b03909116600482015292839190829081906024820190565b03915afa908115611e2f57600091611e1357501690565b6040516391b46a9160e01b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481660048201526024810191909152611cda9161207091610af4919061206a9061205e90602081806044810103817f0000000000000000000000004ea57ef203e91ae8c7d9822aa09cc719a9c01ac66001600160a01b03165afa9081156120b0575b600091612082575b50611e3c565b6001600160801b031690565b90611edf565b6001600160801b036000549116611efe565b6120a3915060203d81116120a9575b61209b81836103d5565b810190611ed0565b38612058565b503d612091565b6120b8611b72565b612050565b7f0000000000000000000000000000000000000000000000000000000064a20f808042101561213b5750611fa260206001600160801b039261210f611f70610d31610d3160075460018060a01b031690565b60405163b0f2892160e01b81526001600160801b03909116600482015292839190829081906024820190565b6121a2906020612151611cda9460005490611edf565b6040516391b46a9160e01b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816600482015260248101939093529192839081906044820190565b03817f0000000000000000000000004ea57ef203e91ae8c7d9822aa09cc719a9c01ac66001600160a01b03165afa918215612206575b6000926121e6575b50611efe565b6121ff91925060203d81116120a95761209b81836103d5565b90386121e0565b61220e611b72565b6121d8565b606091949392608082019560018060a01b0316825260208201526001600160801b0380931660408201520152565b6001600160a01b03909116815260208101919091526001600160801b0391821660408201529116606082015260800190565b600092836064926122af968295604051946323b872dd60e01b865260018060a01b03809216600487015216602485015260448401525af1611c70565b156122b657565b60405162461bcd60e51b81526020600482015260146024820152731d1c985b9cd9995c88199c9bdb4819985a5b195960621b6044820152606490fd5b919082039182116122ff57565b61230761188a565b565b6001600160a01b0391821681526020810192909252918216604082015291166060820152608081019190915260a00190565b90612345826120bd565b7f0000000000000000000000000000000000000000000000000000000064a20f80938442106000146125cd5761237c8230836118a1565b506001600160a01b0391818316330361245e575050916123ea916001600160801b03949360207f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48956123cd85611e3c565b604051637ef1c17560e11b81529687928392908a60048501612213565b03816000857f000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f165af1938415612451575b60009461242f575b50611e2b939416612954565b611e2b945061244b9060203d8111610bb257610ba481836103d5565b93612423565b612459611b72565b61241b565b6001600160a01b03821660009081526002602052604090209295926124979033905b9060018060a01b0316600052602052604060002090565b5481811061259757611cda9594936001600160801b03936124e06124c0612528956020956122f2565b6001600160a01b0390921660009081526002602052604090203390612480565b5561250b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4896611e3c565b604051637ef1c17560e11b81529384928392908960048501612213565b038160008a7f000000000000000000000000cd1d02fda51cd24123e857ce94e4356d5c073b3f165af190811561258a575b60009161256c575b501693849216612954565b612584915060203d8111610bb257610ba481836103d5565b38612561565b612592611b72565b612559565b604051636d4c6c8960e01b815260146004820152602481019190915260448101869052600060648201819052608482015260a490fd5b6001600160a01b039594919350858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860048701612309565b03927f0000000000000000000000004ea57ef203e91ae8c7d9822aa09cc719a9c01ac6165af1908115612681575b600091612669575090565b611cda915060203d81116120a95761209b81836103d5565b612689611b72565b61265e565b6001600160a01b03811660009081526002602052604090209195916126b4903390612480565b54848110612732578495966126cd6020966000936122f2565b6001600160a01b03841660009081526002602052604090206126f0903390612480565b55612630604051978896879586946370a03ced60e01b86527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860048701612309565b604051636d4c6c8960e01b815260146004820152602481019190915260448101859052600060648201819052608482015260a490fd5b92919092612775816120bd565b937f0000000000000000000000000000000000000000000000000000000064a20f80928342106000146128ee576127ad8630836118a1565b506001600160a01b0395818716330361281b5750506001600160801b039460207f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48956127fb611f7086611e3c565b956123ea6040519788938493637ef1c17560e11b85528b60048601612241565b6001600160a01b03821660009081526002602052604090209395929493612843903390612480565b548181106128b85792611cda9695949261286a6124c06020946001600160801b03976122f2565b55612898611f707f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4897611e3c565b926125286040519485938493637ef1c17560e11b85528a60048601612241565b604051636d4c6c8960e01b815260146004820152602481019190915260448101879052600060648201819052608482015260a490fd5b6001600160a01b039695945090929150858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860048701612309565b6044600092838093612987966040519363a9059cbb60e01b855260018060a01b0316600485015260248401525af1611c70565b1561298e57565b60405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606490fd5b907f0000000000000000000000000000000000000000000000000000000064a20f80804210600014612b09576129fc8330866118a1565b506001600160a01b03938085163303612a925750906001600160801b036125286020611cda9594612a4d7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4896611e3c565b60405163d744e26960e01b81526001600160a01b038816600482015260248101929092526001600160801b031660448201526000606482015291829081906084820190565b6001600160a01b0381166000908152600260205260409020612ab5903390612480565b548481106127325760208594936001600160801b0393612ade6124c0611cda99612528966122f2565b55612a4d7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4896611e3c565b6001600160a01b039493858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860048701612309565b91927f0000000000000000000000000000000000000000000000000000000064a20f8090814210600014612c8c57612ba28430876118a1565b506001600160a01b03948086163303612c145750611cda93929160206001600160801b0392612bf4611f707f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4897611e3c565b92612528604051948593849363d744e26960e01b85528a60048601612241565b6001600160a01b0381166000908152600260205260409020612c37903390612480565b54858110612597576001600160801b039286959492612c5e6124c0611cda996020956122f2565b55612bf4611f707f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4897611e3c565b506001600160a01b039493858116330361268e5750936020929160006126309596604051968795869485936370a03ced60e01b855233907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486004870161230956fea26469706673582212208530e193d9391de7f27e9397e62718fc6cde8627999f6fa7228b7435e6f7b91564736f6c63430008100033

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.