Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xE5aC5142BdE69cfA722662D9C3E4C8111f60B8d5
Balance 0 ETH
Nonce 1
Code Size 4237 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

4237 bytes
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063681a992111610071578063681a9921146101a157806395025926146101b45780639ae697bf146101f3578063a0821be314610206578063b5609be414610219578063bbe4fd501461022157600080fd5b80632eb4a7ab146100b957806334354068146100f3578063374e0241146100fc57806346c81436146101115780635e192de61461012457806361dcd7ab1461017a575b600080fd5b6100e07f208f34053f93e6e263cbc7ed2a289b6607ec98dd67d4163ec3011a5d768c68e581565b6040519081526020015b60405180910390f35b6100e060005481565b61010f61010a366004610cba565b610227565b005b61010f61011f366004610dba565b61037a565b61015a610132366004610e40565b6001602081905260009182526040909120805491810154600282015460039092015490919084565b6040805194855260208501939093529183015260608201526080016100ea565b6100e07f00000000000000000000000000000000000000000000000000000000638fd9a781565b61010f6101af366004610e62565b6103cc565b6101db7f000000000000000000000000249ca82617ec3dfb2589c4c17ab7ec9765350a1881565b6040516001600160a01b0390911681526020016100ea565b6100e0610201366004610e40565b610416565b6100e0610214366004610e40565b61049a565b61010f61057b565b426100e0565b600a89106102755760405162461bcd60e51b81526020600482015260166024820152755665727365436c61696d65723a20544f4f5f4d414e5960501b60448201526064015b60405180910390fd5b60005b8981101561036c5761035a61028d828e610ef3565b8c8c8481811061029f5761029f610f0c565b90506020020160208101906102b49190610e40565b8b8b858181106102c6576102c6610f0c565b905060200201358a8a868181106102df576102df610f0c565b905060200201358989878181106102f8576102f8610f0c565b9050602002013588888881811061031157610311610f0c565b90506020028101906103239190610f22565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061058692505050565b8061036481610f6c565b915050610278565b505050505050505050505050565b6103bb863387878787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061058692505050565b6103c4336106d5565b505050505050565b61040d878787878787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061058692505050565b50505050505050565b6001600160a01b03811660009081526001602081905260408220015442908290821061044357600061046b565b6001600160a01b0384166000908152600160208190526040909120015461046b908390610f85565b6001600160a01b038516600090815260016020526040902054909150610492908290610f98565b949350505050565b6001600160a01b03811660009081526001602081905260408220015442908083036104c9575060009392505050565b6000818311610501576104fc7f00000000000000000000000000000000000000000000000000000000638fd9a784610f85565b61052b565b61052b7f00000000000000000000000000000000000000000000000000000000638fd9a783610f85565b6001600160a01b03861660009081526001602052604090206003810154600282015491549293509161055e908490610f98565b6105689190610ef3565b6105729190610f85565b95945050505050565b610584336106d5565b565b6001600160a01b03851660009081526001602081905260409091200154156106015760405162461bcd60e51b815260206004820152602860248201527f5665727365436c61696d65723a20524543495049454e545f414c52454144595f60448201526711539493d313115160c21b606482015260840161026c565b604080516020808201899052606088901b6bffffffffffffffffffffffff191682840152605482018790526074820186905260948083018690528351808403909101815260b4909201909252805191012061067d827f208f34053f93e6e263cbc7ed2a289b6607ec98dd67d4163ec3011a5d768c68e583610766565b6106c95760405162461bcd60e51b815260206004820152601b60248201527f5665727365436c61696d65723a20494e56414c49445f50524f4f460000000000604482015260640161026c565b61040d86868686610815565b60006106e08261049a565b6001600160a01b038316600090815260016020526040812060030180549293508392909190610710908490610ef3565b909155506107209050828261099b565b6040805182815242602082015281516001600160a01b038516927ff4c6297f72d4e746c679dde16c732ea9af03893c22fe2ca98037465dd6a3bb2b928290030190a25050565b600081815b855181101561080a57600086828151811061078857610788610f0c565b60200260200101519050808311156107c9576040805160208101839052908101849052606001604051602081830303815290604052805190602001206107f4565b6040805160208101859052908101829052606001604051602081830303815290604052805190602001205b925050808061080290610f6c565b91505061076b565b509092149392505050565b7f0000000000000000000000000000000000000000000000000000000001e16a308110156108855760405162461bcd60e51b815260206004820181905260248201527f5665727365436c61696d65723a20494e56414c49445f54494d455f4652414d45604482015260640161026c565b82826000546108949190610ef3565b61089e9190610ef3565b6000556108cb817f00000000000000000000000000000000000000000000000000000000638fd9a7610ef3565b6001600160a01b038516600090815260016020819052604090912001556108f28184610fc5565b6001600160a01b038516600090815260016020526040902055816109168285610fd9565b6109209190610ef3565b6001600160a01b0385166000908152600160205260408120600201919091555461094990610b12565b60408051828152602081018590529081018390526001600160a01b038516907f8ceefb1ee30c963bc99d8216add67b76190bb2d0403a4e8f0e321ae3e41d7fbe9060600160405180910390a250505050565b806000808282546109ac9190610f85565b9091555050604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b179052915160009283927f000000000000000000000000249ca82617ec3dfb2589c4c17ab7ec9765350a181691610a5d9190610fed565b6000604051808303816000865af19150503d8060008114610a9a576040519150601f19603f3d011682016040523d82523d6000602084013e610a9f565b606091505b5091509150818015610ac0575080806020019051810190610ac0919061101c565b610b0c5760405162461bcd60e51b815260206004820152601c60248201527f566572736548656c7065723a205452414e534645525f4641494c454400000000604482015260640161026c565b50505050565b604080518082018252601281527162616c616e63654f6628616464726573732960701b602091820152815130602480830191909152835180830390910181526044909101835290810180516001600160e01b03166370a0823160e01b179052905160009182917f000000000000000000000000249ca82617ec3dfb2589c4c17ab7ec9765350a186001600160a01b031691610bac91610fed565b6000604051808303816000865af19150503d8060008114610be9576040519150601f19603f3d011682016040523d82523d6000602084013e610bee565b606091505b5091509150818015610c1357508281806020019051810190610c10919061103e565b10155b610c695760405162461bcd60e51b815260206004820152602160248201527f566572736548656c7065723a2042414c414e43455f434845434b5f4641494c456044820152601160fa1b606482015260840161026c565b505050565b60008083601f840112610c8057600080fd5b50813567ffffffffffffffff811115610c9857600080fd5b6020830191508360208260051b8501011115610cb357600080fd5b9250929050565b600080600080600080600080600080600060c08c8e031215610cdb57600080fd5b8b359a5067ffffffffffffffff8060208e01351115610cf957600080fd5b610d098e60208f01358f01610c6e565b909b50995060408d0135811015610d1f57600080fd5b610d2f8e60408f01358f01610c6e565b909950975060608d0135811015610d4557600080fd5b610d558e60608f01358f01610c6e565b909750955060808d0135811015610d6b57600080fd5b610d7b8e60808f01358f01610c6e565b909550935060a08d0135811015610d9157600080fd5b50610da28d60a08e01358e01610c6e565b81935080925050509295989b509295989b9093969950565b60008060008060008060a08789031215610dd357600080fd5b86359550602087013594506040870135935060608701359250608087013567ffffffffffffffff811115610e0657600080fd5b610e1289828a01610c6e565b979a9699509497509295939492505050565b80356001600160a01b0381168114610e3b57600080fd5b919050565b600060208284031215610e5257600080fd5b610e5b82610e24565b9392505050565b600080600080600080600060c0888a031215610e7d57600080fd5b87359650610e8d60208901610e24565b955060408801359450606088013593506080880135925060a088013567ffffffffffffffff811115610ebe57600080fd5b610eca8a828b01610c6e565b989b979a50959850939692959293505050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610f0657610f06610edd565b92915050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112610f3957600080fd5b83018035915067ffffffffffffffff821115610f5457600080fd5b6020019150600581901b3603821315610cb357600080fd5b600060018201610f7e57610f7e610edd565b5060010190565b81810381811115610f0657610f06610edd565b8082028115828204841417610f0657610f06610edd565b634e487b7160e01b600052601260045260246000fd5b600082610fd457610fd4610faf565b500490565b600082610fe857610fe8610faf565b500690565b6000825160005b8181101561100e5760208186018101518583015201610ff4565b506000920191825250919050565b60006020828403121561102e57600080fd5b81518015158114610e5b57600080fd5b60006020828403121561105057600080fd5b505191905056fea26469706673582212204954ce87625480e8867f55b5adc0d4f8031ef2e6976573c38b677338be82cdca64736f6c63430008110033

