ETH Price: $3,394.35 (+1.65%)

Token

vTHOR (vTHOR)
 

Overview

Max Total Supply

60,903,966.603002104476319849 vTHOR

Holders

2,505

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
583,332.999999999995 vTHOR

Value
$0.00
0x9ddea6c0bfa53bdf244ade7ba5ed7e227f6e58b4
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
vTHOR

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion
File 1 of 7 : vTHOR.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import { ERC20Vote } from "../lib/ERC20Vote.sol";
import { IERC20 } from "./interfaces/IERC20.sol";
import { IERC4626 } from "./interfaces/IERC4626.sol";
import { SafeTransferLib } from "../lib/SafeTransferLib.sol";
import { FixedPointMathLib } from "../lib/FixedPointMathLib.sol";
import { ReentrancyGuard } from "../lib/ReentrancyGuard.sol";

contract vTHOR is IERC4626, ERC20Vote, ReentrancyGuard {
    using SafeTransferLib for address;
    using FixedPointMathLib for uint256;

    IERC20 public _asset;

    constructor(IERC20 asset_) ERC20Vote("vTHOR", "vTHOR", 18) {
        _asset = asset_;
    }

    function asset() public view returns (address) {
        return address(_asset);
    }

    function totalAssets() public view returns (uint256) {
        return _asset.balanceOf(address(this));
    }

    function convertToShares(uint256 assets) public view returns (uint256) {
        uint256 supply = totalSupply;
        return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());
    }

    function convertToAssets(uint256 shares) public view returns (uint256) {
        uint256 supply = totalSupply;
        return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
    }

    function previewDeposit(uint256 assets) public view returns (uint256) {
        return convertToShares(assets);
    }

    function previewMint(uint256 shares) public view returns (uint256) {
        uint256 supply = totalSupply;
        return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
    }

    function previewWithdraw(uint256 assets) public view returns (uint256) {
        uint256 supply = totalSupply;
        return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());
    }

    function previewRedeem(uint256 shares) public view returns (uint256) {
        return convertToAssets(shares);
    }

    function maxDeposit(address) public view returns (uint256) {
        return type(uint256).max;
    }

    function maxMint(address) public view returns (uint256) {
        return type(uint256).max;
    }

    function maxWithdraw(address owner) public view returns (uint256) {
        return convertToAssets(balanceOf[owner]);
    }

    function maxRedeem(address owner) public view returns (uint256) {
        return balanceOf[owner];
    }

    function deposit(uint256 assets, address receiver) public nonReentrant returns (uint256 shares) {
        // Check for rounding error since we round down in previewDeposit.
        require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");
        // Need to transfer before minting or ERC777s could reenter.
        address(_asset).safeTransferFrom(msg.sender, address(this), assets);
        _mint(receiver, shares);
        emit Deposit(msg.sender, receiver, assets, shares);
    }

    function mint(uint256 shares, address receiver) public nonReentrant returns (uint256 assets) {
        assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.
        // Need to transfer before minting or ERC777s could reenter.
        address(_asset).safeTransferFrom(msg.sender, address(this), assets);
        _mint(receiver, shares);
        emit Deposit(msg.sender, receiver, assets, shares);
    }

    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public nonReentrant returns (uint256 shares) {
        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.
        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.
            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }
        _burn(owner, shares);
        emit Withdraw(msg.sender, receiver, owner, assets, shares);
        address(_asset).safeTransfer(receiver, assets);
    }

    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public nonReentrant returns (uint256 assets) {
        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.
            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }
        // Check for rounding error since we round down in previewRedeem.
        require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");
        _burn(owner, shares);
        emit Withdraw(msg.sender, receiver, owner, assets, shares);
        address(_asset).safeTransfer(receiver, assets);
    }
}

