ETH Price: $1,961.70 (+1.66%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw233459132025-09-12 8:53:47169 days ago1757667227IN
0x577c8444...7d4451d45
0 ETH0.000133641.19043564
Confirm Mileston...233458992025-09-12 8:50:59169 days ago1757667059IN
0x577c8444...7d4451d45
0 ETH0.000075411.19865802
Confirm Mileston...233458982025-09-12 8:50:47169 days ago1757667047IN
0x577c8444...7d4451d45
0 ETH0.000075681.20289104
Confirm Mileston...233458972025-09-12 8:50:35169 days ago1757667035IN
0x577c8444...7d4451d45
0 ETH0.000075491.19986226
Confirm Mileston...233458962025-09-12 8:50:23169 days ago1757667023IN
0x577c8444...7d4451d45
0 ETH0.00007621.21120307
Confirm Mileston...233458952025-09-12 8:50:11169 days ago1757667011IN
0x577c8444...7d4451d45
0 ETH0.000075961.20740054
Confirm Mileston...233458942025-09-12 8:49:59169 days ago1757666999IN
0x577c8444...7d4451d45
0 ETH0.000076121.20990919
Confirm Mileston...233458922025-09-12 8:49:35169 days ago1757666975IN
0x577c8444...7d4451d45
0 ETH0.00007641.21441888
Confirm Mileston...217907362025-02-06 23:25:47387 days ago1738884347IN
0x577c8444...7d4451d45
0 ETH0.000170391.45631826

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Method Block
From
To
0x60a06040217867382025-02-06 10:02:59387 days ago1738836179  Contract Creation0 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

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

Contract Name:
VestingAllocation

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: AGPL-3.0-only
import "./BaseAllocation.sol";

pragma solidity 0.8.20;

contract VestingAllocation is BaseAllocation {

    /// @notice constructor for VestingAllocation
    /// @param _grantee address of the grantee
    /// @param _controller address of the controller
    /// @param _allocation Allocation struct containing token contract
    /// @param _milestones array of Milestone structs with conditions and awards
    constructor (
        address _grantee,
        address _controller,
        Allocation memory _allocation,
        Milestone[] memory _milestones
    ) BaseAllocation(
         _grantee,
         _controller
    ) {
        //perform input validation
        if (_allocation.tokenContract == address(0)) revert MetaVesT_ZeroAddress();
        //if (_allocation.tokenStreamTotal == 0) revert MetaVesT_ZeroAmount();
        if (_grantee == address(0)) revert MetaVesT_ZeroAddress();
        if (_allocation.vestingRate >  1000*1e18 || _allocation.unlockRate > 1000*1e18) revert MetaVesT_RateTooHigh();

        //set vesting allocation variables
        allocation.tokenContract = _allocation.tokenContract;
        allocation.tokenStreamTotal = _allocation.tokenStreamTotal;
        allocation.vestingCliffCredit = _allocation.vestingCliffCredit;
        allocation.unlockingCliffCredit = _allocation.unlockingCliffCredit;
        allocation.vestingRate = _allocation.vestingRate;
        allocation.vestingStartTime = _allocation.vestingStartTime;
        allocation.unlockRate = _allocation.unlockRate;
        allocation.unlockStartTime = _allocation.unlockStartTime;
        // manually copy milestones
        for (uint256 i; i < _milestones.length; ++i) {
            milestones.push(_milestones[i]);
        }
    }

    /// @notice returns the contract vesting type 1 for VestingAllocation
    /// @return 1 for VestingAllocation
    function getVestingType() external pure override returns (uint256) {
        return 1;
    }

    /// @notice returns the governing power of the VestingAllocation
    /// @return governingPower - the governing power of the VestingAllocation based on the governance setting
    function getGoverningPower() external view override returns (uint256 governingPower) {
        if(govType==GovType.all)
        {
            uint256 totalMilestoneAward = 0;
            for(uint256 i; i < milestones.length; ++i)
            { 
                    totalMilestoneAward += milestones[i].milestoneAward;
            }
            governingPower = (allocation.tokenStreamTotal + totalMilestoneAward) - tokensWithdrawn;
        }
        else if(govType==GovType.vested)
             governingPower = getVestedTokenAmount() - tokensWithdrawn;
        else 
            governingPower = _min(getVestedTokenAmount(), getUnlockedTokenAmount()) - tokensWithdrawn;
        
        return governingPower;
    }

    /// @notice unused for VestingAllocation
    /// @dev onlyController -- must be called from the metavest controller
    /// @param _shortStopTime - the new short stop time
    function updateStopTimes(uint48 _shortStopTime) external override onlyController {
        if(terminated) revert MetaVesT_AlreadyTerminated();
        revert MetaVesT_ConditionNotSatisfied();
    }

    /// @notice terminates the VestingAllocation and transfers any remaining tokens to the authority
    /// @dev onlyController -- must be called from the metavest controller
    function terminate() external override onlyController nonReentrant {
        if(terminated) revert MetaVesT_AlreadyTerminated();
        uint256 tokensToRecover = 0;
        uint256 milestonesAllocation = 0;
        for (uint256 i; i < milestones.length; ++i) {
                milestonesAllocation += milestones[i].milestoneAward;
        }
        tokensToRecover = allocation.tokenStreamTotal + milestonesAllocation - getVestedTokenAmount();
        if(tokensToRecover>IERC20M(allocation.tokenContract).balanceOf(address(this)))
            tokensToRecover = IERC20M(allocation.tokenContract).balanceOf(address(this));
        terminationTime = block.timestamp;
        safeTransfer(allocation.tokenContract, getAuthority(), tokensToRecover);
        terminated = true;
        emit MetaVesT_Terminated(grantee, tokensToRecover);
    }

    /// @notice returns the amount of tokens that are vested
    /// @return _tokensVested - the amount of tokens that are vested in decimals of the vesting token
    function getVestedTokenAmount() public view returns (uint256) {
        if(block.timestamp<allocation.vestingStartTime)
            return 0;
        uint256 _timeElapsedSinceVest = block.timestamp - allocation.vestingStartTime;
        if(terminated)
            _timeElapsedSinceVest = terminationTime - allocation.vestingStartTime;

           uint256 _tokensVested = (_timeElapsedSinceVest * allocation.vestingRate) + allocation.vestingCliffCredit;

            if(_tokensVested>allocation.tokenStreamTotal) 
                _tokensVested = allocation.tokenStreamTotal;
        return _tokensVested += milestoneAwardTotal;
    }

    /// @notice returns the amount of tokens that are unlocked
    /// @return _tokensUnlocked - the amount of tokens that are unlocked in decimals of the vesting token
    function getUnlockedTokenAmount() public view returns (uint256) {
        if(block.timestamp<allocation.unlockStartTime)
            return 0;
        uint256 _timeElapsedSinceUnlock = block.timestamp - allocation.unlockStartTime;
        uint256 _tokensUnlocked = (_timeElapsedSinceUnlock * allocation.unlockRate) + allocation.unlockingCliffCredit;

        if(_tokensUnlocked>allocation.tokenStreamTotal + milestoneAwardTotal) 
            _tokensUnlocked = allocation.tokenStreamTotal + milestoneAwardTotal;

        return _tokensUnlocked += milestoneUnlockedTotal;
    }

    /// @notice returns the amount of tokens that are withdrawable
    /// @return _tokensWithdrawable - the amount of tokens that are withdrawable in decimals of the vesting token
    function getAmountWithdrawable() public view override returns (uint256) {
        uint256 _tokensVested = getVestedTokenAmount();
        uint256 _tokensUnlocked = getUnlockedTokenAmount();
        uint256 withdrawableAmount = _min(_tokensVested, _tokensUnlocked);
        if(withdrawableAmount>tokensWithdrawn)
            return withdrawableAmount - tokensWithdrawn;
        else
            return 0;
        
    }

}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.20;

/// @notice interface to a MetaLeX condition contract
/// @dev see https://github.com/MetaLex-Tech/BORG-CORE/tree/main/src/libs/conditions
interface IConditionM {
    function checkCondition(address _contract, bytes4 _functionSignature, bytes memory data) external view returns (bool);
}

interface IERC20M {
    function allowance(address owner, address spender) external view returns (uint256);
    function decimals() external view returns (uint8);
    function balanceOf(address account) external view returns (uint256);
}

interface IController { 
    function authority() external view returns (address);
}

/// @notice Solady's SafeTransferLib 'SafeTransfer()' and 'SafeTransferFrom()'; (https://github.com/Vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
abstract contract SafeTransferLib {
    error TransferFailed();
    error TransferFromFailed();

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`. Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and(
                    // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. Reverts upon failure.
    /// The `from` account must have at least `amount` approved for the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and(
                    // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }
}

/// @notice gas-optimized reentrancy protection by Solady (https://github.com/Vectorized/solady/blob/main/src/utils/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    /// @dev Equivalent to: `uint72(bytes9(keccak256("_REENTRANCY_GUARD_SLOT")))`. 9 bytes is large enough to avoid collisions with lower slots,
    /// but not too large to result in excessive bytecode bloat.
    uint256 private constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268;
    error Reentrancy();

    /// @dev Guards a function from reentrancy.
    modifier nonReentrant() virtual {
        assembly {
            if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
                mstore(0x00, 0xab143c06) // `Reentrancy()`.
                revert(0x1c, 0x04)
            }
            sstore(_REENTRANCY_GUARD_SLOT, address())
        }
        _;
        assembly {
            sstore(_REENTRANCY_GUARD_SLOT, codesize())
        }
    }
}


abstract contract BaseAllocation is ReentrancyGuard, SafeTransferLib{

        /// @notice MetaVesTController contract address, immutably tied to this MetaVesT
        address public immutable controller;
        uint256 constant public MAX_MILESTONES = 20;
        /// @notice authority address, may replace itself in 'controller'
        address public authority; // REVIEW: probably just have `getAuthority` which calls thru to `controller`? Saves having to worry about updating if it changes?
        struct Milestone {
            uint256 milestoneAward; // per-milestone indexed lump sums of tokens vested upon corresponding milestone completion
            bool unlockOnCompletion; // whether the 'milestoneAward' is to be unlocked upon completion
            bool complete; // whether the Milestone is satisfied and the 'milestoneAward' is to be released
            address[] conditionContracts; // array of contract addresses corresponding to condition(s) that must satisfied for this Milestone to be 'complete'
        }
        error MetaVesT_OnlyController();
        error MetaVesT_OnlyGrantee();
        error MetaVesT_OnlyAuthority();
        error MetaVesT_ZeroAddress();
        error MetaVesT_RateTooHigh();
        error MetaVesT_ZeroAmount();
        error MetaVesT_MilestoneIndexOutOfRange();
        error MetaVesT_NotTerminated();
        error MetaVesT_MilestoneIndexCompletedOrDoesNotExist();
        error MetaVesT_ConditionNotSatisfied();
        error MetaVesT_AlreadyTerminated();
        error MetaVesT_MoreThanAvailable();
        error MetaVesT_VestNotTransferable();
        error MetaVesT_ShortStopTimeNotReached();
        error MetaVest_ShortStopDatePassed();
        error MetaVesT_MaxMilestonesReached();
        error MetaVesT_TooSmallAmount();

        event MetaVesT_MilestoneCompleted(address indexed grantee, uint256 indexed milestoneIndex);
        event MetaVesT_MilestoneAdded(address indexed grantee, Milestone milestone);
        event MetaVesT_MilestoneRemoved(address indexed grantee, uint256 indexed milestoneIndex);
        event MetaVesT_StopTimesUpdated(
            address indexed grant,
            uint48 shortStopTime
        );
        event MetaVesT_TransferabilityUpdated(address indexed grantee, bool isTransferable);
        event MetaVest_TransferRightsPending(address indexed grantee, address indexed pendingGrantee);
        event MetaVesT_TransferredRights(address indexed grantee, address transferee);
        event MetaVesT_UnlockRateUpdated(address indexed grantee, uint208 unlockRate);
        event MetaVesT_VestingRateUpdated(address indexed grantee, uint208 vestingRate);
        event MetaVesT_Withdrawn(address indexed grantee, address indexed tokenAddress, uint256 amount);
        event MetaVesT_PriceUpdated(address indexed grantee, uint256 exercisePrice);
        event MetaVesT_RepurchaseAndWithdrawal(address indexed grantee, address indexed tokenAddress, uint256 withdrawalAmount, uint256 repurchaseAmount);
        event MetaVesT_Terminated(address indexed grantee, uint256 tokensRecovered);
        event MetaVest_GovVariablesUpdated(GovType _govType);

        struct Allocation {
            uint256 tokenStreamTotal; // total number of tokens subject to linear vesting/restriction removal (includes cliff credits but not each 'milestoneAward')
            uint128 vestingCliffCredit; // lump sum of tokens which become vested at 'startTime' and will be added to '_linearVested'
            uint128 unlockingCliffCredit; // lump sum of tokens which become unlocked at 'startTime' and will be added to '_linearUnlocked'
            uint160 vestingRate; // tokens per second that become vested; if RESTRICTED this amount corresponds to 'lapse rate' for tokens that become non-repurchasable
            uint48 vestingStartTime; // if RESTRICTED this amount corresponds to 'lapse start time'
            uint160 unlockRate; // tokens per second that become unlocked;
            uint48 unlockStartTime; // start of the linear unlock
            address tokenContract; // contract address of the ERC20 token included in the MetaVesT
        }

        // enum to determine which tokens in the vesting contract will be counted towards governing power
        enum GovType {all, vested, unlocked}

        address public grantee; // grantee of the tokens
        address public pendingGrantee; // address of the pending grantee
        bool transferable; // whether grantee can transfer their MetaVesT in whole
        Milestone[] public milestones; // array of Milestone structs
        Allocation public allocation; // struct containing vesting and unlocking details
        uint256 public milestoneAwardTotal; // total number of tokens awarded in milestones
        uint256 public milestoneUnlockedTotal; // total number of tokens unlocked in milestones
        uint256 public tokensWithdrawn; // total number of tokens withdrawn
        GovType public govType;
        bool public terminated;
        uint256 public terminationTime;

        /// @notice BaseAllocation constructor
        /// @param _grantee: address of the grantee, cannot be a zero address
        /// @param _controller: address of the MetaVesTController contract
        constructor(address _grantee, address _controller) {
            // Controller can be 0 for an immuatable version, but grantee cannot
            if (_grantee == address(0)) revert MetaVesT_ZeroAddress();
            grantee = _grantee;
            controller = _controller;
            govType = GovType.vested;
        }

        function getVestingType() external view virtual returns (uint256);
        function getGoverningPower() external virtual returns (uint256);  
        function updateStopTimes(uint48 _shortStopTime) external virtual;// onlyController;
        function terminate() external virtual;// onlyController;
        function getAmountWithdrawable() public view virtual returns (uint256);

        /// @notice returns the amount of voting power that may be affected by amendment proposals
        /// @return majorityVotingPower - the amount of tokens that are vested, locked, and unexercised
        function getMajorityVotingPower() external view returns (uint256 majorityVotingPower) {
            //add up the total tokens that are unvested or locked
            if(terminated) return 0;
            uint256 totalMilestoneAward = 0;
            for(uint256 i; i < milestones.length; ++i)
            { 
                    totalMilestoneAward += milestones[i].milestoneAward;
            }
            uint256 tokensNotAffected = tokensWithdrawn + getAmountWithdrawable();
            majorityVotingPower = allocation.tokenStreamTotal + totalMilestoneAward - tokensNotAffected;
        }

        /// @notice updates the transferability of the vesting contract
        /// @dev onlyController -- must be called from the metavest controller
        /// @param _transferable - bool to set the transferability of the vesting contract
        function updateTransferability(bool _transferable) external onlyController {
            transferable = _transferable;
            emit MetaVesT_TransferabilityUpdated(grantee, _transferable);
        }

        function totalTokens() external view returns (uint256) {
            return IERC20M(allocation.tokenContract).balanceOf(address(this));
        }

        /// @notice updates the vesting rate of the VestingAllocation
        /// @dev onlyController -- must be called from the metavest controller
        /// @param _newVestingRate - the updated vesting rate in tokens per second in the vesting token decimal
        function updateVestingRate(uint160 _newVestingRate) external onlyController {
            if(terminated) revert MetaVesT_AlreadyTerminated();
            allocation.vestingRate = _newVestingRate;
            emit MetaVesT_VestingRateUpdated(grantee, _newVestingRate);
        }

        /// @notice updates the unlock rate of the VestingAllocation
        /// @dev onlyController -- must be called from the metavest controller
        /// @param _newUnlockRate - the updated unlock rate in tokens per second in the vesting token decimal
        function updateUnlockRate(uint160 _newUnlockRate) external onlyController {
            allocation.unlockRate = _newUnlockRate;
            emit MetaVesT_UnlockRateUpdated(grantee, _newUnlockRate);
        }

        /// @notice Sets the governing power type for the MetaVesT
        /// @param _govType: the type of governing power to be used
        function setGovVariables(GovType _govType) external onlyController {
            if(terminated) revert MetaVesT_AlreadyTerminated();
            govType = _govType;
            emit MetaVest_GovVariablesUpdated(govType);
        }

        /// @notice allows a milestone to be 'unlocked'. callable by anyone but the conditions for the milestone must be met
        /// @param _milestoneIndex - the index of the milestone to confirm
        function confirmMilestone(uint256 _milestoneIndex) external nonReentrant {
            if(terminated) revert MetaVesT_AlreadyTerminated();
            if(_milestoneIndex >= milestones.length) revert MetaVesT_MilestoneIndexOutOfRange();
            Milestone storage milestone = milestones[_milestoneIndex];
            if (_milestoneIndex >= milestones.length || milestone.complete)
                revert MetaVesT_MilestoneIndexCompletedOrDoesNotExist();
            
            //encode the milestone index to bytes for signature verification
            bytes memory _data = abi.encodePacked(_milestoneIndex);
            // perform any applicable condition checks, including whether 'authority' has a signatureCondition
            for (uint256 i; i < milestone.conditionContracts.length; ++i) {
                if (!IConditionM(milestone.conditionContracts[i]).checkCondition(address(this), msg.sig, _data))
                    revert MetaVesT_ConditionNotSatisfied();
            }

            milestone.complete = true;
            milestoneAwardTotal += milestone.milestoneAward;
            if(milestone.unlockOnCompletion)
                milestoneUnlockedTotal += milestone.milestoneAward;
        
            emit MetaVesT_MilestoneCompleted(grantee, _milestoneIndex);
        }

        /// @notice removes a milestone from the VestingAllocation
        /// @dev onlyController -- must be called from the metavest controller
        /// @param _milestoneIndex - the index of the milestone to remove
        function removeMilestone(uint256 _milestoneIndex) external onlyController {
            if(terminated) revert MetaVesT_AlreadyTerminated();
            if (_milestoneIndex >= milestones.length) revert MetaVesT_MilestoneIndexOutOfRange();
            uint256 _milestoneAward = milestones[_milestoneIndex].milestoneAward;
            //transfer the milestone award back to the authority, we check in the controller to ensure only uncompleted milestones can be removed
            safeTransfer(allocation.tokenContract, getAuthority(), _milestoneAward);
            delete milestones[_milestoneIndex];
            milestones[_milestoneIndex] = milestones[milestones.length - 1];
            milestones.pop();
            emit MetaVesT_MilestoneRemoved(grantee, _milestoneIndex);
        }

        /// @notice adds a milestone to the VestingAllocation
        /// @dev onlyController -- must be called from the metavest controller
        /// @param _milestone - the milestone to add
        function addMilestone(Milestone calldata _milestone) external onlyController {
            if(terminated) revert MetaVesT_AlreadyTerminated();
            if(milestones.length >= MAX_MILESTONES) revert MetaVesT_MaxMilestonesReached();
            milestones.push(_milestone);
            emit MetaVesT_MilestoneAdded(grantee, _milestone);
        }

        /// @notice transfers the rights of the VestingAllocation to a new owner
        /// @dev onlyGrantee -- must be called by the grantee
        /// @param _newOwner - the address of the new owner
        function transferRights(address _newOwner) external onlyGrantee {
            if(_newOwner == address(0)) revert MetaVesT_ZeroAddress();
            if(!transferable) revert MetaVesT_VestNotTransferable();
            emit MetaVest_TransferRightsPending(grantee, _newOwner);
            pendingGrantee = _newOwner;
        }

        /// @notice confirms the transfer of the rights of the VestingAllocation to a new owner
        function confirmTransfer() external {
            if(msg.sender != pendingGrantee) revert MetaVesT_OnlyGrantee();
            grantee = pendingGrantee;
            emit MetaVesT_TransferredRights(grantee, pendingGrantee);
            pendingGrantee = address(0);
        }

        /// @notice withdraws tokens from the VestingAllocation
        /// @dev onlyGrantee -- must be called by the grantee
        /// @param _amount - the amount of tokens to withdraw
        function withdraw(uint256 _amount) external nonReentrant onlyGrantee {
            if (_amount == 0) revert MetaVesT_ZeroAmount();
            if (_amount > getAmountWithdrawable() || _amount > IERC20M(allocation.tokenContract).balanceOf(address(this))) revert MetaVesT_MoreThanAvailable();
            tokensWithdrawn += _amount;
            safeTransfer(allocation.tokenContract, msg.sender, _amount);
            emit MetaVesT_Withdrawn(msg.sender, allocation.tokenContract, _amount);
        }

        /// @notice gets the details of the vest
        /// @return Allocation - the allocation details
        function getMetavestDetails() external view returns (Allocation memory) {
            return allocation;
        }

        /// @notice returns the authority address
        /// @return address of the authority
        function getAuthority() public view returns (address){
            return IController(controller).authority();
        }
        
        modifier onlyController() {
            if (msg.sender != controller) revert MetaVesT_OnlyController();
            _;
        }

        modifier onlyGrantee() {
            if (msg.sender != grantee) revert MetaVesT_OnlyGrantee();
            _;
        }

        modifier onlyAuthority() {
            if (msg.sender != getAuthority()) revert MetaVesT_OnlyAuthority();
            _;
        }

        /// @dev returns the minimum of `x` and `y`. See https://github.com/Vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol
        function _min(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := xor(x, mul(xor(x, y), lt(y, x)))
                }
        }


}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_grantee","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"components":[{"internalType":"uint256","name":"tokenStreamTotal","type":"uint256"},{"internalType":"uint128","name":"vestingCliffCredit","type":"uint128"},{"internalType":"uint128","name":"unlockingCliffCredit","type":"uint128"},{"internalType":"uint160","name":"vestingRate","type":"uint160"},{"internalType":"uint48","name":"vestingStartTime","type":"uint48"},{"internalType":"uint160","name":"unlockRate","type":"uint160"},{"internalType":"uint48","name":"unlockStartTime","type":"uint48"},{"internalType":"address","name":"tokenContract","type":"address"}],"internalType":"struct BaseAllocation.Allocation","name":"_allocation","type":"tuple"},{"components":[{"internalType":"uint256","name":"milestoneAward","type":"uint256"},{"internalType":"bool","name":"unlockOnCompletion","type":"bool"},{"internalType":"bool","name":"complete","type":"bool"},{"internalType":"address[]","name":"conditionContracts","type":"address[]"}],"internalType":"struct BaseAllocation.Milestone[]","name":"_milestones","type":"tuple[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MetaVesT_AlreadyTerminated","type":"error"},{"inputs":[],"name":"MetaVesT_ConditionNotSatisfied","type":"error"},{"inputs":[],"name":"MetaVesT_MaxMilestonesReached","type":"error"},{"inputs":[],"name":"MetaVesT_MilestoneIndexCompletedOrDoesNotExist","type":"error"},{"inputs":[],"name":"MetaVesT_MilestoneIndexOutOfRange","type":"error"},{"inputs":[],"name":"MetaVesT_MoreThanAvailable","type":"error"},{"inputs":[],"name":"MetaVesT_NotTerminated","type":"error"},{"inputs":[],"name":"MetaVesT_OnlyAuthority","type":"error"},{"inputs":[],"name":"MetaVesT_OnlyController","type":"error"},{"inputs":[],"name":"MetaVesT_OnlyGrantee","type":"error"},{"inputs":[],"name":"MetaVesT_RateTooHigh","type":"error"},{"inputs":[],"name":"MetaVesT_ShortStopTimeNotReached","type":"error"},{"inputs":[],"name":"MetaVesT_TooSmallAmount","type":"error"},{"inputs":[],"name":"MetaVesT_VestNotTransferable","type":"error"},{"inputs":[],"name":"MetaVesT_ZeroAddress","type":"error"},{"inputs":[],"name":"MetaVesT_ZeroAmount","type":"error"},{"inputs":[],"name":"MetaVest_ShortStopDatePassed","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferFromFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"components":[{"internalType":"uint256","name":"milestoneAward","type":"uint256"},{"internalType":"bool","name":"unlockOnCompletion","type":"bool"},{"internalType":"bool","name":"complete","type":"bool"},{"internalType":"address[]","name":"conditionContracts","type":"address[]"}],"indexed":false,"internalType":"struct BaseAllocation.Milestone","name":"milestone","type":"tuple"}],"name":"MetaVesT_MilestoneAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":true,"internalType":"uint256","name":"milestoneIndex","type":"uint256"}],"name":"MetaVesT_MilestoneCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":true,"internalType":"uint256","name":"milestoneIndex","type":"uint256"}],"name":"MetaVesT_MilestoneRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":false,"internalType":"uint256","name":"exercisePrice","type":"uint256"}],"name":"MetaVesT_PriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdrawalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"repurchaseAmount","type":"uint256"}],"name":"MetaVesT_RepurchaseAndWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grant","type":"address"},{"indexed":false,"internalType":"uint48","name":"shortStopTime","type":"uint48"}],"name":"MetaVesT_StopTimesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokensRecovered","type":"uint256"}],"name":"MetaVesT_Terminated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":false,"internalType":"bool","name":"isTransferable","type":"bool"}],"name":"MetaVesT_TransferabilityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":false,"internalType":"address","name":"transferee","type":"address"}],"name":"MetaVesT_TransferredRights","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":false,"internalType":"uint208","name":"unlockRate","type":"uint208"}],"name":"MetaVesT_UnlockRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":false,"internalType":"uint208","name":"vestingRate","type":"uint208"}],"name":"MetaVesT_VestingRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MetaVesT_Withdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum BaseAllocation.GovType","name":"_govType","type":"uint8"}],"name":"MetaVest_GovVariablesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"grantee","type":"address"},{"indexed":true,"internalType":"address","name":"pendingGrantee","type":"address"}],"name":"MetaVest_TransferRightsPending","type":"event"},{"inputs":[],"name":"MAX_MILESTONES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"milestoneAward","type":"uint256"},{"internalType":"bool","name":"unlockOnCompletion","type":"bool"},{"internalType":"bool","name":"complete","type":"bool"},{"internalType":"address[]","name":"conditionContracts","type":"address[]"}],"internalType":"struct BaseAllocation.Milestone","name":"_milestone","type":"tuple"}],"name":"addMilestone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allocation","outputs":[{"internalType":"uint256","name":"tokenStreamTotal","type":"uint256"},{"internalType":"uint128","name":"vestingCliffCredit","type":"uint128"},{"internalType":"uint128","name":"unlockingCliffCredit","type":"uint128"},{"internalType":"uint160","name":"vestingRate","type":"uint160"},{"internalType":"uint48","name":"vestingStartTime","type":"uint48"},{"internalType":"uint160","name":"unlockRate","type":"uint160"},{"internalType":"uint48","name":"unlockStartTime","type":"uint48"},{"internalType":"address","name":"tokenContract","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_milestoneIndex","type":"uint256"}],"name":"confirmMilestone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAmountWithdrawable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuthority","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGoverningPower","outputs":[{"internalType":"uint256","name":"governingPower","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMajorityVotingPower","outputs":[{"internalType":"uint256","name":"majorityVotingPower","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMetavestDetails","outputs":[{"components":[{"internalType":"uint256","name":"tokenStreamTotal","type":"uint256"},{"internalType":"uint128","name":"vestingCliffCredit","type":"uint128"},{"internalType":"uint128","name":"unlockingCliffCredit","type":"uint128"},{"internalType":"uint160","name":"vestingRate","type":"uint160"},{"internalType":"uint48","name":"vestingStartTime","type":"uint48"},{"internalType":"uint160","name":"unlockRate","type":"uint160"},{"internalType":"uint48","name":"unlockStartTime","type":"uint48"},{"internalType":"address","name":"tokenContract","type":"address"}],"internalType":"struct BaseAllocation.Allocation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnlockedTokenAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVestedTokenAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVestingType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"govType","outputs":[{"internalType":"enum BaseAllocation.GovType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"grantee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"milestoneAwardTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"milestoneUnlockedTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"milestones","outputs":[{"internalType":"uint256","name":"milestoneAward","type":"uint256"},{"internalType":"bool","name":"unlockOnCompletion","type":"bool"},{"internalType":"bool","name":"complete","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGrantee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_milestoneIndex","type":"uint256"}],"name":"removeMilestone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum BaseAllocation.GovType","name":"_govType","type":"uint8"}],"name":"setGovVariables","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"terminate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"terminated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"terminationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferRights","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"_shortStopTime","type":"uint48"}],"name":"updateStopTimes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_transferable","type":"bool"}],"name":"updateTransferability","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint160","name":"_newUnlockRate","type":"uint160"}],"name":"updateUnlockRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint160","name":"_newVestingRate","type":"uint160"}],"name":"updateVestingRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

0x60a0604052346200058e576200230d803803806200001d81620005a6565b92833981818101039061016082126200058e576200003b83620005cc565b6200004960208501620005cc565b916101008094603f1901126200058e5760405193808501906001600160401b03821186831017620003bb57620000ea91604052604087015186526200009160608801620005e1565b6020870152620000a460808801620005e1565b6040870152620000b760a08801620005cc565b6060870152620000ca60c08801620005f6565b6080870152620000dd60e08801620005cc565b60a08701528601620005f6565b60c0850152620000fe6101208601620005cc565b60e0850152610140850151946001600160401b0386116200058e57818101601f8783010112156200058e5785810151620001426200013c826200060a565b620005a6565b96602088838152019084840160208460051b8387010101116200058e57602081850101915b60208460051b838701010183106200047757505050506001600160a01b03831615915062000465905057600180546001600160a01b0319166001600160a01b03928316178155608092909252600c805460ff191690921790915560e082015116156200046557683635c9adc5dea000008060018060a01b03606084015116119081156200044d575b506200043b5760018060a01b0360e08201511660018060a01b03196008541617600855805160045560018060801b0360208201511660018060801b0319604083015160801b161760055560018060a01b0360608201511660065465ffffffffffff60a01b9182608085015160a01b169060018060d01b0319809316171760065560018060a01b0360a0840151169160c060075494015160a01b16921617176007555f5b8151811015620003e35760208160051b830101516003908154680100000000000000009283821015620003bb5760018201808255821015620003cf57606091816002925f5260205f20910201835181556001810160208501511515815460ff61ff006040890151151560081b1692169061ffff1916171790550191015180519260018060401b038411620003bb578311620003bb57815483835580841062000392575b50602001905f5260205f205f5b8381106200037457505050505f198114620003605760010162000292565b634e487b7160e01b5f52601160045260245ffd5b82516001600160a01b03168183015560209092019160010162000342565b825f528360205f2091820191015b818110620003af575062000335565b5f8155600101620003a0565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b604051611cdc9081620006318239608051818181610345015281816103e701528181610c3301528181610db601528181610e720152818161110b0152818161136b015281816114e5015281816115470152611ae80152f35b60405163883e669d60e01b8152600490fd5b60a08301516001600160a01b03161190505f620001ef565b604051630a20411f60e41b8152600490fd5b82516001600160401b0381116200058e57828601016080601f19828989010301126200058e5760405190608082016001600160401b03811183821017620005925760405260208101518252620004d06040820162000622565b6020830152620004e36060820162000622565b604083015260808101516001600160401b0381116200058e57888801603f8284010112156200058e576020818301015190620005236200013c836200060a565b9260208484815201918b8b0160408560051b8385010101116200058e57604081830101925b60408560051b8385010101841062000573575050505050606082015281526020928301920162000167565b602080916200058286620005cc565b81520193019262000548565b5f80fd5b60245f634e487b7160e01b81526041600452fd5b6040519190601f01601f191682016001600160401b03811183821017620003bb57604052565b51906001600160a01b03821682036200058e57565b51906001600160801b03821682036200058e57565b519065ffffffffffff821682036200058e57565b6001600160401b038111620003bb5760051b60200190565b519081151582036200058e5756fe60806040526004361015610011575f80fd5b5f3560e01c80630473d3b4146102345780630a86491a1461022f5780630c08bf881461022a5780630e17454c14610225578063194307bf146102205780631c12691d1461021b57806329315ea7146102165780632e1a7d4d1461021157806336f2e56b1461020c5780634614baaa14610207578063497fb5b9146102025780634c05abeb146101fd57806361d3458f146101f857806363f5de76146101f35780636ccd7214146101ee578063736eb718146101e95780637bd57fbe146101e45780637e1c0c09146101df57806388a17bde146101da5780638c301e57146101d557806397926fc8146101d05780639d0d55b5146101cb578063b7de1cc0146101c6578063baa49301146101c1578063bf7e214f146101bc578063c4083cb1146101b7578063ce4254ce146101b2578063d2487d72146101ad578063d5f52076146101a8578063db9c7d3e146101a3578063e2b178a01461019e578063e89e4ed614610199578063f70eadc6146101945763f77c47911461018f575f80fd5b611532565b6114c1565b611471565b6113f4565b611344565b61131c565b611302565b6112e5565b6112cb565b6112a4565b611233565b611216565b6111fc565b6110f5565b6110d8565b61105e565b610fec565b610e37565b610d97565b610cca565b610ca8565b610c0b565b610be6565b610bc9565b610afa565b610a41565b6108a7565b610673565b61064b565b610626565b61060b565b6103d4565b61031e565b34610309575f8060031936011261030657600c5460ff1661025481610a10565b806102bd5750806003545b80821061029757505061028361027a6102939260045461159d565b600b54906115b8565b6040519081529081906020820190565b0390f35b90916102b16102b7916102a985611434565b50549061159d565b9261158a565b9061025f565b600191506102ca81610a10565b036102e2576102936102dd61027a611b57565b610283565b6102936102dd61027a6102f3611b57565b6102fb611c05565b818110908218021890565b80fd5b5f80fd5b6001600160a01b0381160361030957565b346103095760203660031901126103095760043561033b8161030d565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811633036103c257600780546001600160a01b0319168383161790556001546040516001600160a01b03909316835216907fc72b361adc3106aab68fafd2bb0c88c8640ab9a4a9e44e0fe3c006138dcf4d7b9080602081015b0390a2005b604051635f84f8e360e11b8152600490fd5b34610309575f80600319360112610306577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036103c25768929eee149b4bd21268308154146105fe57308155600c5460081c60ff166105ec5781826003545b8082106105d45750506104556104639160045461159d565b61045d611b57565b906115b8565b6008546104869061047a906001600160a01b031681565b6001600160a01b031690565b6040516370a0823160e01b80825230600483015260209392918481602481865afa9081156105b25787916105b7575b508311610554575b505090506104ca42600d55565b6008546104eb9082906001600160a01b03165b6104e5611ad3565b9061197f565b6104ff61010061ff0019600c541617600c55565b6001547f0b921cba1f8d7abccbb39feb38b91f62a4b3f2d82fc130481835dd545b7e5d039061054b9061053a906001600160a01b031661047a565b604051938452929081906020820190565b0390a238905580f35b60405190815230600482015291508290829060249082905afa9182156105b2578492610585575b5050805f806104bd565b6105a49250803d106105ab575b61059c8183611669565b81019061168b565b5f8061057b565b503d610592565b61169a565b6105ce9150853d87116105ab5761059c8183611669565b5f6104b5565b90916102b16105e6916102a985611434565b9061043d565b604051637daa23d960e11b8152600490fd5b63ab143c0682526004601cfd5b34610309575f36600319011261030957602060405160018152f35b34610309575f36600319011261030957602060ff600c5460081c166040519015158152f35b34610309575f366003190112610309576002546040516001600160a01b039091168152602090f35b34610309576020806003193601126103095760049081359068929eee149b4bd21268923084541461089c57308455600c5460081c60ff1661088d57600354831091821561087d576106c384611434565b50925f9061086c575b61085c5760408051916106f7836106e98884830160209181520190565b03601f198101855284611669565b60028501805493905f80356001600160e01b03191691905b8681106107ae578a8a8a61074f600182016107338161010061ff0019825416179055565b610748610743845460095461159d565b600955565b5460ff1690565b610793575b5060015461076a906001600160a01b031661047a565b7f232bf093fa1e4fed3729de5722f4210ce4f9652bb817a59794e3dffde53d6fc35f80a3389055005b6107a36107a89154600a5461159d565b600a55565b82610754565b6107f985856107db61047a61047a6107c687896116a5565b905460039190911b1c6001600160a01b031690565b868c8b519586948593849363ba1267b560e01b8552309085016116cf565b03915afa9081156105b2575f9161082f575b501561081f5761081a9061158a565b61070f565b8551637e96811560e01b81528890fd5b61084f9150863d8811610855575b6108478183611669565b8101906116ba565b5f61080b565b503d61083d565b50604051635efff6bb60e01b8152fd5b50600183015460081c60ff166106cc565b5060405163e6cf825560e01b8152fd5b604051637daa23d960e11b8152fd5b63ab143c065f52601cfd5b34610309576020366003190112610309576004803568929eee149b4bd21268913083541461089c573083556001546001600160a01b03919082163303610a015782156109f2576108f5611c76565b83118015610980575b610971575061091761091283600b5461159d565b600b55565b60085461093090839033906001600160a01b031661197f565b600854604051928352166001600160a01b03169033907fcb7000702ccb0f4a36ea88ebadd8460f2535d7780f465abdc42156d59c7e471690602090a3389055005b60405163ae110e3d60e01b8152fd5b506008546109989061047a906001600160a01b031681565b6040516370a0823160e01b815230838201908152909160209183919082908190850103915afa9081156105b2575f916109d4575b5083116108fe565b6109ec915060203d81116105ab5761059c8183611669565b5f6109cc565b6040516317338d0b60e31b8152fd5b604051637232eb7d60e11b8152fd5b60031115610a1a57565b634e487b7160e01b5f52602160045260245ffd5b919060208301926003821015610a1a5752565b34610309575f3660031901126103095761029360ff600c541660405191829182610a2e565b610af89092919260e080610100830195805184526001600160801b03806020830151166020860152604082015116604085015260018060a01b03606082015116606085015265ffffffffffff6080820151166080850152610ad660a082015160a086019060018060a01b03169052565b60c08181015165ffffffffffff169085015201516001600160a01b0316910152565b565b34610309575f806003193601126103065760e0604051610b198161164c565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201520152610293604051610b518161164c565b60045481526005546001600160801b0381166020830152608090811c60408301526006546001600160a01b03808216606085015265ffffffffffff60a092831c81169385019390935260075490811682850152901c1660c08201526008546001600160a01b031660e082015260405191829182610a66565b34610309575f366003190112610309576020600b54604051908152f35b34610309575f36600319011261030957602060405160148152f35b8015150361030957565b3461030957602036600319011261030957600435610c2881610c01565b6001600160a01b03907f0000000000000000000000000000000000000000000000000000000000000000821633036103c25760207f2b63f16f8aad8ee3cd55e8dc71af123c4505b84d3db0296fcc922c8ca976455c9115159260025460ff60a01b8560a01b169060ff60a01b1916176002556001541692604051908152a2005b34610309575f366003190112610309576020610cc2611c05565b604051908152f35b3461030957602036600319011261030957600435610ce78161030d565b6001546001600160a01b03908116919033839003610d855781168015610d735760ff60025460a01c1615610d6157610d5f927fd7d74b0ecb9406d169a04ae7ac3ac603f82b97eb19cdfe10f1716c37a80014b05f80a360018060a01b03166bffffffffffffffffffffffff60a01b6002541617600255565b005b6040516347923a9760e11b8152600490fd5b604051630a20411f60e41b8152600490fd5b604051637232eb7d60e11b8152600490fd5b34610309576020366003190112610309576004356003811015610309577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036103c257600c549060ff8260081c166105ec577f2f117a93d1eaa3374f55da6d5f07d4d62db2e30e2e9679a47f0b80ae2ce014849160ff610e329216809160ff191617600c5560405191829182610a2e565b0390a1005b346103095760031960203682011261030957600480359067ffffffffffffffff908183116103095782810193608084360391820112610309577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163303610fdc5760ff600c5460081c16610fcc576003546014811015610fbb57600160401b811015610fb657806001610ed59201600355611434565b949094610fb15785358555610f3160018601610f0a6024840135610ef881610c01565b829060ff801983541691151516179055565b604483013590610f1982610c01565b9061ff00825491151560081b169061ff001916179055565b60648101359160221901821215610309570190810135918211610309576024018160051b36038113610309576002610f6993016119be565b6001547f877dce72a969310ab9303c0fc5712523d328f5191e944d7959c464f02d5af314906103bd90610fa4906001600160a01b031661047a565b9260405191829182611a54565b611789565b611638565b6040516309bfed0d60e41b81528390fd5b50604051637daa23d960e11b8152fd5b50604051635f84f8e360e11b8152fd5b34610309575f366003190112610309576008546040516370a0823160e01b815230600482015290602090829060249082906001600160a01b03165afa80156105b2576020915f91611041575b50604051908152f35b6110589150823d81116105ab5761059c8183611669565b5f611038565b34610309575f3660031901126103095761010060045460055460065460075460018060a01b038060085416936040519586526001600160801b038116602087015260801c6040860152808316606086015265ffffffffffff809360a01c166080860152811660a085015260a01c1660c083015260e0820152f35b34610309575f366003190112610309576020600954604051908152f35b34610309576020366003190112610309576004357f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036103c257600c5460081c60ff166105ec576003548110156111ea5761116f61115c82611434565b50546008546001600160a01b03166104dd565b61118161117b82611434565b9061179c565b6111a76111976111926003546115aa565b611434565b506111a183611434565b90611849565b6111af6118ae565b6001546111c4906001600160a01b031661047a565b7fab7f5ece62808ccb186faae53397a9b1175f6c73f8a1092d7dd3041ba2b9768e5f80a3005b60405163e6cf825560e01b8152600490fd5b34610309575f366003190112610309576020610cc26115c5565b34610309575f366003190112610309576020600a54604051908152f35b34610309575f366003190112610309576002546001600160a01b0381169033829003610d85576bffffffffffffffffffffffff60a01b91808360015416176001557fb87f3d33fa2183dad430f3c1ec9d76f87d9d5220ee47d7a1514c03746e8ed36c6020604051838152a216600255005b34610309575f366003190112610309575f546040516001600160a01b039091168152602090f35b34610309575f366003190112610309576020610cc2611c76565b34610309575f366003190112610309576020600d54604051908152f35b34610309575f366003190112610309576020610cc2611b57565b34610309575f366003190112610309576001546040516001600160a01b039091168152602090f35b34610309576020366003190112610309576004356113618161030d565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811633036103c25760ff600c5460081c166105ec57600680546001600160a01b0319168383161790556001546040516001600160a01b03909316835216907fbf1524e769506b96315e7c8ed4e7bbb9e1184c4527a5dd96b58863d3aacdbf709080602081016103bd565b34610309575f36600319011261030957602061140e611ad3565b6040516001600160a01b039091168152f35b634e487b7160e01b5f52603260045260245ffd5b60035481101561146c57600390815f52027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01905f90565b611420565b34610309576020366003190112610309576004356003548110156103095761149a606091611434565b5060ff600182549201546040519283528181161515602084015260081c1615156040820152f35b346103095760203660031901126103095760043565ffffffffffff811603610309577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036103c25760ff600c5460081c166105ec57604051637e96811560e01b8152600490fd5b34610309575f366003190112610309576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b634e487b7160e01b5f52601160045260245ffd5b5f1981146115985760010190565b611576565b9190820180921161159857565b5f1981019190821161159857565b9190820391821161159857565b60ff600c5460081c16611634575f806003545b80821061160e575050600b546115ec611c76565b8101809111611598576004549182018092116115985761160b916115b8565b90565b909161161983611434565b505481018091116115985761162e909261158a565b906115d8565b5f90565b634e487b7160e01b5f52604160045260245ffd5b610100810190811067ffffffffffffffff821117610fb657604052565b90601f8019910116810190811067ffffffffffffffff821117610fb657604052565b90816020910312610309575190565b6040513d5f823e3d90fd5b805482101561146c575f5260205f2001905f90565b90816020910312610309575161160b81610c01565b9193929060018060a01b0316825260209363ffffffff60e01b1684830152606060408301528051908160608401525f5b82811061172057505060809293505f838284010152601f8019910116010190565b8181018601518482016080015285016116ff565b8181029291811591840414171561159857565b600160401b8211610fb65780549180825582811061176457505050565b5f9182526020822092830192015b82811061177e57505050565b818155600101611772565b634e487b7160e01b5f525f60045260245ffd5b90610fb1575f808255600260019282848201550190815491818155826117c3575b50505050565b815260208120918201915b828110156117bd5781815583016117ce565b8181146118455781549167ffffffffffffffff8311610fb6576118038383611747565b5f5260205f20905f5260205f208154915f925b848410611824575050505050565b600191820180546001600160a01b0390921684860155939091019290611816565b5050565b90610fb157818103611859575050565b60028083610af8945484556118a66001850160ff6001840161188a82825416849060ff801983541691151516179055565b5460081c1661ff00825491151560081b169061ff001916179055565b0191016117e0565b600354801561196b575f1981019081101561146c575f600381527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d6003830282817fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0155827fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c82015501908154918181558261194d575b505050600355565b815260208120918201915b8281101561194557818155600101611958565b634e487b7160e01b5f52603160045260245ffd5b60109260209260145260345260445f9384809363a9059cbb60601b82525af13d1560018351141716156119b157603452565b6390b8ec1890526004601cfd5b9067ffffffffffffffff8311610fb6576119d88383611747565b905f526020805f20905f5b8481106119f1575050505050565b60019082853595611a018761030d565b019481850155016119e3565b9190808252602080920192915f5b828110611a29575050505090565b9091929382806001928735611a3d8161030d565b848060a01b03168152019501910192919092611a1b565b9060208252803560208301526020810135611a6e81610c01565b151560408301526040810135611a8381610c01565b151560608301526060810135601e198236030181121561030957016020813591019067ffffffffffffffff8111610309578060051b360382136103095760a08360808061160b9601520191611a0d565b60405163bf7e214f60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156105b2575f91611b23575090565b906020823d8211611b4f575b81611b3c60209383611669565b8101031261030657505161160b8161030d565b3d9150611b2f565b60065465ffffffffffff8160a01c1690814210611bff57814203428111611598579160ff600c5460081c16611be9575b5061160b91611bcc91611ba5916001600160a01b0390911690611734565b611bc6611bba6005546001600160801b031690565b6001600160801b031690565b9061159d565b600454808211611be1575b506009549061159d565b90505f611bd7565b600d549081039250821161159857611ba5611b87565b50505f90565b60075465ffffffffffff8160a01c16804210611bff57420342811161159857611c37916001600160a01b031690611734565b60055460801c81018091116115985780600454906009548201809211611598578110611c6e575b50600a5481018091116115985790565b90505f611c5e565b611c7e611b57565b611c86611c05565b8181109082180218600b548082115f14611bff578103908111611598579056fea26469706673582212202bd4919294f831f70cff95ba8cfbb740d9524ab77c7b3c9ba582f39a4fe4635a64736f6c634300081400330000000000000000000000009a5e2780204fb980a5a5714b4e6bf7a659343cbd000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067a1456400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067a1456400000000000000000000000058b9cb810a68a7f3e1e4f8cb45d1b9b3c79705e800000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000460000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000005e000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000760000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000008e000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000a600000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000ca00000000000000000000000000000000000000000000000000000000000000d600000000000000000000000000000000000000000000000000000000000000e20000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96000000000000000000000000000000000000000000001d4fd1ff1e40b0d435e5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000010f12518679a8ebef24373c8184d057a5cbcbe96

Deployed Bytecode

0x60806040526004361015610011575f80fd5b5f3560e01c80630473d3b4146102345780630a86491a1461022f5780630c08bf881461022a5780630e17454c14610225578063194307bf146102205780631c12691d1461021b57806329315ea7146102165780632e1a7d4d1461021157806336f2e56b1461020c5780634614baaa14610207578063497fb5b9146102025780634c05abeb146101fd57806361d3458f146101f857806363f5de76146101f35780636ccd7214146101ee578063736eb718146101e95780637bd57fbe146101e45780637e1c0c09146101df57806388a17bde146101da5780638c301e57146101d557806397926fc8146101d05780639d0d55b5146101cb578063b7de1cc0146101c6578063baa49301146101c1578063bf7e214f146101bc578063c4083cb1146101b7578063ce4254ce146101b2578063d2487d72146101ad578063d5f52076146101a8578063db9c7d3e146101a3578063e2b178a01461019e578063e89e4ed614610199578063f70eadc6146101945763f77c47911461018f575f80fd5b611532565b6114c1565b611471565b6113f4565b611344565b61131c565b611302565b6112e5565b6112cb565b6112a4565b611233565b611216565b6111fc565b6110f5565b6110d8565b61105e565b610fec565b610e37565b610d97565b610cca565b610ca8565b610c0b565b610be6565b610bc9565b610afa565b610a41565b6108a7565b610673565b61064b565b610626565b61060b565b6103d4565b61031e565b34610309575f8060031936011261030657600c5460ff1661025481610a10565b806102bd5750806003545b80821061029757505061028361027a6102939260045461159d565b600b54906115b8565b6040519081529081906020820190565b0390f35b90916102b16102b7916102a985611434565b50549061159d565b9261158a565b9061025f565b600191506102ca81610a10565b036102e2576102936102dd61027a611b57565b610283565b6102936102dd61027a6102f3611b57565b6102fb611c05565b818110908218021890565b80fd5b5f80fd5b6001600160a01b0381160361030957565b346103095760203660031901126103095760043561033b8161030d565b6001600160a01b037f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b4811633036103c257600780546001600160a01b0319168383161790556001546040516001600160a01b03909316835216907fc72b361adc3106aab68fafd2bb0c88c8640ab9a4a9e44e0fe3c006138dcf4d7b9080602081015b0390a2005b604051635f84f8e360e11b8152600490fd5b34610309575f80600319360112610306577f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b46001600160a01b031633036103c25768929eee149b4bd21268308154146105fe57308155600c5460081c60ff166105ec5781826003545b8082106105d45750506104556104639160045461159d565b61045d611b57565b906115b8565b6008546104869061047a906001600160a01b031681565b6001600160a01b031690565b6040516370a0823160e01b80825230600483015260209392918481602481865afa9081156105b25787916105b7575b508311610554575b505090506104ca42600d55565b6008546104eb9082906001600160a01b03165b6104e5611ad3565b9061197f565b6104ff61010061ff0019600c541617600c55565b6001547f0b921cba1f8d7abccbb39feb38b91f62a4b3f2d82fc130481835dd545b7e5d039061054b9061053a906001600160a01b031661047a565b604051938452929081906020820190565b0390a238905580f35b60405190815230600482015291508290829060249082905afa9182156105b2578492610585575b5050805f806104bd565b6105a49250803d106105ab575b61059c8183611669565b81019061168b565b5f8061057b565b503d610592565b61169a565b6105ce9150853d87116105ab5761059c8183611669565b5f6104b5565b90916102b16105e6916102a985611434565b9061043d565b604051637daa23d960e11b8152600490fd5b63ab143c0682526004601cfd5b34610309575f36600319011261030957602060405160018152f35b34610309575f36600319011261030957602060ff600c5460081c166040519015158152f35b34610309575f366003190112610309576002546040516001600160a01b039091168152602090f35b34610309576020806003193601126103095760049081359068929eee149b4bd21268923084541461089c57308455600c5460081c60ff1661088d57600354831091821561087d576106c384611434565b50925f9061086c575b61085c5760408051916106f7836106e98884830160209181520190565b03601f198101855284611669565b60028501805493905f80356001600160e01b03191691905b8681106107ae578a8a8a61074f600182016107338161010061ff0019825416179055565b610748610743845460095461159d565b600955565b5460ff1690565b610793575b5060015461076a906001600160a01b031661047a565b7f232bf093fa1e4fed3729de5722f4210ce4f9652bb817a59794e3dffde53d6fc35f80a3389055005b6107a36107a89154600a5461159d565b600a55565b82610754565b6107f985856107db61047a61047a6107c687896116a5565b905460039190911b1c6001600160a01b031690565b868c8b519586948593849363ba1267b560e01b8552309085016116cf565b03915afa9081156105b2575f9161082f575b501561081f5761081a9061158a565b61070f565b8551637e96811560e01b81528890fd5b61084f9150863d8811610855575b6108478183611669565b8101906116ba565b5f61080b565b503d61083d565b50604051635efff6bb60e01b8152fd5b50600183015460081c60ff166106cc565b5060405163e6cf825560e01b8152fd5b604051637daa23d960e11b8152fd5b63ab143c065f52601cfd5b34610309576020366003190112610309576004803568929eee149b4bd21268913083541461089c573083556001546001600160a01b03919082163303610a015782156109f2576108f5611c76565b83118015610980575b610971575061091761091283600b5461159d565b600b55565b60085461093090839033906001600160a01b031661197f565b600854604051928352166001600160a01b03169033907fcb7000702ccb0f4a36ea88ebadd8460f2535d7780f465abdc42156d59c7e471690602090a3389055005b60405163ae110e3d60e01b8152fd5b506008546109989061047a906001600160a01b031681565b6040516370a0823160e01b815230838201908152909160209183919082908190850103915afa9081156105b2575f916109d4575b5083116108fe565b6109ec915060203d81116105ab5761059c8183611669565b5f6109cc565b6040516317338d0b60e31b8152fd5b604051637232eb7d60e11b8152fd5b60031115610a1a57565b634e487b7160e01b5f52602160045260245ffd5b919060208301926003821015610a1a5752565b34610309575f3660031901126103095761029360ff600c541660405191829182610a2e565b610af89092919260e080610100830195805184526001600160801b03806020830151166020860152604082015116604085015260018060a01b03606082015116606085015265ffffffffffff6080820151166080850152610ad660a082015160a086019060018060a01b03169052565b60c08181015165ffffffffffff169085015201516001600160a01b0316910152565b565b34610309575f806003193601126103065760e0604051610b198161164c565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201520152610293604051610b518161164c565b60045481526005546001600160801b0381166020830152608090811c60408301526006546001600160a01b03808216606085015265ffffffffffff60a092831c81169385019390935260075490811682850152901c1660c08201526008546001600160a01b031660e082015260405191829182610a66565b34610309575f366003190112610309576020600b54604051908152f35b34610309575f36600319011261030957602060405160148152f35b8015150361030957565b3461030957602036600319011261030957600435610c2881610c01565b6001600160a01b03907f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b4821633036103c25760207f2b63f16f8aad8ee3cd55e8dc71af123c4505b84d3db0296fcc922c8ca976455c9115159260025460ff60a01b8560a01b169060ff60a01b1916176002556001541692604051908152a2005b34610309575f366003190112610309576020610cc2611c05565b604051908152f35b3461030957602036600319011261030957600435610ce78161030d565b6001546001600160a01b03908116919033839003610d855781168015610d735760ff60025460a01c1615610d6157610d5f927fd7d74b0ecb9406d169a04ae7ac3ac603f82b97eb19cdfe10f1716c37a80014b05f80a360018060a01b03166bffffffffffffffffffffffff60a01b6002541617600255565b005b6040516347923a9760e11b8152600490fd5b604051630a20411f60e41b8152600490fd5b604051637232eb7d60e11b8152600490fd5b34610309576020366003190112610309576004356003811015610309577f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b46001600160a01b031633036103c257600c549060ff8260081c166105ec577f2f117a93d1eaa3374f55da6d5f07d4d62db2e30e2e9679a47f0b80ae2ce014849160ff610e329216809160ff191617600c5560405191829182610a2e565b0390a1005b346103095760031960203682011261030957600480359067ffffffffffffffff908183116103095782810193608084360391820112610309577f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b46001600160a01b03163303610fdc5760ff600c5460081c16610fcc576003546014811015610fbb57600160401b811015610fb657806001610ed59201600355611434565b949094610fb15785358555610f3160018601610f0a6024840135610ef881610c01565b829060ff801983541691151516179055565b604483013590610f1982610c01565b9061ff00825491151560081b169061ff001916179055565b60648101359160221901821215610309570190810135918211610309576024018160051b36038113610309576002610f6993016119be565b6001547f877dce72a969310ab9303c0fc5712523d328f5191e944d7959c464f02d5af314906103bd90610fa4906001600160a01b031661047a565b9260405191829182611a54565b611789565b611638565b6040516309bfed0d60e41b81528390fd5b50604051637daa23d960e11b8152fd5b50604051635f84f8e360e11b8152fd5b34610309575f366003190112610309576008546040516370a0823160e01b815230600482015290602090829060249082906001600160a01b03165afa80156105b2576020915f91611041575b50604051908152f35b6110589150823d81116105ab5761059c8183611669565b5f611038565b34610309575f3660031901126103095761010060045460055460065460075460018060a01b038060085416936040519586526001600160801b038116602087015260801c6040860152808316606086015265ffffffffffff809360a01c166080860152811660a085015260a01c1660c083015260e0820152f35b34610309575f366003190112610309576020600954604051908152f35b34610309576020366003190112610309576004357f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b46001600160a01b031633036103c257600c5460081c60ff166105ec576003548110156111ea5761116f61115c82611434565b50546008546001600160a01b03166104dd565b61118161117b82611434565b9061179c565b6111a76111976111926003546115aa565b611434565b506111a183611434565b90611849565b6111af6118ae565b6001546111c4906001600160a01b031661047a565b7fab7f5ece62808ccb186faae53397a9b1175f6c73f8a1092d7dd3041ba2b9768e5f80a3005b60405163e6cf825560e01b8152600490fd5b34610309575f366003190112610309576020610cc26115c5565b34610309575f366003190112610309576020600a54604051908152f35b34610309575f366003190112610309576002546001600160a01b0381169033829003610d85576bffffffffffffffffffffffff60a01b91808360015416176001557fb87f3d33fa2183dad430f3c1ec9d76f87d9d5220ee47d7a1514c03746e8ed36c6020604051838152a216600255005b34610309575f366003190112610309575f546040516001600160a01b039091168152602090f35b34610309575f366003190112610309576020610cc2611c76565b34610309575f366003190112610309576020600d54604051908152f35b34610309575f366003190112610309576020610cc2611b57565b34610309575f366003190112610309576001546040516001600160a01b039091168152602090f35b34610309576020366003190112610309576004356113618161030d565b6001600160a01b037f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b4811633036103c25760ff600c5460081c166105ec57600680546001600160a01b0319168383161790556001546040516001600160a01b03909316835216907fbf1524e769506b96315e7c8ed4e7bbb9e1184c4527a5dd96b58863d3aacdbf709080602081016103bd565b34610309575f36600319011261030957602061140e611ad3565b6040516001600160a01b039091168152f35b634e487b7160e01b5f52603260045260245ffd5b60035481101561146c57600390815f52027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01905f90565b611420565b34610309576020366003190112610309576004356003548110156103095761149a606091611434565b5060ff600182549201546040519283528181161515602084015260081c1615156040820152f35b346103095760203660031901126103095760043565ffffffffffff811603610309577f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b46001600160a01b031633036103c25760ff600c5460081c166105ec57604051637e96811560e01b8152600490fd5b34610309575f366003190112610309576040517f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b46001600160a01b03168152602090f35b634e487b7160e01b5f52601160045260245ffd5b5f1981146115985760010190565b611576565b9190820180921161159857565b5f1981019190821161159857565b9190820391821161159857565b60ff600c5460081c16611634575f806003545b80821061160e575050600b546115ec611c76565b8101809111611598576004549182018092116115985761160b916115b8565b90565b909161161983611434565b505481018091116115985761162e909261158a565b906115d8565b5f90565b634e487b7160e01b5f52604160045260245ffd5b610100810190811067ffffffffffffffff821117610fb657604052565b90601f8019910116810190811067ffffffffffffffff821117610fb657604052565b90816020910312610309575190565b6040513d5f823e3d90fd5b805482101561146c575f5260205f2001905f90565b90816020910312610309575161160b81610c01565b9193929060018060a01b0316825260209363ffffffff60e01b1684830152606060408301528051908160608401525f5b82811061172057505060809293505f838284010152601f8019910116010190565b8181018601518482016080015285016116ff565b8181029291811591840414171561159857565b600160401b8211610fb65780549180825582811061176457505050565b5f9182526020822092830192015b82811061177e57505050565b818155600101611772565b634e487b7160e01b5f525f60045260245ffd5b90610fb1575f808255600260019282848201550190815491818155826117c3575b50505050565b815260208120918201915b828110156117bd5781815583016117ce565b8181146118455781549167ffffffffffffffff8311610fb6576118038383611747565b5f5260205f20905f5260205f208154915f925b848410611824575050505050565b600191820180546001600160a01b0390921684860155939091019290611816565b5050565b90610fb157818103611859575050565b60028083610af8945484556118a66001850160ff6001840161188a82825416849060ff801983541691151516179055565b5460081c1661ff00825491151560081b169061ff001916179055565b0191016117e0565b600354801561196b575f1981019081101561146c575f600381527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d6003830282817fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0155827fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c82015501908154918181558261194d575b505050600355565b815260208120918201915b8281101561194557818155600101611958565b634e487b7160e01b5f52603160045260245ffd5b60109260209260145260345260445f9384809363a9059cbb60601b82525af13d1560018351141716156119b157603452565b6390b8ec1890526004601cfd5b9067ffffffffffffffff8311610fb6576119d88383611747565b905f526020805f20905f5b8481106119f1575050505050565b60019082853595611a018761030d565b019481850155016119e3565b9190808252602080920192915f5b828110611a29575050505090565b9091929382806001928735611a3d8161030d565b848060a01b03168152019501910192919092611a1b565b9060208252803560208301526020810135611a6e81610c01565b151560408301526040810135611a8381610c01565b151560608301526060810135601e198236030181121561030957016020813591019067ffffffffffffffff8111610309578060051b360382136103095760a08360808061160b9601520191611a0d565b60405163bf7e214f60e01b81526020816004817f000000000000000000000000b46ce29c2c88b1983386c0a1709feab155d7c0b46001600160a01b03165afa9081156105b2575f91611b23575090565b906020823d8211611b4f575b81611b3c60209383611669565b8101031261030657505161160b8161030d565b3d9150611b2f565b60065465ffffffffffff8160a01c1690814210611bff57814203428111611598579160ff600c5460081c16611be9575b5061160b91611bcc91611ba5916001600160a01b0390911690611734565b611bc6611bba6005546001600160801b031690565b6001600160801b031690565b9061159d565b600454808211611be1575b506009549061159d565b90505f611bd7565b600d549081039250821161159857611ba5611b87565b50505f90565b60075465ffffffffffff8160a01c16804210611bff57420342811161159857611c37916001600160a01b031690611734565b60055460801c81018091116115985780600454906009548201809211611598578110611c6e575b50600a5481018091116115985790565b90505f611c5e565b611c7e611b57565b611c86611c05565b8181109082180218600b548082115f14611bff578103908111611598579056fea26469706673582212202bd4919294f831f70cff95ba8cfbb740d9524ab77c7b3c9ba582f39a4fe4635a64736f6c63430008140033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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