ETH Price: $3,284.75 (+0.44%)

Contract

0x815C23eCA83261b6Ec689b60Cc4a58b54BC24D8D
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer216097342025-01-12 16:53:5945 mins ago1736700839IN
0x815C23eC...54BC24D8D
0 ETH0.000445243.41635651
Redeem216091302025-01-12 14:52:472 hrs ago1736693567IN
0x815C23eC...54BC24D8D
0 ETH0.000506684.58758153
Redeem216084982025-01-12 12:45:474 hrs ago1736685947IN
0x815C23eC...54BC24D8D
0 ETH0.000275482.49427651
Deposit216036962025-01-11 20:42:2320 hrs ago1736628143IN
0x815C23eC...54BC24D8D
0 ETH0.000491653.74170717
Deposit215980522025-01-11 1:46:5939 hrs ago1736560019IN
0x815C23eC...54BC24D8D
0 ETH0.000465783.98447772
Approve215980232025-01-11 1:41:1139 hrs ago1736559671IN
0x815C23eC...54BC24D8D
0 ETH0.000192734.16553234
Redeem215975792025-01-11 0:11:4741 hrs ago1736554307IN
0x815C23eC...54BC24D8D
0 ETH0.000352443.59140631
Redeem215971212025-01-10 22:39:4742 hrs ago1736548787IN
0x815C23eC...54BC24D8D
0 ETH0.000428124.36315964
Approve215966742025-01-10 21:09:5944 hrs ago1736543399IN
0x815C23eC...54BC24D8D
0 ETH0.000208674.50895717
Redeem215961012025-01-10 19:15:2346 hrs ago1736536523IN
0x815C23eC...54BC24D8D
0 ETH0.000873647.58140056
Deposit215955102025-01-10 17:16:352 days ago1736529395IN
0x815C23eC...54BC24D8D
0 ETH0.00089776.59172629
Deposit215946112025-01-10 14:15:592 days ago1736518559IN
0x815C23eC...54BC24D8D
0 ETH0.0011250311.27004351
Deposit215941492025-01-10 12:43:232 days ago1736513003IN
0x815C23eC...54BC24D8D
0 ETH0.000477524.56471039
Deposit215941332025-01-10 12:40:112 days ago1736512811IN
0x815C23eC...54BC24D8D
0 ETH0.000560915.61902983
Deposit215941182025-01-10 12:36:592 days ago1736512619IN
0x815C23eC...54BC24D8D
0 ETH0.000423454.24195348
Deposit215941062025-01-10 12:34:352 days ago1736512475IN
0x815C23eC...54BC24D8D
0 ETH0.000474554.75386969
Redeem215937942025-01-10 11:31:472 days ago1736508707IN
0x815C23eC...54BC24D8D
0 ETH0.00053744.86520691
Redeem215937612025-01-10 11:25:112 days ago1736508311IN
0x815C23eC...54BC24D8D
0 ETH0.000567635.13884538
Approve215934772025-01-10 10:27:592 days ago1736504879IN
0x815C23eC...54BC24D8D
0 ETH0.000294526.32607832
Approve215933852025-01-10 10:09:232 days ago1736503763IN
0x815C23eC...54BC24D8D
0 ETH0.000276965.98434183
Transfer215931062025-01-10 9:13:232 days ago1736500403IN
0x815C23eC...54BC24D8D
0 ETH0.000614425.30401199
Approve215924672025-01-10 7:04:352 days ago1736492675IN
0x815C23eC...54BC24D8D
0 ETH0.000167133.6113118
Redeem215923182025-01-10 6:34:232 days ago1736490863IN
0x815C23eC...54BC24D8D
0 ETH0.000407833.69219367
Approve215923002025-01-10 6:30:472 days ago1736490647IN
0x815C23eC...54BC24D8D
0 ETH0.000141793.06452438
Approve215922452025-01-10 6:19:472 days ago1736489987IN
0x815C23eC...54BC24D8D
0 ETH0.000144513.12245828
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

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


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.