File 2 of 7 : ERC20Vote.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas-optimized ERC20 + EIP-2612 implementation with COMP-style governance.
abstract contract ERC20Vote {
    /*///////////////////////////////////////////////////////////////
                            EVENTS
    //////////////////////////////////////////////////////////////*/

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

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

    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

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

    string public name;

    string public symbol;

    uint8 public immutable decimals;

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

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

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

    /*///////////////////////////////////////////////////////////////
                            DAO STORAGE
    //////////////////////////////////////////////////////////////*/

    bytes32 public constant DELEGATION_TYPEHASH = 
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    mapping(address => address) internal _delegates;

    mapping(address => mapping(uint256 => Checkpoint)) public checkpoints;

    mapping(address => uint256) public numCheckpoints;

    struct Checkpoint {
        uint32 fromTimestamp;
        uint96 votes;
    }

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

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

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

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

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

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

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

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

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

        return true;
    }

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

        // this is safe from overflow because the sum of all user
        // balances can't exceed 'type(uint256).max'
        unchecked {
            balanceOf[to] += amount;
        }
        
        _moveDelegates(delegates(msg.sender), delegates(to), amount);

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

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        if (allowance[from][msg.sender] != type(uint256).max) 
            allowance[from][msg.sender] -= amount;

        balanceOf[from] -= amount;

        // this is safe from overflow because the sum of all user
        // balances can't exceed 'type(uint256).max'
        unchecked {
            balanceOf[to] += amount;
        }
        
        _moveDelegates(delegates(from), delegates(to), amount);

        emit Transfer(from, to, amount);

        return true;
    }

    /*///////////////////////////////////////////////////////////////
                            DAO LOGIC
    //////////////////////////////////////////////////////////////*/

    function delegates(address delegator) public view virtual returns (address delegatee) {
        address current = _delegates[delegator];
        
        delegatee = current == address(0) ? delegator : current;
    }

    function getCurrentVotes(address account) public view virtual returns (uint256 votes) {
        // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
        unchecked {
            uint256 nCheckpoints = numCheckpoints[account];

            votes = nCheckpoints != 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
        }
    }

    function delegate(address delegatee) public virtual {
        _delegate(msg.sender, delegatee);
    }

    function delegateBySig(
        address delegatee, 
        uint256 nonce, 
        uint256 expiry, 
        uint8 v, 
        bytes32 r, 
        bytes32 s
    ) public virtual {
        bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));

        bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), structHash));

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

        require(signatory != address(0), "ZERO_ADDRESS");
        
        // this is reasonably safe from overflow because incrementing `nonces` beyond
        // 'type(uint256).max' is exceedingly unlikely compared to optimization benefits
        unchecked {
            require(nonce == nonces[signatory]++, "INVALID_NONCE");
        }

        require(block.timestamp <= expiry, "SIGNATURE_EXPIRED");

        _delegate(signatory, delegatee);
    }

    function getPriorVotes(address account, uint256 timestamp) public view virtual returns (uint96 votes) {
        require(block.timestamp > timestamp, "NOT_YET_DETERMINED");

        uint256 nCheckpoints = numCheckpoints[account];

        if (nCheckpoints == 0) return 0;
        
        // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
        unchecked {
            if (checkpoints[account][nCheckpoints - 1].fromTimestamp <= timestamp)
                
                return checkpoints[account][nCheckpoints - 1].votes;

            if (checkpoints[account][0].fromTimestamp > timestamp) return 0;

            uint256 lower;
            
            // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
            uint256 upper = nCheckpoints - 1;

            while (upper > lower) {
                // this is safe from underflow because `upper` ceiling is provided
                uint256 center = upper - (upper - lower) / 2;

                Checkpoint memory cp = checkpoints[account][center];

                if (cp.fromTimestamp == timestamp) {
                    return cp.votes;
                } else if (cp.fromTimestamp < timestamp) {
                    lower = center;
                } else {
                    upper = center - 1;
                }
            }

        return checkpoints[account][lower].votes;

        }
    }

    function _delegate(address delegator, address delegatee) internal virtual {
        address currentDelegate = _delegates[delegator];

        _delegates[delegator] = delegatee;

        _moveDelegates(currentDelegate, delegatee, balanceOf[delegator]);

        emit DelegateChanged(delegator, currentDelegate, delegatee);
    }

    function _moveDelegates(
        address srcRep, 
        address dstRep, 
        uint256 amount
    ) internal virtual {
        if (srcRep != dstRep && amount != 0) 
            if (srcRep != address(0)) {
                uint256 srcRepNum = numCheckpoints[srcRep];
                
                uint256 srcRepOld = srcRepNum != 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;

                uint256 srcRepNew = srcRepOld - amount;

                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }
            
            if (dstRep != address(0)) {
                uint256 dstRepNum = numCheckpoints[dstRep];

                uint256 dstRepOld = dstRepNum != 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;

                uint256 dstRepNew = dstRepOld + amount;

                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
    }

    function _writeCheckpoint(
        address delegatee, 
        uint256 nCheckpoints, 
        uint256 oldVotes, 
        uint256 newVotes
    ) internal virtual {
        unchecked {
            // this is safe from underflow because decrement only occurs if `nCheckpoints` is positive
            if (nCheckpoints != 0 && checkpoints[delegatee][nCheckpoints - 1].fromTimestamp == block.timestamp) {
                checkpoints[delegatee][nCheckpoints - 1].votes = safeCastTo96(newVotes);
            } else {
                checkpoints[delegatee][nCheckpoints] = Checkpoint(safeCastTo32(block.timestamp), safeCastTo96(newVotes));
                
                // this is reasonably safe from overflow because incrementing `nCheckpoints` beyond
                // 'type(uint256).max' is exceedingly unlikely compared to optimization benefits
                numCheckpoints[delegatee] = nCheckpoints + 1;
            }
        }

        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
    }

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

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

        // this is reasonably safe from overflow because incrementing `nonces` beyond
        // 'type(uint256).max' is exceedingly unlikely compared to optimization benefits
        unchecked {
            bytes32 digest = keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    DOMAIN_SEPARATOR(),
                    keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                )
            );

            address recoveredAddress = ecrecover(digest, v, r, s);
            
            require(recoveredAddress != address(0) && recoveredAddress == owner, 'INVALID_PERMIT_SIGNATURE');

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

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

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

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

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

        // this is safe because the sum of all user
        // balances can't exceed 'type(uint256).max'
        unchecked {
            balanceOf[to] += amount;
        }

        _moveDelegates(address(0), delegates(to), amount);

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

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

        // this is safe because a user won't ever
        // have a balance larger than `totalSupply`
        unchecked {
            totalSupply -= amount;
        }

        _moveDelegates(delegates(from), address(0), amount);

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

    /*///////////////////////////////////////////////////////////////
                            SAFECAST LOGIC
    //////////////////////////////////////////////////////////////*/
    
    function safeCastTo32(uint256 x) internal pure virtual returns (uint32 y) {
        require(x <= type(uint32).max);

        y = uint32(x);
    }
    
    function safeCastTo96(uint256 x) internal pure virtual returns (uint96 y) {
        require(x <= type(uint96).max);

        y = uint96(x);
    }
}

