Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x982be53A6AE5E5FD037Be995f1d884aaad293b7c
Balance 0 ETH
Nonce 1
Code Size 3987 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

3987 bytes
0x608060405234801561001057600080fd5b50600436106101165760003560e01c8063746dd88d116100a257806395ee12211161007157806395ee122114610203578063c04637111461020b578063c45a015514610213578063e29bc68b1461021b578063ea8a1af01461022357610116565b8063746dd88d146101e35780638129fc1c146101eb57806384a1931f146101f357806390df22ed146101fb57610116565b80634500054f116100e95780634500054f146101895780634e71d92d146101a55780635aa6e675146101ad5780635c19a95c146101b557806366d003ac146101db57610116565b8063032d09611461011b57806309c10d1d1461013f5780632b73429b146101595780633bbed4a014610161575b600080fd5b61012361022b565b604080516001600160a01b039092168252519081900360200190f35b61014761023a565b60408051918252519081900360200190f35b610147610240565b6101876004803603602081101561017757600080fd5b50356001600160a01b0316610318565b005b61019161038a565b604080519115158252519081900360200190f35b610187610393565b6101236103ed565b610187600480360360208110156101cb57600080fd5b50356001600160a01b03166103fc565b61012361051a565b610147610529565b6101876105c8565b61014761088f565b610123610895565b6101916108a4565b6101476108b2565b6101236108b8565b6101476108c7565b6101876108cd565b6003546001600160a01b031681565b60055481565b600854600090610100900460ff161561025b57506000610315565b60075442106102e35760048054604080516370a0823160e01b81523093810193909352516001600160a01b03909116916370a08231916024808301926020929190829003018186803b1580156102b057600080fd5b505afa1580156102c4573d6000803e3d6000fd5b505050506040513d60208110156102da57600080fd5b50519050610315565b610312600654600754036103066009544203600554610c3590919063ffffffff16565b9063ffffffff610c9716565b90505b90565b6002546001600160a01b03163314610368576040805162461bcd60e51b815260206004820152600e60248201526d13d3931648149150d2541251539560921b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60085460ff1681565b6002546001600160a01b031633146103e3576040805162461bcd60e51b815260206004820152600e60248201526d13d3931648149150d2541251539560921b604482015290519081900360640190fd5b6103eb610cd9565b565b6000546001600160a01b031681565b6002546001600160a01b0316331461044c576040805162461bcd60e51b815260206004820152600e60248201526d13d3931648149150d2541251539560921b604482015290519081900360640190fd5b600354604080516317066a5760e21b81526001600160a01b03848116600483015291519190921691635c19a95c91602480830192600092919082900301818387803b15801561049a57600080fd5b505af11580156104ae573d6000803e3d6000fd5b50506004805460408051631e756d0f60e01b81523093810193909352516001600160a01b039091169350631e756d0f9250602480830192600092919082900301818387803b1580156104ff57600080fd5b505af1158015610513573d6000803e3d6000fd5b5050505050565b6002546001600160a01b031681565b6000610312670de0b6b3a7640000610306600460009054906101000a90046001600160a01b03166001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561058857600080fd5b505afa15801561059c573d6000803e3d6000fd5b505050506040513d60208110156105b257600080fd5b50516105bc610240565b9063ffffffff610c3516565b600354604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561061357600080fd5b505afa158015610627573d6000803e3d6000fd5b505050506040513d602081101561063d57600080fd5b5051905080610685576040805162461bcd60e51b815260206004820152600f60248201526e0494e5620414d4f554e54204953203608c1b604482015290519081900360640190fd5b6001546001600160a01b031633146106d3576040805162461bcd60e51b815260206004820152600c60248201526b4f4e4c5920464143544f525960a01b604482015290519081900360640190fd5b600354600480546040805163095ea7b360e01b81526001600160a01b0392831693810193909352602483018590525192169163095ea7b3916044808201926020929091908290030181600087803b15801561072d57600080fd5b505af1158015610741573d6000803e3d6000fd5b505050506040513d602081101561075757600080fd5b5050600480546040805163140e25ad60e31b8152928301849052516001600160a01b039091169163a0712d689160248083019260209291908290030181600087803b1580156107a557600080fd5b505af11580156107b9573d6000803e3d6000fd5b505050506040513d60208110156107cf57600080fd5b505115610811576040805162461bcd60e51b815260206004820152600b60248201526a135253950811905253115160aa1b604482015290519081900360640190fd5b60048054604080516370a0823160e01b81523093810193909352516001600160a01b03909116916370a08231916024808301926020929190829003018186803b15801561085d57600080fd5b505afa158015610871573d6000803e3d6000fd5b505050506040513d602081101561088757600080fd5b505160055550565b60075481565b6004546001600160a01b031681565b600854610100900460ff1681565b60095481565b6001546001600160a01b031681565b60065481565b6000546001600160a01b03163314806108f057506002546001600160a01b031633145b610941576040805162461bcd60e51b815260206004820152601c60248201527f4f4e4c5920474f5645524e414e4345204f5220524543495049454e5400000000604482015290519081900360640190fd5b60085460ff168061095c57506002546001600160a01b031633145b61099f576040805162461bcd60e51b815260206004820152600f60248201526e4e4f542043414e43454c4c41424c4560881b604482015290519081900360640190fd5b600854610100900460ff16156109f0576040805162461bcd60e51b8152602060048201526011602482015270105314915051164810d05390d153131151607a1b604482015290519081900360640190fd5b6109f8610cd9565b60048054604080516370a0823160e01b81523093810193909352516001600160a01b039091169163db006a759183916370a08231916024808301926020929190829003018186803b158015610a4c57600080fd5b505afa158015610a60573d6000803e3d6000fd5b505050506040513d6020811015610a7657600080fd5b5051604080516001600160e01b031960e085901b16815260048101929092525160248083019260209291908290030181600087803b158015610ab757600080fd5b505af1158015610acb573d6000803e3d6000fd5b505050506040513d6020811015610ae157600080fd5b505115610b25576040805162461bcd60e51b815260206004820152600d60248201526c14915111515348119052531151609a1b604482015290519081900360640190fd5b600354600054604080516370a0823160e01b815230600482015290516001600160a01b039384169363a9059cbb93169184916370a0823191602480820192602092909190829003018186803b158015610b7d57600080fd5b505afa158015610b91573d6000803e3d6000fd5b505050506040513d6020811015610ba757600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610bf857600080fd5b505af1158015610c0c573d6000803e3d6000fd5b505050506040513d6020811015610c2257600080fd5b50506008805461ff001916610100179055565b600082610c4457506000610c91565b82820282848281610c5157fe5b0414610c8e5760405162461bcd60e51b8152600401808060200182810382526021815260200180610f3e6021913960400191505060405180910390fd5b90505b92915050565b6000610c8e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610e9b565b6004546001600160a01b031663db006a75610cf2610240565b6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015610d2857600080fd5b505af1158015610d3c573d6000803e3d6000fd5b505050506040513d6020811015610d5257600080fd5b505115610d96576040805162461bcd60e51b815260206004820152600d60248201526c14915111515348119052531151609a1b604482015290519081900360640190fd5b600354600254604080516370a0823160e01b815230600482015290516001600160a01b039384169363a9059cbb93169184916370a0823191602480820192602092909190829003018186803b158015610dee57600080fd5b505afa158015610e02573d6000803e3d6000fd5b505050506040513d6020811015610e1857600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610e6957600080fd5b505af1158015610e7d573d6000803e3d6000fd5b505050506040513d6020811015610e9357600080fd5b505042600955565b60008183610f275760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610eec578181015183820152602001610ed4565b50505050905090810190601f168015610f195780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581610f3357fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a265627a7a723158209efc069b51c94b713f7081b4ac782854a8e1ecd8e08195a084597188cac498a864736f6c63430005100032