Verified Source Code Full Match

Compiler: v0.8.17+commit.8df45f5f EVM: london Optimization: Yes (200 runs)
MerkleProof.sol 29 lines
// SPDX-License-Identifier: --BCOM--

pragma solidity =0.8.17;

library MerkleProof {

    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    )
        internal
        pure
        returns (bool)
    {
        bytes32 computedHash = leaf;

        for (uint256 i = 0; i < proof.length; i++) {

            bytes32 proofElement = proof[i];

            computedHash = computedHash <= proofElement
                ? keccak256(abi.encodePacked(computedHash, proofElement))
                : keccak256(abi.encodePacked(proofElement, computedHash));
        }

        return computedHash == root;
    }
}
VerseHelper.sol 102 lines
// SPDX-License-Identifier: --BCOM--

pragma solidity =0.8.17;

contract VerseHelper {

    uint256 public totalRequired;
    address public immutable verseToken;

    event recipientEnrolled(
        address indexed recipient,
        uint256 timeFrame,
        uint256 tokensLocked,
        uint256 tokensOpened
    );

    event tokensScraped(
        address indexed scraper,
        uint256 scrapedAmount,
        uint256 timestamp
    );

    constructor(
        address _verseTokenAddress
    ) {
        if (_verseTokenAddress == address(0x0)) {
            revert("VerseHelper: INVALID_VERSE_TOKEN");
        }

        verseToken = _verseTokenAddress;
    }

    bytes4 private constant TRANSFER = bytes4(
        keccak256(
            bytes(
                "transfer(address,uint256)"
            )
        )
    );

    bytes4 private constant BALANCEOF = bytes4(
        keccak256(
            bytes(
                "balanceOf(address)"
            )
        )
    );

    function _safeVerseScrape(
        address _to,
        uint256 _scrapeAmount
    )
        internal
    {
        totalRequired -= _scrapeAmount;

        (bool success, bytes memory data) = verseToken.call(
            abi.encodeWithSelector(
                TRANSFER,
                _to,
                _scrapeAmount
            )
        );

        require(
            success && (
                abi.decode(
                    data, (bool)
                )
            ),
            "VerseHelper: TRANSFER_FAILED"
        );
    }

    function _checkVerseBalance(
        uint256 _required
    )
        internal
    {
        (bool success, bytes memory data) = verseToken.call(
            abi.encodeWithSelector(
                BALANCEOF,
                address(this)
            )
        );

        require(
            success && abi.decode(
                data, (uint256)
            ) >= _required,
            "VerseHelper: BALANCE_CHECK_FAILED"
        );
    }

    function getNow()
        public
        view
        returns (uint256 time)
    {
        time = block.timestamp;
    }
}
VerseClaimer.sol 266 lines
// SPDX-License-Identifier: --BCOM--

