Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xa7209Ca2D4A6a9b9f14e67b8013F2b72Fb42d729
Balance 0 ETH
Nonce 1
Code Size 2784 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

2784 bytes
0x608060405234801561001057600080fd5b50600436106100935760003560e01c8063715018a611610066578063715018a6146100ef5780638da5cb5b146100f7578063dd7bec531461011c578063eb82031214610143578063f2fde38b146101b457600080fd5b80631e83409a146100985780633c910d48146100ad57806361ab45ab146100c95780636c24a76f146100dc575b600080fd5b6100ab6100a636600461095e565b6101c7565b005b6100b660025481565b6040519081526020015b60405180910390f35b6100ab6100d7366004610978565b6103f9565b6100b66100ea36600461095e565b61074c565b6100ab610821565b6000546001600160a01b03165b6040516001600160a01b0390911681526020016100c0565b6101047f00000000000000000000000066761fa41377003622aee3c7675fc7b5c1c2fac581565b61018761015136600461095e565b60016020819052600091825260409091208054918101546002820154600383015460048401546005909401549293919290919086565b604080519687526020870195909552938501929092526060840152608083015260a082015260c0016100c0565b6100ab6101c236600461095e565b610857565b6001600160a01b0381166000908152600160205260409020600201544210156102375760405162461bcd60e51b815260206004820152601c60248201527f56657374696e673a3a636c61696d3a206e6f742074696d65207965740000000060448201526064015b60405180910390fd5b6001600160a01b0381166000908152600160205260409020546102a85760405162461bcd60e51b815260206004820152602360248201527f56657374696e673a3a636c61696d3a20726563697069656e74206e6f742076616044820152621b1a5960ea1b606482015260840161022e565b60006102b38261074c565b6001600160a01b0383166000908152600160205260408120426004820155600501805492935083929091906102e9908490610a26565b9250508190555080600260008282546103029190610a7d565b909155505060405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f00000000000000000000000066761fa41377003622aee3c7675fc7b5c1c2fac5169063a9059cbb90604401602060405180830381600087803b15801561037157600080fd5b505af1158015610385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a991906109b9565b6103f55760405162461bcd60e51b815260206004820152601e60248201527f56657374696e673a3a636c61696d3a207472616e73666572206572726f720000604482015260640161022e565b5050565b6000546001600160a01b031633146104235760405162461bcd60e51b815260040161022e906109f1565b428310156104885760405162461bcd60e51b815260206004820152602c60248201527f56657374696e673a3a686f6c64546f6b656e733a2076657374696e672062656760448201526b696e20746f6f206561726c7960a01b606482015260840161022e565b8181116104e55760405162461bcd60e51b815260206004820152602560248201527f56657374696e673a3a686f6c64546f6b656e733a20656e6420697320746f6f206044820152646561726c7960d81b606482015260840161022e565b828210156105455760405162461bcd60e51b815260206004820152602760248201527f56657374696e673a3a686f6c64546f6b656e733a20636c69666620697320746f6044820152666f206561726c7960c81b606482015260840161022e565b6040516370a0823160e01b81523060048201527f00000000000000000000000066761fa41377003622aee3c7675fc7b5c1c2fac56001600160a01b0316906370a082319060240160206040518083038186803b1580156105a457600080fd5b505afa1580156105b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dc91906109d9565b846002546105ea9190610a26565b11156106445760405162461bcd60e51b815260206004820152602360248201527f56657374696e673a3a686f6c64546f6b656e733a206e6f74456e6f75676846756044820152626e647360e81b606482015260840161022e565b6001600160a01b038516600090815260016020526040902054156106c55760405162461bcd60e51b815260206004820152603260248201527f56657374696e673a3a686f6c64546f6b656e733a20726563697069656e74206160448201527106c72656164792068617665206c6f636b75760741b606482015260840161022e565b83600260008282546106d79190610a26565b90915550506040805160c08101825294855260208086018581528683019485526060870193845260808701958652600060a088018181526001600160a01b0390991681526001928390529290922095518655905190850155905160028401555160038301555160048201559051600590910155565b6001600160a01b0381166000908152600160208181526040808420815160c0810183528154815293810154928401929092526002820154908301819052600382015460608401526004820154608084015260059091015460a083015282904210156107bb575060009392505050565b816060015142106107de5760a082015182516107d79190610a7d565b905061081a565b816020015182606001516107f29190610a7d565b60808301516108019042610a7d565b835161080d9190610a5e565b6108179190610a3e565b90505b9392505050565b6000546001600160a01b0316331461084b5760405162461bcd60e51b815260040161022e906109f1565b61085560006108f2565b565b6000546001600160a01b031633146108815760405162461bcd60e51b815260040161022e906109f1565b6001600160a01b0381166108e65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161022e565b6108ef816108f2565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356001600160a01b038116811461095957600080fd5b919050565b60006020828403121561096f578081fd5b61081a82610942565b600080600080600060a0868803121561098f578081fd5b61099886610942565b97602087013597506040870135966060810135965060800135945092505050565b6000602082840312156109ca578081fd5b8151801515811461081a578182fd5b6000602082840312156109ea578081fd5b5051919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115610a3957610a39610a94565b500190565b600082610a5957634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615610a7857610a78610a94565b500290565b600082821015610a8f57610a8f610a94565b500390565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220178e33b7b787c9e7dbe5f51e1d53a74c66ea7b4b63d3cb42fcbd5d664e49996464736f6c63430008040033