Verified Source Code Partial Match

Compiler: v0.5.16+commit.9c3226ce EVM: istanbul Optimization: Yes (200 runs)
XinvVester.sol 315 lines
pragma solidity ^0.5.16;

// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol
// Subject to the MIT license.

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, errorMessage);

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot underflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction underflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot underflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, errorMessage);

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers.
     * Reverts on division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers.
     * Reverts with custom message on division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

interface Ixinv {
    function mint(uint mintAmount) external returns (uint);
    function redeem(uint redeemTokens) external returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function syncDelegate(address user) external;
    function exchangeRateStored() external view returns (uint);
}

interface Iinv {
    function balanceOf(address account) external view returns (uint);
    function transfer(address dst, uint rawAmount) external returns (bool);
    function delegate(address delegatee) external;
    function approve(address spender, uint rawAmount) external returns (bool);
    function transferFrom(address src, address dst, uint rawAmount) external returns (bool);
}

contract XinvVesterFactory {

    address public governance;
    Iinv public inv;
    Ixinv public xinv;
    XinvVester[] public vesters;

    constructor (Ixinv _xinv, Iinv _inv, address _governance) public {
        governance = _governance;
        inv = _inv;
        xinv = _xinv;
    }

    function deployVester(address _recipient, uint _invAmount, uint _vestingStartTimestamp, uint _vestingDurationSeconds, bool _isCancellable) public {
        require(msg.sender == governance, "ONLY GOVERNANCE");
        XinvVester vester = new XinvVester(xinv, inv, governance, _recipient, _vestingStartTimestamp, _vestingDurationSeconds, _isCancellable);
        inv.transferFrom(governance, address(vester), _invAmount);
        vester.initialize();
        vesters.push(vester);
    }
}