pragma solidity =0.8.17;

import "./MerkleProof.sol";
import "./VerseHelper.sol";

contract VerseClaimer is VerseHelper {

    bytes32 public immutable merkleRoot;
    uint256 public immutable createTime;

    uint256 immutable minimumTimeFrame;

    struct KeeperInfo {
        uint256 keeperRate;
        uint256 keeperTill;
        uint256 keeperInstant;
        uint256 keeperPayouts;
    }

    mapping(address => KeeperInfo) public keeperList;

    constructor(
        bytes32 _merkleRoot,
        uint256 _minimumTimeFrame,
        address _verseTokenAddress
    )
        VerseHelper(_verseTokenAddress)
    {
        require(
            _minimumTimeFrame > 0,
            "VerseClaimer: INVALID_TIMEFRAME"
        );

        require(
            _merkleRoot > 0,
            "VerseClaimer: INVALID_MERKLE_ROOT"
        );

        createTime = getNow();
        merkleRoot = _merkleRoot;
        minimumTimeFrame = _minimumTimeFrame;
    }

    function enrollRecipient(
        uint256 _index,
        address _recipient,
        uint256 _tokensLocked,
        uint256 _tokensOpened,
        uint256 _timeFrame,
        bytes32[] calldata _merkleProof
    )
        external
    {
        _enrollRecipient(
            _index,
            _recipient,
            _tokensLocked,
            _tokensOpened,
            _timeFrame,
            _merkleProof
        );
    }

    function enrollRecipientBulk(
        uint256 _index,
        address[] calldata _recipient,
        uint256[] calldata _tokensLocked,
        uint256[] calldata _tokensOpened,
        uint256[] calldata _timeFrame,
        bytes32[][] calldata _merkleProof
    )
        external
    {
        require(
            _recipient.length < 10,
            "VerseClaimer: TOO_MANY"
        );

        for (uint256 i = 0; i < _recipient.length; i++) {
            _enrollRecipient(
                _index + i,
                _recipient[i],
                _tokensLocked[i],
                _tokensOpened[i],
                _timeFrame[i],
                _merkleProof[i]
            );
        }
    }

    function _enrollRecipient(
        uint256 _index,
        address _recipient,
        uint256 _tokensLocked,
        uint256 _tokensOpened,
        uint256 _timeFrame,
        bytes32[] memory _merkleProof
    )
        private
    {
        require(
            keeperList[_recipient].keeperTill == 0,
            "VerseClaimer: RECIPIENT_ALREADY_ENROLLED"
        );

        bytes32 node = keccak256(
            abi.encodePacked(
                _index,
                _recipient,
                _tokensLocked,
                _tokensOpened,
                _timeFrame
            )
        );

        require(
            MerkleProof.verify(
                _merkleProof,
                merkleRoot,
                node
            ),
            "VerseClaimer: INVALID_PROOF"
        );

        _allocateTokens(
            _recipient,
            _tokensLocked,
            _tokensOpened,
            _timeFrame
        );
    }

    function _allocateTokens(
        address _recipient,
        uint256 _tokensLocked,
        uint256 _tokensOpened,
        uint256 _timeFrame
    )
        private
    {
        require(
            _timeFrame >= minimumTimeFrame,
            "VerseClaimer: INVALID_TIME_FRAME"
        );

        totalRequired = totalRequired
            + _tokensOpened
            + _tokensLocked;

        keeperList[_recipient].keeperTill = createTime
            + _timeFrame;

        keeperList[_recipient].keeperRate = _tokensLocked
            / _timeFrame;

        keeperList[_recipient].keeperInstant = _tokensLocked
            % _timeFrame
            + _tokensOpened;

        _checkVerseBalance(
            totalRequired
        );

        emit recipientEnrolled(
            _recipient,
            _timeFrame,
            _tokensLocked,
            _tokensOpened
        );
    }

    function enrollAndScrape(
        uint256 _index,
        uint256 _tokensLocked,
        uint256 _tokensOpened,
        uint256 _timeFrame,
        bytes32[] calldata _merkleProof
    )
        external
    {
        _enrollRecipient(
            _index,
            msg.sender,
            _tokensLocked,
            _tokensOpened,
            _timeFrame,
            _merkleProof
        );

        _scrapeTokens(
            msg.sender
        );
    }

    function scrapeMyTokens()
        external
    {
        _scrapeTokens(
            msg.sender
        );
    }

    function _scrapeTokens(
        address _recipient
    )
        private
    {
        uint256 scrapeAmount = availableBalance(
            _recipient
        );

        keeperList[_recipient].keeperPayouts += scrapeAmount;

        _safeVerseScrape(
            _recipient,
            scrapeAmount
        );

        emit tokensScraped(
            _recipient,
            scrapeAmount,
            getNow()
        );
    }

    function availableBalance(
        address _recipient
    )
        public
        view
        returns (uint256 balance)
    {
        uint256 timeNow = getNow();
        uint256 timeMax = keeperList[_recipient].keeperTill;

        if (timeMax == 0) return 0;

        uint256 timePassed = timeNow > timeMax
            ? timeMax - createTime
            : timeNow - createTime;

        balance = keeperList[_recipient].keeperRate
            * timePassed
            + keeperList[_recipient].keeperInstant
            - keeperList[_recipient].keeperPayouts;
    }

    function lockedBalance(
        address _recipient
    )
        external
        view
        returns (uint256 balance)
    {
        uint256 timeNow = getNow();

        uint256 timeRemaining =
            keeperList[_recipient].keeperTill > timeNow ?
            keeperList[_recipient].keeperTill - timeNow : 0;

        balance = keeperList[_recipient].keeperRate
            * timeRemaining;
    }
}

Read Contract

availableBalance 0xa0821be3 → uint256
createTime 0x61dcd7ab → uint256
getNow 0xbbe4fd50 → uint256
keeperList 0x5e192de6 → uint256, uint256, uint256, uint256
lockedBalance 0x9ae697bf → uint256
merkleRoot 0x2eb4a7ab → bytes32
totalRequired 0x34354068 → uint256
verseToken 0x95025926 → address

Write Contract 4 functions

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

enrollAndScrape 0x46c81436
uint256 _index
uint256 _tokensLocked
uint256 _tokensOpened
uint256 _timeFrame
bytes32[] _merkleProof
enrollRecipient 0x681a9921
uint256 _index
address _recipient
uint256 _tokensLocked
uint256 _tokensOpened
uint256 _timeFrame
bytes32[] _merkleProof
enrollRecipientBulk 0x374e0241
uint256 _index
address[] _recipient
uint256[] _tokensLocked
uint256[] _tokensOpened
uint256[] _timeFrame
bytes32[][] _merkleProof
scrapeMyTokens 0xb5609be4
No parameters

Recent Transactions

No transactions found for this address