File 3 of 7 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}

File 4 of 7 : IERC4626.sol
interface IERC4626 {
    function asset() external view returns (address assetTokenAddress);
    function totalAssets() external view returns (uint256 totalManagedAssets);
    function convertToShares(uint256 assets) external view returns (uint256 shares);
    function convertToAssets(uint256 shares) external view returns (uint256 assets);
    function maxDeposit(address receiver) external view returns (uint256 maxAssets);
    function previewDeposit(uint256 assets) external view returns (uint256 shares);
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);
    function maxMint(address receiver) external view returns (uint256 maxShares);
    function previewMint(uint256 shares) external view returns (uint256 assets);
    function mint(uint256 shares, address receiver) external returns (uint256 assets);
    function maxWithdraw(address owner) external view returns (uint256 maxAssets);
    function previewWithdraw(uint256 assets) external view returns (uint256 shares);
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
    function maxRedeem(address owner) external view returns (uint256 maxShares);
    function previewRedeem(uint256 shares) external view returns (uint256 assets);
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);
    event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares);
}

File 5 of 7 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

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

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

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

        require(callStatus, "ETH_TRANSFER_FAILED");
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                // Set success to whether it returned true.
                success := iszero(iszero(mload(0)))
            }
            case 0 {
                // There was no return data.
                success := 1
            }
            default {
                // It returned some malformed input.
                success := 0
            }
        }
    }
}

File 6 of 7 : FixedPointMathLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // Divide z by the denominator.
            z := div(z, denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // First, divide z - 1 by the denominator and add 1.
            // We allow z - 1 to underflow if z is 0, because we multiply the
            // end result by 0 if z is zero, ensuring we return 0 if z is zero.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        assembly {
            // Start off with z at 1.
            z := 1

            // Used below to help find a nearby power of 2.
            let y := x

            // Find the lowest power of 2 that is at least sqrt(x).
            if iszero(lt(y, 0x100000000000000000000000000000000)) {
                y := shr(128, y) // Like dividing by 2 ** 128.
                z := shl(64, z) // Like multiplying by 2 ** 64.
            }
            if iszero(lt(y, 0x10000000000000000)) {
                y := shr(64, y) // Like dividing by 2 ** 64.
                z := shl(32, z) // Like multiplying by 2 ** 32.
            }
            if iszero(lt(y, 0x100000000)) {
                y := shr(32, y) // Like dividing by 2 ** 32.
                z := shl(16, z) // Like multiplying by 2 ** 16.
            }
            if iszero(lt(y, 0x10000)) {
                y := shr(16, y) // Like dividing by 2 ** 16.
                z := shl(8, z) // Like multiplying by 2 ** 8.
            }
            if iszero(lt(y, 0x100)) {
                y := shr(8, y) // Like dividing by 2 ** 8.
                z := shl(4, z) // Like multiplying by 2 ** 4.
            }
            if iszero(lt(y, 0x10)) {
                y := shr(4, y) // Like dividing by 2 ** 4.
                z := shl(2, z) // Like multiplying by 2 ** 2.
            }
            if iszero(lt(y, 0x8)) {
                // Equivalent to 2 ** z.
                z := shl(1, z)
            }

            // Shifting right by 1 is like dividing by 2.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // Compute a rounded down version of z.
            let zRoundDown := div(x, z)

            // If zRoundDown is smaller, use it.
            if lt(zRoundDown, z) {
                z := zRoundDown
            }
        }
    }
}

File 7 of 7 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"asset_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"domainSeparator","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_asset","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkpoints","outputs":[{"internalType":"uint32","name":"fromTimestamp","type":"uint32"},{"internalType":"uint96","name":"votes","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"delegatee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint96","name":"votes","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","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":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]