// Should only be deployed via factory
// Assumes xINV withdrawal delay is permanently set to 0
contract XinvVester {
    using SafeMath for uint;

    address public governance;
    address public factory;
    address public recipient;
    Iinv public inv;
    Ixinv public xinv;

    uint public vestingXinvAmount;
    uint public vestingBegin;
    uint public vestingEnd;
    bool public isCancellable;
    bool public isCancelled;
    uint public lastUpdate;

    constructor(Ixinv _xinv, Iinv _inv, address _governance, address _recipient, uint _vestingStartTimestamp, uint _vestingDurationSeconds, bool _isCancellable) public {
        require(_vestingDurationSeconds > 0, "DURATION IS 0");
        inv = _inv;
        xinv = _xinv;
        vestingBegin = _vestingStartTimestamp;
        vestingEnd = vestingBegin + _vestingDurationSeconds;
        recipient = _recipient;
        isCancellable = _isCancellable;
        governance = _governance;
        factory = msg.sender;

        lastUpdate = _vestingStartTimestamp;

        inv.delegate(_recipient);
        xinv.syncDelegate(address(this));
    }

    function initialize() public {
        uint _invAmount = inv.balanceOf(address(this));
        require(_invAmount > 0, "INV AMOUNT IS 0");
        require(msg.sender == factory, "ONLY FACTORY");
        inv.approve(address(xinv), _invAmount);
        require(xinv.mint(_invAmount) == 0, "MINT FAILED");
        vestingXinvAmount = xinv.balanceOf(address(this));
    }

    function delegate(address delegate_) public {
        require(msg.sender == recipient, 'ONLY RECIPIENT');
        inv.delegate(delegate_);
        xinv.syncDelegate(address(this));
    }

    function setRecipient(address recipient_) public {
        require(msg.sender == recipient, 'ONLY RECIPIENT');
        recipient = recipient_;
    }

    function claimableXINV() public view returns (uint xinvAmount) {
        if (isCancelled) return 0;
        if (block.timestamp >= vestingEnd) {
            xinvAmount = xinv.balanceOf(address(this));
        } else {
            xinvAmount = vestingXinvAmount.mul(block.timestamp - lastUpdate).div(vestingEnd - vestingBegin);
        }
    }

    function claimableINV() public view returns (uint invAmount) {
        return claimableXINV().mul(xinv.exchangeRateStored()).div(1 ether);
    }

    function claim() public {
        require(msg.sender == recipient, "ONLY RECIPIENT");
        _claim();
    }

    function _claim() private {
        require(xinv.redeem(claimableXINV()) == 0, "REDEEM FAILED");
        inv.transfer(recipient, inv.balanceOf(address(this)));
        lastUpdate = block.timestamp;
    }

    function cancel() public {
        require(msg.sender == governance || msg.sender == recipient, "ONLY GOVERNANCE OR RECIPIENT");
        require(isCancellable || msg.sender == recipient, "NOT CANCELLABLE");
        require(!isCancelled, "ALREADY CANCELLED");
        _claim();
        require(xinv.redeem(xinv.balanceOf(address(this))) == 0, "REDEEM FAILED");
        inv.transfer(governance, inv.balanceOf(address(this)));
        isCancelled = true;
    }

}

Read Contract

claimableINV 0x746dd88d → uint256
claimableXINV 0x2b73429b → uint256
factory 0xc45a0155 → address
governance 0x5aa6e675 → address
inv 0x032d0961 → address
isCancellable 0x4500054f → bool
isCancelled 0x95ee1221 → bool
lastUpdate 0xc0463711 → uint256
recipient 0x66d003ac → address
vestingBegin 0xe29bc68b → uint256
vestingEnd 0x84a1931f → uint256
vestingXinvAmount 0x09c10d1d → uint256
xinv 0x90df22ed → address

Write Contract 5 functions

These functions modify contract state and require a wallet transaction to execute.

cancel 0xea8a1af0
No parameters
claim 0x4e71d92d
No parameters
delegate 0x5c19a95c
address delegate_
initialize 0x8129fc1c
No parameters
setRecipient 0x3bbed4a0
address recipient_

Recent Transactions

No transactions found for this address