Verified Source Code Full Match

Compiler: v0.8.4+commit.c7e474f2 EVM: istanbul Optimization: Yes (200 runs)
Vesting.sol 81 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";


contract Vesting is Ownable {
    IERC20 public immutable CPOOL;

    struct VestingParams {
        uint amount;
        uint vestingBegin;
        uint vestingCliff;
        uint vestingEnd;
        uint lastUpdate;
        uint claimed;
    }

    mapping (address => VestingParams) public recipients;
    uint public totalVest;

    constructor(address tokenAddress) {
        CPOOL = IERC20(tokenAddress);
    }


    function holdTokens(
        address recipient_,
        uint amount_,
        uint vestingBegin_,
        uint vestingCliff_,
        uint vestingEnd_
    )
        onlyOwner
        external
    {
        require(vestingBegin_ >= block.timestamp, 'Vesting::holdTokens: vesting begin too early');
        require(vestingEnd_ > vestingCliff_, 'Vesting::holdTokens: end is too early');
        require(vestingCliff_ >= vestingBegin_, 'Vesting::holdTokens: cliff is too early');
        require(totalVest + amount_ <= CPOOL.balanceOf(address(this)), 'Vesting::holdTokens: notEnoughFunds');
        require(recipients[recipient_].amount == 0, 'Vesting::holdTokens: recipient already have lockup');

        totalVest += amount_;
        recipients[recipient_] = VestingParams({
            amount: amount_,
            vestingBegin: vestingBegin_,
            vestingCliff: vestingCliff_,
            vestingEnd: vestingEnd_,
            lastUpdate: vestingBegin_,
            claimed: 0
        });
    }

    function claim(address recipient_) external {
        require(block.timestamp >= recipients[recipient_].vestingCliff, 'Vesting::claim: not time yet');
        require(recipients[recipient_].amount > 0, 'Vesting::claim: recipient not valid');

        uint amount = getAvailableBalance(recipient_);
        recipients[recipient_].lastUpdate = block.timestamp;
        recipients[recipient_].claimed += amount;
        totalVest -= amount;
        require(IERC20(CPOOL).transfer(recipient_, amount), 'Vesting::claim: transfer error');
    }

    function getAvailableBalance(address recipient_) public view returns(uint) {
        VestingParams memory vestParams = recipients[recipient_];
        uint amount;
        if (block.timestamp < vestParams.vestingCliff) {
            return 0;
        }
        if (block.timestamp >= vestParams.vestingEnd) {
            amount = vestParams.amount - vestParams.claimed;
        } else {
            amount = vestParams.amount * (block.timestamp - vestParams.lastUpdate) / (vestParams.vestingEnd - vestParams.vestingBegin);
        }
        return amount;
    }
}

Context.sol 23 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
Ownable.sol 71 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
IERC20.sol 81 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

Read Contract

CPOOL 0xdd7bec53 → address
getAvailableBalance 0x6c24a76f → uint256
owner 0x8da5cb5b → address
recipients 0xeb820312 → uint256, uint256, uint256, uint256, uint256, uint256
totalVest 0x3c910d48 → uint256

Write Contract 4 functions

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

claim 0x1e83409a
address recipient_
holdTokens 0x61ab45ab
address recipient_
uint256 amount_
uint256 vestingBegin_
uint256 vestingCliff_
uint256 vestingEnd_
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

No transactions found for this address