60e060405260016009553480156200001657600080fd5b506040516200277f3803806200277f83398101604081905262000039916200022d565b6040805180820182526005808252643b2a2427a960d91b6020808401828152855180870190965292855284015281519192916012916200007d916000919062000187565b5081516200009390600190602085019062000187565b5060ff81166080524660a052620000a9620000d6565b60c0525050600a80546001600160a01b0319166001600160a01b0393909316929092179091555062000340565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516200010a91906200029c565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b82805462000195906200025f565b90600052602060002090601f016020900481019282620001b9576000855562000204565b82601f10620001d457805160ff191683800117855562000204565b8280016001018555821562000204579182015b8281111562000204578251825591602001919060010190620001e7565b506200021292915062000216565b5090565b5b8082111562000212576000815560010162000217565b6000602082840312156200024057600080fd5b81516001600160a01b03811681146200025857600080fd5b9392505050565b600181811c908216806200027457607f821691505b602082108114156200029657634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c915080831680620002b957607f831692505b6020808410821415620002da57634e487b7160e01b86526022600452602486fd5b818015620002f15760018114620003035762000332565b60ff1986168952848901965062000332565b60008a81526020902060005b868110156200032a5781548b8201529085019083016200030f565b505084890196505b509498975050505050505050565b60805160a05160c05161240f6200037060003960006109ae0152600061097e015260006103ca015261240f6000f3fe608060405234801561001057600080fd5b50600436106102925760003560e01c8063782d6fe111610160578063c3cda520116100d8578063d905777e1161008c578063e7a324dc11610071578063e7a324dc14610638578063ef8b30f71461065f578063fcea5e291461067257600080fd5b8063d905777e146105e4578063dd62ed3e1461060d57600080fd5b8063c6e6f592116100bd578063c6e6f592146105ab578063ce96cb77146105be578063d505accf146105d157600080fd5b8063c3cda52014610598578063c63d75b61461042b57600080fd5b8063a9059cbb1161012f578063b460af9411610114578063b460af941461055f578063b4b5ea5714610572578063ba0876521461058557600080fd5b8063a9059cbb14610539578063b3d7f6b91461054c57600080fd5b8063782d6fe1146104ce5780637ecebe00146104fe57806394bf804d1461051e57806395d89b411461053157600080fd5b8063313ce5671161020e578063587cde1e116101c25780636e553f65116101a75780636e553f651461047b5780636fcfff451461048e57806370a08231146104ae57600080fd5b8063587cde1e146104535780635c19a95c1461046657600080fd5b806338d52e0f116101f357806338d52e0f14610406578063402d267d1461042b5780634cdad5061461044057600080fd5b8063313ce567146103c55780633644e515146103fe57600080fd5b80630a28a4771161026557806318160ddd1161024a57806318160ddd1461038257806323b872dd1461038b57806330adf81f1461039e57600080fd5b80630a28a477146102fd5780630cdfebfa1461031057600080fd5b806301e1d1141461029757806306fdde03146102b257806307a2d13a146102c7578063095ea7b3146102da575b600080fd5b61029f610685565b6040519081526020015b60405180910390f35b6102ba610710565b6040516102a99190611fad565b61029f6102d5366004612020565b61079e565b6102ed6102e8366004612055565b6107cb565b60405190151581526020016102a9565b61029f61030b366004612020565b610838565b61035961031e366004612055565b600660209081526000928352604080842090915290825290205463ffffffff81169064010000000090046bffffffffffffffffffffffff1682565b6040805163ffffffff90931683526bffffffffffffffffffffffff9091166020830152016102a9565b61029f60025481565b6102ed61039936600461207f565b610858565b61029f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6103ec7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102a9565b61029f61097a565b600a546001600160a01b03165b6040516001600160a01b0390911681526020016102a9565b61029f6104393660046120bb565b5060001990565b61029f61044e366004612020565b6109d0565b6104136104613660046120bb565b6109db565b6104796104743660046120bb565b610a04565b005b61029f6104893660046120d6565b610a11565b61029f61049c3660046120bb565b60076020526000908152604090205481565b61029f6104bc3660046120bb565b60036020526000908152604090205481565b6104e16104dc366004612055565b610b3b565b6040516bffffffffffffffffffffffff90911681526020016102a9565b61029f61050c3660046120bb565b60086020526000908152604090205481565b61029f61052c3660046120d6565b610d58565b6102ba610e22565b6102ed610547366004612055565b610e2f565b61029f61055a366004612020565b610ebc565b61029f61056d366004612102565b610edb565b61029f6105803660046120bb565b611025565b61029f610593366004612102565b61109e565b6104796105a636600461214f565b611229565b61029f6105b9366004612020565b6114b3565b61029f6105cc3660046120bb565b6114d3565b6104796105df3660046121a7565b6114f5565b61029f6105f23660046120bb565b6001600160a01b031660009081526003602052604090205490565b61029f61061b366004612211565b600460209081526000928352604080842090915290825290205481565b61029f7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b61029f61066d366004612020565b6117ac565b600a54610413906001600160a01b031681565b600a546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156106e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070b919061223b565b905090565b6000805461071d90612254565b80601f016020809104026020016040519081016040528092919081815260200182805461074990612254565b80156107965780601f1061076b57610100808354040283529160200191610796565b820191906000526020600020905b81548152906001019060200180831161077957829003601f168201915b505050505081565b60025460009080156107c2576107bd6107b5610685565b8490836117b7565b6107c4565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906108269086815260200190565b60405180910390a35060015b92915050565b60025460009080156107c2576107bd81610850610685565b8591906117d6565b6001600160a01b0383166000908152600460209081526040808320338452909152812054600019146108bd576001600160a01b0384166000908152600460209081526040808320338452909152812080548492906108b79084906122d7565b90915550505b6001600160a01b038416600090815260036020526040812080548492906108e59084906122d7565b90915550506001600160a01b0383166000908152600360205260409020805483019055610923610914856109db565b61091d856109db565b84611804565b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161096891815260200190565b60405180910390a35060019392505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146109ab5761070b61198d565b507f000000000000000000000000000000000000000000000000000000000000000090565b60006108328261079e565b6001600160a01b0380821660009081526005602052604081205490911680156107c257806107c4565b610a0e3382611a58565b50565b6000600954600114610a6a5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6002600955610a78836117ac565b905080610ac75760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f5348415245530000000000000000000000000000000000000000006044820152606401610a61565b600a54610adf906001600160a01b0316333086611b08565b610ae98282611bbe565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d791015b60405180910390a3600160095592915050565b6000814211610b8c5760405162461bcd60e51b815260206004820152601260248201527f4e4f545f5945545f44455445524d494e454400000000000000000000000000006044820152606401610a61565b6001600160a01b03831660009081526007602052604090205480610bb4576000915050610832565b6001600160a01b03841660009081526006602090815260408083206000198501845290915290205463ffffffff168310610c2e576001600160a01b0384166000908152600660209081526040808320600019909401835292905220546bffffffffffffffffffffffff640100000000909104169050610832565b6001600160a01b038416600090815260066020908152604080832083805290915290205463ffffffff16831015610c69576000915050610832565b600060001982015b81811115610d14576001600160a01b038616600090815260066020908152604080832060028686030485038085529083529281902081518083019092525463ffffffff81168083526401000000009091046bffffffffffffffffffffffff169282019290925290871415610cef576020015194506108329350505050565b805163ffffffff16871115610d0657819350610d0d565b6001820392505b5050610c71565b506001600160a01b038516600090815260066020908152604080832093835292905220546bffffffffffffffffffffffff6401000000009091041691505092915050565b6000600954600114610dac5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a61565b6002600955610dba83610ebc565b600a54909150610dd5906001600160a01b0316333084611b08565b610ddf8284611bbe565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d79101610b28565b6001805461071d90612254565b33600090815260036020526040812080548391908390610e509084906122d7565b90915550506001600160a01b0383166000908152600360205260409020805483019055610e7f610914336109db565b6040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610826565b60025460009080156107c2576107bd610ed3610685565b8490836117d6565b6000600954600114610f2f5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a61565b6002600955610f3d84610838565b9050336001600160a01b03831614610fad576001600160a01b03821660009081526004602090815260408083203384529091529020546000198114610fab57610f8682826122d7565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b610fb78282611c4c565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4600a54611019906001600160a01b03168486611cd4565b60016009559392505050565b6001600160a01b0381166000908152600760205260408120548061104a576000611089565b6001600160a01b03831660009081526006602090815260408083206000198501845290915290205464010000000090046bffffffffffffffffffffffff165b6bffffffffffffffffffffffff169392505050565b60006009546001146110f25760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a61565b6002600955336001600160a01b03831614611165576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146111635761113e85826122d7565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61116e846109d0565b9050806111bd5760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f4153534554530000000000000000000000000000000000000000006044820152606401610a61565b6111c78285611c4c565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4600a54611019906001600160a01b03168483611cd4565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009060a001604051602081830303815290604052805190602001209050600061129a61097a565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa15801561135e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150506001600160a01b0381166113df5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610a61565b6001600160a01b0381166000908152600860205260409020805460018101909155881461144e5760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49445f4e4f4e4345000000000000000000000000000000000000006044820152606401610a61565b8642111561149e5760405162461bcd60e51b815260206004820152601160248201527f5349474e41545552455f455850495245440000000000000000000000000000006044820152606401610a61565b6114a8818a611a58565b505050505050505050565b60025460009080156107c2576107bd816114cb610685565b8591906117b7565b6001600160a01b0381166000908152600360205260408120546108329061079e565b834211156115455760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610a61565b600061154f61097a565b6001600160a01b0389811660008181526008602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156116a1573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150506001600160a01b038116158015906116f55750886001600160a01b0316816001600160a01b0316145b6117415760405162461bcd60e51b815260206004820152601860248201527f494e56414c49445f5045524d49545f5349474e415455524500000000000000006044820152606401610a61565b6001600160a01b0390811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000610832826114b3565b8282028115158415858304851417166117cf57600080fd5b0492915050565b8282028115158415858304851417166117ee57600080fd5b6001826001830304018115150290509392505050565b816001600160a01b0316836001600160a01b03161415801561182557508015155b156118d9576001600160a01b038316156118d9576001600160a01b038316600090815260076020526040812054908161185f5760006118ab565b6001600160a01b0385166000908152600660205260408120906118836001856122d7565b815260208101919091526040016000205464010000000090046bffffffffffffffffffffffff165b6bffffffffffffffffffffffff16905060006118c784836122d7565b90506118d586848484611d7a565b5050505b6001600160a01b03821615611988576001600160a01b038216600090815260076020526040812054908161190e57600061195a565b6001600160a01b0384166000908152600660205260408120906119326001856122d7565b815260208101919091526040016000205464010000000090046bffffffffffffffffffffffff165b6bffffffffffffffffffffffff169050600061197684836122ee565b905061198485848484611d7a565b5050505b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516119bf9190612306565b604080519182900382208282018252600183527f31000000000000000000000000000000000000000000000000000000000000006020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b03808316600090815260056020908152604080832080548686167fffffffffffffffffffffffff0000000000000000000000000000000000000000821617909155600390925290912054911690611ab99082908490611804565b816001600160a01b0316816001600160a01b0316846001600160a01b03167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a4505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af1915050611b6b81611f34565b611bb75760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152606401610a61565b5050505050565b8060026000828254611bd091906122ee565b90915550506001600160a01b0382166000908152600360205260408120805483019055611c0690611c00846109db565b83611804565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6001600160a01b03821660009081526003602052604081208054839290611c749084906122d7565b9091555050600280548290039055611c96611c8e836109db565b600083611804565b6040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611c40565b60006040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201528260248201526000806044836000895af1915050611d2881611f34565b611d745760405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610a61565b50505050565b8215801590611db557506001600160a01b03841660009081526006602090815260408083206000198701845290915290205463ffffffff1642145b15611e3357611dc381611f7b565b6001600160a01b038516600090815260066020908152604080832060001988018452909152902080546bffffffffffffffffffffffff92909216640100000000027fffffffffffffffffffffffffffffffff000000000000000000000000ffffffff909216919091179055611eea565b6040518060400160405280611e4742611f9a565b63ffffffff168152602001611e5b83611f7b565b6bffffffffffffffffffffffff9081169091526001600160a01b038616600081815260066020908152604080832089845282528083208651815497840151909616640100000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000090971663ffffffff90961695909517959095179093559081526007909152206001840190555b60408051838152602081018390526001600160a01b038616917fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724910160405180910390a250505050565b60003d82611f4657806000803e806000fd5b8060208114611f5e578015611f6f5760009250611f74565b816000803e60005115159250611f74565b600192505b5050919050565b60006bffffffffffffffffffffffff821115611f9657600080fd5b5090565b600063ffffffff821115611f9657600080fd5b600060208083528351808285015260005b81811015611fda57858101830151858201604001528201611fbe565b81811115611fec576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561203257600080fd5b5035919050565b80356001600160a01b038116811461205057600080fd5b919050565b6000806040838503121561206857600080fd5b61207183612039565b946020939093013593505050565b60008060006060848603121561209457600080fd5b61209d84612039565b92506120ab60208501612039565b9150604084013590509250925092565b6000602082840312156120cd57600080fd5b6107c482612039565b600080604083850312156120e957600080fd5b823591506120f960208401612039565b90509250929050565b60008060006060848603121561211757600080fd5b8335925061212760208501612039565b915061213560408501612039565b90509250925092565b803560ff8116811461205057600080fd5b60008060008060008060c0878903121561216857600080fd5b61217187612039565b9550602087013594506040870135935061218d6060880161213e565b92506080870135915060a087013590509295509295509295565b600080600080600080600060e0888a0312156121c257600080fd5b6121cb88612039565b96506121d960208901612039565b955060408801359450606088013593506121f56080890161213e565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561222457600080fd5b61222d83612039565b91506120f960208401612039565b60006020828403121561224d57600080fd5b5051919050565b600181811c9082168061226857607f821691505b602082108114156122a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156122e9576122e96122a8565b500390565b60008219821115612301576123016122a8565b500190565b600080835481600182811c91508083168061232257607f831692505b602080841082141561235b577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b81801561236f576001811461239e576123cb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616895284890196506123cb565b60008a81526020902060005b868110156123c35781548b8201529085019083016123aa565b505084890196505b50949897505050505050505056fea2646970667358221220dce9b3b62177ed9b77d6bff0b72a63b5aa14cac41b0c62b023093a2bcae418ec64736f6c634300080a0033000000000000000000000000a5f2211b9b8170f694421f2046281775e8468044

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102925760003560e01c8063782d6fe111610160578063c3cda520116100d8578063d905777e1161008c578063e7a324dc11610071578063e7a324dc14610638578063ef8b30f71461065f578063fcea5e291461067257600080fd5b8063d905777e146105e4578063dd62ed3e1461060d57600080fd5b8063c6e6f592116100bd578063c6e6f592146105ab578063ce96cb77146105be578063d505accf146105d157600080fd5b8063c3cda52014610598578063c63d75b61461042b57600080fd5b8063a9059cbb1161012f578063b460af9411610114578063b460af941461055f578063b4b5ea5714610572578063ba0876521461058557600080fd5b8063a9059cbb14610539578063b3d7f6b91461054c57600080fd5b8063782d6fe1146104ce5780637ecebe00146104fe57806394bf804d1461051e57806395d89b411461053157600080fd5b8063313ce5671161020e578063587cde1e116101c25780636e553f65116101a75780636e553f651461047b5780636fcfff451461048e57806370a08231146104ae57600080fd5b8063587cde1e146104535780635c19a95c1461046657600080fd5b806338d52e0f116101f357806338d52e0f14610406578063402d267d1461042b5780634cdad5061461044057600080fd5b8063313ce567146103c55780633644e515146103fe57600080fd5b80630a28a4771161026557806318160ddd1161024a57806318160ddd1461038257806323b872dd1461038b57806330adf81f1461039e57600080fd5b80630a28a477146102fd5780630cdfebfa1461031057600080fd5b806301e1d1141461029757806306fdde03146102b257806307a2d13a146102c7578063095ea7b3146102da575b600080fd5b61029f610685565b6040519081526020015b60405180910390f35b6102ba610710565b6040516102a99190611fad565b61029f6102d5366004612020565b61079e565b6102ed6102e8366004612055565b6107cb565b60405190151581526020016102a9565b61029f61030b366004612020565b610838565b61035961031e366004612055565b600660209081526000928352604080842090915290825290205463ffffffff81169064010000000090046bffffffffffffffffffffffff1682565b6040805163ffffffff90931683526bffffffffffffffffffffffff9091166020830152016102a9565b61029f60025481565b6102ed61039936600461207f565b610858565b61029f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6103ec7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016102a9565b61029f61097a565b600a546001600160a01b03165b6040516001600160a01b0390911681526020016102a9565b61029f6104393660046120bb565b5060001990565b61029f61044e366004612020565b6109d0565b6104136104613660046120bb565b6109db565b6104796104743660046120bb565b610a04565b005b61029f6104893660046120d6565b610a11565b61029f61049c3660046120bb565b60076020526000908152604090205481565b61029f6104bc3660046120bb565b60036020526000908152604090205481565b6104e16104dc366004612055565b610b3b565b6040516bffffffffffffffffffffffff90911681526020016102a9565b61029f61050c3660046120bb565b60086020526000908152604090205481565b61029f61052c3660046120d6565b610d58565b6102ba610e22565b6102ed610547366004612055565b610e2f565b61029f61055a366004612020565b610ebc565b61029f61056d366004612102565b610edb565b61029f6105803660046120bb565b611025565b61029f610593366004612102565b61109e565b6104796105a636600461214f565b611229565b61029f6105b9366004612020565b6114b3565b61029f6105cc3660046120bb565b6114d3565b6104796105df3660046121a7565b6114f5565b61029f6105f23660046120bb565b6001600160a01b031660009081526003602052604090205490565b61029f61061b366004612211565b600460209081526000928352604080842090915290825290205481565b61029f7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b61029f61066d366004612020565b6117ac565b600a54610413906001600160a01b031681565b600a546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156106e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070b919061223b565b905090565b6000805461071d90612254565b80601f016020809104026020016040519081016040528092919081815260200182805461074990612254565b80156107965780601f1061076b57610100808354040283529160200191610796565b820191906000526020600020905b81548152906001019060200180831161077957829003601f168201915b505050505081565b60025460009080156107c2576107bd6107b5610685565b8490836117b7565b6107c4565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906108269086815260200190565b60405180910390a35060015b92915050565b60025460009080156107c2576107bd81610850610685565b8591906117d6565b6001600160a01b0383166000908152600460209081526040808320338452909152812054600019146108bd576001600160a01b0384166000908152600460209081526040808320338452909152812080548492906108b79084906122d7565b90915550505b6001600160a01b038416600090815260036020526040812080548492906108e59084906122d7565b90915550506001600160a01b0383166000908152600360205260409020805483019055610923610914856109db565b61091d856109db565b84611804565b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161096891815260200190565b60405180910390a35060019392505050565b60007f000000000000000000000000000000000000000000000000000000000000000146146109ab5761070b61198d565b507f3f7a01af5ff3624642de4b101c245afcd4ecdf1c85f8176be167e8bf7232b9ae90565b60006108328261079e565b6001600160a01b0380821660009081526005602052604081205490911680156107c257806107c4565b610a0e3382611a58565b50565b6000600954600114610a6a5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6002600955610a78836117ac565b905080610ac75760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f5348415245530000000000000000000000000000000000000000006044820152606401610a61565b600a54610adf906001600160a01b0316333086611b08565b610ae98282611bbe565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d791015b60405180910390a3600160095592915050565b6000814211610b8c5760405162461bcd60e51b815260206004820152601260248201527f4e4f545f5945545f44455445524d494e454400000000000000000000000000006044820152606401610a61565b6001600160a01b03831660009081526007602052604090205480610bb4576000915050610832565b6001600160a01b03841660009081526006602090815260408083206000198501845290915290205463ffffffff168310610c2e576001600160a01b0384166000908152600660209081526040808320600019909401835292905220546bffffffffffffffffffffffff640100000000909104169050610832565b6001600160a01b038416600090815260066020908152604080832083805290915290205463ffffffff16831015610c69576000915050610832565b600060001982015b81811115610d14576001600160a01b038616600090815260066020908152604080832060028686030485038085529083529281902081518083019092525463ffffffff81168083526401000000009091046bffffffffffffffffffffffff169282019290925290871415610cef576020015194506108329350505050565b805163ffffffff16871115610d0657819350610d0d565b6001820392505b5050610c71565b506001600160a01b038516600090815260066020908152604080832093835292905220546bffffffffffffffffffffffff6401000000009091041691505092915050565b6000600954600114610dac5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a61565b6002600955610dba83610ebc565b600a54909150610dd5906001600160a01b0316333084611b08565b610ddf8284611bbe565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d79101610b28565b6001805461071d90612254565b33600090815260036020526040812080548391908390610e509084906122d7565b90915550506001600160a01b0383166000908152600360205260409020805483019055610e7f610914336109db565b6040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610826565b60025460009080156107c2576107bd610ed3610685565b8490836117d6565b6000600954600114610f2f5760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a61565b6002600955610f3d84610838565b9050336001600160a01b03831614610fad576001600160a01b03821660009081526004602090815260408083203384529091529020546000198114610fab57610f8682826122d7565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b610fb78282611c4c565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4600a54611019906001600160a01b03168486611cd4565b60016009559392505050565b6001600160a01b0381166000908152600760205260408120548061104a576000611089565b6001600160a01b03831660009081526006602090815260408083206000198501845290915290205464010000000090046bffffffffffffffffffffffff165b6bffffffffffffffffffffffff169392505050565b60006009546001146110f25760405162461bcd60e51b815260206004820152600a60248201527f5245454e5452414e4359000000000000000000000000000000000000000000006044820152606401610a61565b6002600955336001600160a01b03831614611165576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146111635761113e85826122d7565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b61116e846109d0565b9050806111bd5760405162461bcd60e51b815260206004820152600b60248201527f5a45524f5f4153534554530000000000000000000000000000000000000000006044820152606401610a61565b6111c78285611c4c565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4600a54611019906001600160a01b03168483611cd4565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009060a001604051602081830303815290604052805190602001209050600061129a61097a565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa15801561135e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150506001600160a01b0381166113df5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610a61565b6001600160a01b0381166000908152600860205260409020805460018101909155881461144e5760405162461bcd60e51b815260206004820152600d60248201527f494e56414c49445f4e4f4e4345000000000000000000000000000000000000006044820152606401610a61565b8642111561149e5760405162461bcd60e51b815260206004820152601160248201527f5349474e41545552455f455850495245440000000000000000000000000000006044820152606401610a61565b6114a8818a611a58565b505050505050505050565b60025460009080156107c2576107bd816114cb610685565b8591906117b7565b6001600160a01b0381166000908152600360205260408120546108329061079e565b834211156115455760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610a61565b600061154f61097a565b6001600160a01b0389811660008181526008602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa1580156116a1573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150506001600160a01b038116158015906116f55750886001600160a01b0316816001600160a01b0316145b6117415760405162461bcd60e51b815260206004820152601860248201527f494e56414c49445f5045524d49545f5349474e415455524500000000000000006044820152606401610a61565b6001600160a01b0390811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000610832826114b3565b8282028115158415858304851417166117cf57600080fd5b0492915050565b8282028115158415858304851417166117ee57600080fd5b6001826001830304018115150290509392505050565b816001600160a01b0316836001600160a01b03161415801561182557508015155b156118d9576001600160a01b038316156118d9576001600160a01b038316600090815260076020526040812054908161185f5760006118ab565b6001600160a01b0385166000908152600660205260408120906118836001856122d7565b815260208101919091526040016000205464010000000090046bffffffffffffffffffffffff165b6bffffffffffffffffffffffff16905060006118c784836122d7565b90506118d586848484611d7a565b5050505b6001600160a01b03821615611988576001600160a01b038216600090815260076020526040812054908161190e57600061195a565b6001600160a01b0384166000908152600660205260408120906119326001856122d7565b815260208101919091526040016000205464010000000090046bffffffffffffffffffffffff165b6bffffffffffffffffffffffff169050600061197684836122ee565b905061198485848484611d7a565b5050505b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516119bf9190612306565b604080519182900382208282018252600183527f31000000000000000000000000000000000000000000000000000000000000006020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b03808316600090815260056020908152604080832080548686167fffffffffffffffffffffffff0000000000000000000000000000000000000000821617909155600390925290912054911690611ab99082908490611804565b816001600160a01b0316816001600160a01b0316846001600160a01b03167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a4505050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af1915050611b6b81611f34565b611bb75760405162461bcd60e51b815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152606401610a61565b5050505050565b8060026000828254611bd091906122ee565b90915550506001600160a01b0382166000908152600360205260408120805483019055611c0690611c00846109db565b83611804565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6001600160a01b03821660009081526003602052604081208054839290611c749084906122d7565b9091555050600280548290039055611c96611c8e836109db565b600083611804565b6040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611c40565b60006040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201528260248201526000806044836000895af1915050611d2881611f34565b611d745760405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152606401610a61565b50505050565b8215801590611db557506001600160a01b03841660009081526006602090815260408083206000198701845290915290205463ffffffff1642145b15611e3357611dc381611f7b565b6001600160a01b038516600090815260066020908152604080832060001988018452909152902080546bffffffffffffffffffffffff92909216640100000000027fffffffffffffffffffffffffffffffff000000000000000000000000ffffffff909216919091179055611eea565b6040518060400160405280611e4742611f9a565b63ffffffff168152602001611e5b83611f7b565b6bffffffffffffffffffffffff9081169091526001600160a01b038616600081815260066020908152604080832089845282528083208651815497840151909616640100000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000090971663ffffffff90961695909517959095179093559081526007909152206001840190555b60408051838152602081018390526001600160a01b038616917fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724910160405180910390a250505050565b60003d82611f4657806000803e806000fd5b8060208114611f5e578015611f6f5760009250611f74565b816000803e60005115159250611f74565b600192505b5050919050565b60006bffffffffffffffffffffffff821115611f9657600080fd5b5090565b600063ffffffff821115611f9657600080fd5b600060208083528351808285015260005b81811015611fda57858101830151858201604001528201611fbe565b81811115611fec576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60006020828403121561203257600080fd5b5035919050565b80356001600160a01b038116811461205057600080fd5b919050565b6000806040838503121561206857600080fd5b61207183612039565b946020939093013593505050565b60008060006060848603121561209457600080fd5b61209d84612039565b92506120ab60208501612039565b9150604084013590509250925092565b6000602082840312156120cd57600080fd5b6107c482612039565b600080604083850312156120e957600080fd5b823591506120f960208401612039565b90509250929050565b60008060006060848603121561211757600080fd5b8335925061212760208501612039565b915061213560408501612039565b90509250925092565b803560ff8116811461205057600080fd5b60008060008060008060c0878903121561216857600080fd5b61217187612039565b9550602087013594506040870135935061218d6060880161213e565b92506080870135915060a087013590509295509295509295565b600080600080600080600060e0888a0312156121c257600080fd5b6121cb88612039565b96506121d960208901612039565b955060408801359450606088013593506121f56080890161213e565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561222457600080fd5b61222d83612039565b91506120f960208401612039565b60006020828403121561224d57600080fd5b5051919050565b600181811c9082168061226857607f821691505b602082108114156122a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156122e9576122e96122a8565b500390565b60008219821115612301576123016122a8565b500190565b600080835481600182811c91508083168061232257607f831692505b602080841082141561235b577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b81801561236f576001811461239e576123cb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616895284890196506123cb565b60008a81526020902060005b868110156123c35781548b8201529085019083016123aa565b505084890196505b50949897505050505050505056fea2646970667358221220dce9b3b62177ed9b77d6bff0b72a63b5aa14cac41b0c62b023093a2bcae418ec64736f6c634300080a0033

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

000000000000000000000000a5f2211b9b8170f694421f2046281775e8468044

-----Decoded View---------------
Arg [0] : asset_ (address): 0xa5f2211B9b8170F694421f2046281775E8468044

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


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.