POL Price: $0.324822 (+5.31%)
Gas: 25 GWei
 

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Release676760252025-02-08 7:20:323 days ago1738999232IN
0xe774b60A...818020f8E
0 POL0.0039315435.10372196
Release676460692025-02-07 12:49:323 days ago1738932572IN
0xe774b60A...818020f8E
0 POL0.00995431104.92146815
Release676232562025-02-06 22:41:484 days ago1738881708IN
0xe774b60A...818020f8E
0 POL0.0028462230.00000004
Release675016012025-02-03 20:49:537 days ago1738615793IN
0xe774b60A...818020f8E
0 POL0.01033471108.9309912
Release674570642025-02-02 17:42:068 days ago1738518126IN
0xe774b60A...818020f8E
0 POL0.05890732620.9005851
Release674256752025-02-01 23:04:199 days ago1738451059IN
0xe774b60A...818020f8E
0 POL0.002847330.00000008
Release674109062025-02-01 14:18:189 days ago1738419498IN
0xe774b60A...818020f8E
0 POL0.0038783830.05057563
Release672931032025-01-29 15:31:0912 days ago1738164669IN
0xe774b60A...818020f8E
0 POL0.0028465330.00327587
Release672420452025-01-28 9:03:3014 days ago1738055010IN
0xe774b60A...818020f8E
0 POL0.0040319236.00000001
Release672367072025-01-28 5:54:1614 days ago1738043656IN
0xe774b60A...818020f8E
0 POL0.0033599430.00000002
Release672117312025-01-27 15:05:4114 days ago1737990341IN
0xe774b60A...818020f8E
0 POL0.0102707108.24257332
Release671767082025-01-26 18:10:4115 days ago1737915041IN
0xe774b60A...818020f8E
0 POL0.0028462230.00000214
Release670123422025-01-22 15:50:2319 days ago1737561023IN
0xe774b60A...818020f8E
0 POL0.01007907106.23638431
Release670079092025-01-22 13:13:2219 days ago1737551602IN
0xe774b60A...818020f8E
0 POL0.01245802111.23431121
Release669807242025-01-21 20:52:5620 days ago1737492776IN
0xe774b60A...818020f8E
0 POL0.01002446105.64747885
Release668417362025-01-18 8:18:2124 days ago1737188301IN
0xe774b60A...818020f8E
0 POL0.01735082182.83653376
Release668185302025-01-17 18:32:5424 days ago1737138774IN
0xe774b60A...818020f8E
0 POL0.0108190596.60043912
Release668000332025-01-17 7:22:5825 days ago1737098578IN
0xe774b60A...818020f8E
0 POL0.0059606753.221301
Release667638092025-01-16 9:45:3425 days ago1737020734IN
0xe774b60A...818020f8E
0 POL0.0029028130.59650181
Release665734172025-01-11 15:01:1830 days ago1736607678IN
0xe774b60A...818020f8E
0 POL0.0100427489.66897442
Release664873972025-01-09 11:18:3732 days ago1736421517IN
0xe774b60A...818020f8E
0 POL0.005026152.97665112
Release664575322025-01-08 17:16:4933 days ago1736356609IN
0xe774b60A...818020f8E
0 POL0.02431478256.22017945
Release663736812025-01-06 13:55:4435 days ago1736171744IN
0xe774b60A...818020f8E
0 POL0.0084930689.51941574
Release662219472025-01-02 15:10:5039 days ago1735830650IN
0xe774b60A...818020f8E
0 POL0.0088070892.81751956
Release662120222025-01-02 8:56:5440 days ago1735808214IN
0xe774b60A...818020f8E
0 POL0.0034418730.73158384
View all transactions

Latest 1 internal transaction

Parent Transaction Hash Block From To
574541232024-05-27 14:50:22259 days ago1716821422  Contract Creation0 POL
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TokenVesting

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 5 : TokenVesting.sol
// contracts/TokenVesting.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;

// OpenZeppelin dependencies
import {ERC20} from "solmate/src/tokens/ERC20.sol";
import {Owned} from "solmate/src/auth/Owned.sol";
import {SafeTransferLib} from "solmate/src/utils/SafeTransferLib.sol";
import {ReentrancyGuard} from "solmate/src/utils/ReentrancyGuard.sol";

/**
 * @title TokenVesting
 */
contract TokenVesting is Owned, ReentrancyGuard {
    struct VestingSchedule {
        // beneficiary of tokens after they are released
        address beneficiary;
        // cliff time of the vesting start in seconds since the UNIX epoch
        uint256 cliff;
        // start time of the vesting period in seconds since the UNIX epoch
        uint256 start;
        // duration of the vesting period in seconds
        uint256 duration;
        // duration of a slice period for the vesting in seconds
        uint256 slicePeriodSeconds;
        // whether or not the vesting is revocable
        bool revocable;
        // total amount of tokens to be released at the end of the vesting
        uint256 amountTotal;
        // amount of tokens released
        uint256 released;
        // whether or not the vesting has been revoked
        bool revoked;
    }

    // address of the ERC20 token
    ERC20 private immutable _token;

    bytes32[] private vestingSchedulesIds;
    mapping(bytes32 => VestingSchedule) private vestingSchedules;
    uint256 private vestingSchedulesTotalAmount;
    mapping(address => uint256) private holdersVestingCount;

    /**
     * @dev Reverts if the vesting schedule does not exist or has been revoked.
     */
    modifier onlyIfVestingScheduleNotRevoked(bytes32 vestingScheduleId) {
        require(!vestingSchedules[vestingScheduleId].revoked);
        _;
    }

    /**
     * @dev Creates a vesting contract.
     * @param token_ address of the ERC20 token contract
     */
    constructor(address token_) Owned(msg.sender) {
        // Check that the token address is not 0x0.
        require(token_ != address(0x0));
        // Set the token address.
        _token = ERC20(token_);
    }

    /**
     * @dev This function is called for plain Ether transfers, i.e. for every call with empty calldata.
     */
    receive() external payable {}

    /**
     * @dev Fallback function is executed if none of the other functions match the function
     * identifier or no data was provided with the function call.
     */
    fallback() external payable {}

    /**
     * @notice Creates a new vesting schedule for a beneficiary.
     * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
     * @param _start start time of the vesting period
     * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
     * @param _duration duration in seconds of the period in which the tokens will vest
     * @param _slicePeriodSeconds duration of a slice period for the vesting in seconds
     * @param _revocable whether the vesting is revocable or not
     * @param _amount total amount of tokens to be released at the end of the vesting
     */
    function createVestingSchedule(
        address _beneficiary,
        uint256 _start,
        uint256 _cliff,
        uint256 _duration,
        uint256 _slicePeriodSeconds,
        bool _revocable,
        uint256 _amount
    ) external onlyOwner {
        require(
            getWithdrawableAmount() >= _amount,
            "TokenVesting: cannot create vesting schedule because not sufficient tokens"
        );
        require(_duration > 0, "TokenVesting: duration must be > 0");
        require(_amount > 0, "TokenVesting: amount must be > 0");
        require(_slicePeriodSeconds >= 1, "TokenVesting: slicePeriodSeconds must be >= 1");
        require(_duration >= _cliff, "TokenVesting: duration must be >= cliff");
        bytes32 vestingScheduleId = computeNextVestingScheduleIdForHolder(_beneficiary);
        uint256 cliff = _start + _cliff;
        vestingSchedules[vestingScheduleId] = VestingSchedule(
            _beneficiary,
            cliff,
            _start,
            _duration,
            _slicePeriodSeconds,
            _revocable,
            _amount,
            0,
            false
        );
        vestingSchedulesTotalAmount = vestingSchedulesTotalAmount + _amount;
        vestingSchedulesIds.push(vestingScheduleId);
        uint256 currentVestingCount = holdersVestingCount[_beneficiary];
        holdersVestingCount[_beneficiary] = currentVestingCount + 1;
    }

    /**
     * @notice Revokes the vesting schedule for given identifier.
     * @param vestingScheduleId the vesting schedule identifier
     */
    function revoke(
        bytes32 vestingScheduleId
    ) external onlyOwner onlyIfVestingScheduleNotRevoked(vestingScheduleId) {
        VestingSchedule storage vestingSchedule = vestingSchedules[vestingScheduleId];
        require(vestingSchedule.revocable, "TokenVesting: vesting is not revocable");
        uint256 vestedAmount = _computeReleasableAmount(vestingSchedule);
        if (vestedAmount > 0) {
            release(vestingScheduleId, vestedAmount);
        }
        uint256 unreleased = vestingSchedule.amountTotal - vestingSchedule.released;
        vestingSchedulesTotalAmount = vestingSchedulesTotalAmount - unreleased;
        vestingSchedule.revoked = true;
    }

    /**
     * @notice Withdraw the specified amount if possible.
     * @param amount the amount to withdraw
     */
    function withdraw(uint256 amount) external nonReentrant onlyOwner {
        require(getWithdrawableAmount() >= amount, "TokenVesting: not enough withdrawable funds");
        /*
         * @dev Replaced owner() with msg.sender => address of WITHDRAWER_ROLE
         */
        SafeTransferLib.safeTransfer(_token, msg.sender, amount);
    }

    /**
     * @notice Release vested amount of tokens.
     * @param vestingScheduleId the vesting schedule identifier
     * @param amount the amount to release
     */
    function release(
        bytes32 vestingScheduleId,
        uint256 amount
    ) public nonReentrant onlyIfVestingScheduleNotRevoked(vestingScheduleId) {
        VestingSchedule storage vestingSchedule = vestingSchedules[vestingScheduleId];
        bool isBeneficiary = msg.sender == vestingSchedule.beneficiary;

        bool isReleasor = (msg.sender == owner);
        require(
            isBeneficiary || isReleasor,
            "TokenVesting: only beneficiary and owner can release vested tokens"
        );
        uint256 vestedAmount = _computeReleasableAmount(vestingSchedule);
        require(
            vestedAmount >= amount,
            "TokenVesting: cannot release tokens, not enough vested tokens"
        );
        vestingSchedule.released = vestingSchedule.released + amount;
        address payable beneficiaryPayable = payable(vestingSchedule.beneficiary);
        vestingSchedulesTotalAmount = vestingSchedulesTotalAmount - amount;
        SafeTransferLib.safeTransfer(_token, beneficiaryPayable, amount);
    }

    /**
     * @dev Returns the number of vesting schedules associated to a beneficiary.
     * @return the number of vesting schedules
     */
    function getVestingSchedulesCountByBeneficiary(
        address _beneficiary
    ) external view returns (uint256) {
        return holdersVestingCount[_beneficiary];
    }

    /**
     * @dev Returns the vesting schedule id at the given index.
     * @return the vesting id
     */
    function getVestingIdAtIndex(uint256 index) external view returns (bytes32) {
        require(index < getVestingSchedulesCount(), "TokenVesting: index out of bounds");
        return vestingSchedulesIds[index];
    }

    /**
     * @notice Returns the vesting schedule information for a given holder and index.
     * @return the vesting schedule structure information
     */
    function getVestingScheduleByAddressAndIndex(
        address holder,
        uint256 index
    ) external view returns (VestingSchedule memory) {
        return getVestingSchedule(computeVestingScheduleIdForAddressAndIndex(holder, index));
    }

    /**
     * @notice Returns the total amount of vesting schedules.
     * @return the total amount of vesting schedules
     */
    function getVestingSchedulesTotalAmount() external view returns (uint256) {
        return vestingSchedulesTotalAmount;
    }

    /**
     * @dev Returns the address of the ERC20 token managed by the vesting contract.
     */
    function getToken() external view returns (address) {
        return address(_token);
    }

    /**
     * @dev Returns the number of vesting schedules managed by this contract.
     * @return the number of vesting schedules
     */
    function getVestingSchedulesCount() public view returns (uint256) {
        return vestingSchedulesIds.length;
    }

    /**
     * @notice Computes the vested amount of tokens for the given vesting schedule identifier.
     * @return the vested amount
     */
    function computeReleasableAmount(
        bytes32 vestingScheduleId
    ) external view onlyIfVestingScheduleNotRevoked(vestingScheduleId) returns (uint256) {
        VestingSchedule storage vestingSchedule = vestingSchedules[vestingScheduleId];
        return _computeReleasableAmount(vestingSchedule);
    }

    /**
     * @notice Returns the vesting schedule information for a given identifier.
     * @return the vesting schedule structure information
     */
    function getVestingSchedule(
        bytes32 vestingScheduleId
    ) public view returns (VestingSchedule memory) {
        return vestingSchedules[vestingScheduleId];
    }

    /**
     * @dev Returns the amount of tokens that can be withdrawn by the owner.
     * @return the amount of tokens
     */
    function getWithdrawableAmount() public view returns (uint256) {
        return _token.balanceOf(address(this)) - vestingSchedulesTotalAmount;
    }

    /**
     * @dev Computes the next vesting schedule identifier for a given holder address.
     */
    function computeNextVestingScheduleIdForHolder(address holder) public view returns (bytes32) {
        return computeVestingScheduleIdForAddressAndIndex(holder, holdersVestingCount[holder]);
    }

    /**
     * @dev Returns the last vesting schedule for a given holder address.
     */
    function getLastVestingScheduleForHolder(
        address holder
    ) external view returns (VestingSchedule memory) {
        return
            vestingSchedules[
                computeVestingScheduleIdForAddressAndIndex(holder, holdersVestingCount[holder] - 1)
            ];
    }

    /**
     * @dev Computes the vesting schedule identifier for an address and an index.
     */
    function computeVestingScheduleIdForAddressAndIndex(
        address holder,
        uint256 index
    ) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(holder, index));
    }

    /**
     * @dev Computes the releasable amount of tokens for a vesting schedule.
     * @return the amount of releasable tokens
     */
    function _computeReleasableAmount(
        VestingSchedule memory vestingSchedule
    ) internal view returns (uint256) {
        // Retrieve the current time.
        uint256 currentTime = getCurrentTime();
        // If the current time is before the cliff, no tokens are releasable.
        if ((currentTime < vestingSchedule.cliff) || vestingSchedule.revoked) {
            return 0;
        }
        // If the current time is after the vesting period, all tokens are releasable,
        // minus the amount already released.
        else if (currentTime >= vestingSchedule.cliff + vestingSchedule.duration) {
            return vestingSchedule.amountTotal - vestingSchedule.released;
        }
        // Otherwise, some tokens are releasable.
        else {
            // Compute the number of full vesting periods that have elapsed.
            uint256 timeFromStart = currentTime - vestingSchedule.cliff;
            uint256 secondsPerSlice = vestingSchedule.slicePeriodSeconds;
            uint256 vestedSlicePeriods = timeFromStart / secondsPerSlice;
            uint256 vestedSeconds = vestedSlicePeriods * secondsPerSlice;
            // Compute the amount of tokens that are vested.
            uint256 vestedAmount = (vestingSchedule.amountTotal * vestedSeconds) /
                vestingSchedule.duration;
            // Subtract the amount already released and return.
            return vestedAmount - vestingSchedule.released;
        }
    }

    /**
     * @dev Returns the current time.
     * @return the current timestamp in seconds.
     */
    function getCurrentTime() internal view virtual returns (uint256) {
        return block.timestamp;
    }
}

File 2 of 5 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 3 of 5 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 4 of 5 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

File 5 of 5 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@uniswap/=node_modules/@uniswap/",
    "ds-test/=lib/murky/lib/forge-std/lib/ds-test/src/",
    "erc721a/=node_modules/erc721a/",
    "eth-gas-reporter/=node_modules/eth-gas-reporter/",
    "forge-std/=lib/forge-std/src/",
    "hardhat-deploy/=node_modules/hardhat-deploy/",
    "hardhat/=node_modules/hardhat/",
    "openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/",
    "solmate/=node_modules/solmate/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"computeNextVestingScheduleIdForHolder","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vestingScheduleId","type":"bytes32"}],"name":"computeReleasableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"computeVestingScheduleIdForAddressAndIndex","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_cliff","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"uint256","name":"_slicePeriodSeconds","type":"uint256"},{"internalType":"bool","name":"_revocable","type":"bool"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"createVestingSchedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"getLastVestingScheduleForHolder","outputs":[{"components":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"cliff","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"slicePeriodSeconds","type":"uint256"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"uint256","name":"amountTotal","type":"uint256"},{"internalType":"uint256","name":"released","type":"uint256"},{"internalType":"bool","name":"revoked","type":"bool"}],"internalType":"struct TokenVesting.VestingSchedule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getVestingIdAtIndex","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vestingScheduleId","type":"bytes32"}],"name":"getVestingSchedule","outputs":[{"components":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"cliff","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"slicePeriodSeconds","type":"uint256"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"uint256","name":"amountTotal","type":"uint256"},{"internalType":"uint256","name":"released","type":"uint256"},{"internalType":"bool","name":"revoked","type":"bool"}],"internalType":"struct TokenVesting.VestingSchedule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getVestingScheduleByAddressAndIndex","outputs":[{"components":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"cliff","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"slicePeriodSeconds","type":"uint256"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"uint256","name":"amountTotal","type":"uint256"},{"internalType":"uint256","name":"released","type":"uint256"},{"internalType":"bool","name":"revoked","type":"bool"}],"internalType":"struct TokenVesting.VestingSchedule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVestingSchedulesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"getVestingSchedulesCountByBeneficiary","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVestingSchedulesTotalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vestingScheduleId","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vestingScheduleId","type":"bytes32"}],"name":"revoke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a06040526001805534801561001457600080fd5b5060405161159f38038061159f83398101604081905261003391610098565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b03811661008757600080fd5b6001600160a01b03166080526100c8565b6000602082840312156100aa57600080fd5b81516001600160a01b03811681146100c157600080fd5b9392505050565b6080516114a76100f86000396000818161015d0152818161081301528181610a840152610be401526114a76000f3fe6080604052600436106101015760003560e01c80638da5cb5b1161008f578063ea1bb3d511610061578063ea1bb3d5146102e2578063f2fde38b14610302578063f51321d714610322578063f7c469f014610342578063f9079b371461036257005b80638da5cb5b1461026d57806390be10cc1461028d5780639ef346b4146102a2578063b75c7dc6146102c257005b806348deb471116100d357806348deb471146101b55780635a7bb69a146101ca57806366afd8ef146102005780637e913dc6146102205780638af104da1461024d57005b8063130836171461010a57806317e289e91461012e57806321df0da71461014e5780632e1a7d4d1461019557005b3661010857005b005b34801561011657600080fd5b506002545b6040519081526020015b60405180910390f35b34801561013a57600080fd5b50610108610149366004611242565b610382565b34801561015a57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b039091168152602001610125565b3480156101a157600080fd5b506101086101b03660046112ae565b610735565b3480156101c157600080fd5b5060045461011b565b3480156101d657600080fd5b5061011b6101e53660046112c7565b6001600160a01b031660009081526005602052604090205490565b34801561020c57600080fd5b5061010861021b3660046112e2565b610840565b34801561022c57600080fd5b5061024061023b3660046112c7565b610ab8565b6040516101259190611304565b34801561025957600080fd5b5061011b61026836600461137d565b610b7e565b34801561027957600080fd5b5060005461017d906001600160a01b031681565b34801561029957600080fd5b5061011b610bc6565b3480156102ae57600080fd5b506102406102bd3660046112ae565b610c66565b3480156102ce57600080fd5b506101086102dd3660046112ae565b610cfb565b3480156102ee57600080fd5b5061011b6102fd3660046112ae565b610e87565b34801561030e57600080fd5b5061010861031d3660046112c7565b610f3f565b34801561032e57600080fd5b5061024061033d36600461137d565b610fb4565b34801561034e57600080fd5b5061011b61035d3660046112c7565b610fd0565b34801561036e57600080fd5b5061011b61037d3660046112ae565b610ff4565b6000546001600160a01b031633146103b55760405162461bcd60e51b81526004016103ac906113a7565b60405180910390fd5b806103be610bc6565b10156104455760405162461bcd60e51b815260206004820152604a60248201527f546f6b656e56657374696e673a2063616e6e6f7420637265617465207665737460448201527f696e67207363686564756c652062656361757365206e6f742073756666696369606482015269656e7420746f6b656e7360b01b608482015260a4016103ac565b600084116104a05760405162461bcd60e51b815260206004820152602260248201527f546f6b656e56657374696e673a206475726174696f6e206d757374206265203e604482015261020360f41b60648201526084016103ac565b600081116104f05760405162461bcd60e51b815260206004820181905260248201527f546f6b656e56657374696e673a20616d6f756e74206d757374206265203e203060448201526064016103ac565b60018310156105575760405162461bcd60e51b815260206004820152602d60248201527f546f6b656e56657374696e673a20736c696365506572696f645365636f6e647360448201526c206d757374206265203e3d203160981b60648201526084016103ac565b848410156105b75760405162461bcd60e51b815260206004820152602760248201527f546f6b656e56657374696e673a206475726174696f6e206d757374206265203e6044820152661e9031b634b33360c91b60648201526084016103ac565b60006105c288610fd0565b905060006105d087896113e3565b60408051610120810182526001600160a01b03808d16825260208083018581528385018e8152606085018d8152608086018d81528c151560a0880190815260c088018d8152600060e08a018181526101008b018281528f83526003998a90529b90912099518a5499166001600160a01b031990991698909817895594516001890155925160028801559051938601939093559151600480860191909155915160058501805491151560ff19928316179055905160068501559151600784015592516008909201805492151592909116919091179055549091506106b49084906113e3565b6004556002805460018181019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018390556001600160a01b038a166000908152600560205260409020549061070d9082906113e3565b6001600160a01b03909a16600090815260056020526040902099909955505050505050505050565b6001546001146107745760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016103ac565b60026001556000546001600160a01b031633146107a35760405162461bcd60e51b81526004016103ac906113a7565b806107ac610bc6565b101561080e5760405162461bcd60e51b815260206004820152602b60248201527f546f6b656e56657374696e673a206e6f7420656e6f756768207769746864726160448201526a7761626c652066756e647360a81b60648201526084016103ac565b6108397f0000000000000000000000000000000000000000000000000000000000000000338361107c565b5060018055565b60015460011461087f5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016103ac565b6002600155600082815260036020526040902060080154829060ff16156108a557600080fd5b6000838152600360205260408120805491549091336001600160a01b039182168114929091161481806108d55750805b6109525760405162461bcd60e51b815260206004820152604260248201527f546f6b656e56657374696e673a206f6e6c792062656e6566696369617279206160448201527f6e64206f776e65722063616e2072656c656173652076657374656420746f6b656064820152616e7360f01b608482015260a4016103ac565b604080516101208101825284546001600160a01b03168152600185015460208201526002850154918101919091526003840154606082015260048401546080820152600584015460ff908116151560a0830152600685015460c0830152600785015460e083015260088501541615156101008201526000906109d390611103565b905085811015610a4b5760405162461bcd60e51b815260206004820152603d60248201527f546f6b656e56657374696e673a2063616e6e6f742072656c6561736520746f6b60448201527f656e732c206e6f7420656e6f7567682076657374656420746f6b656e7300000060648201526084016103ac565b858460070154610a5b91906113e3565b600785015583546004546001600160a01b0390911690610a7c9088906113f6565b600455610aaa7f0000000000000000000000000000000000000000000000000000000000000000828961107c565b505060018055505050505050565b610ac06111cd565b6001600160a01b03821660009081526005602052604081205460039190610aef908590610268906001906113f6565b8152602080820192909252604090810160002081516101208101835281546001600160a01b031681526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460ff908116151560a0840152600682015460c0840152600782015460e084015260089091015416151561010082015292915050565b6040516bffffffffffffffffffffffff19606084901b166020820152603481018290526000906054016040516020818303038152906040528051906020012090505b92915050565b600480546040516370a0823160e01b815230928101929092526000917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c579190611409565b610c6191906113f6565b905090565b610c6e6111cd565b5060009081526003602081815260409283902083516101208101855281546001600160a01b0316815260018201549281019290925260028101549382019390935290820154606082015260048201546080820152600582015460ff908116151560a0830152600683015460c0830152600783015460e0830152600890920154909116151561010082015290565b6000546001600160a01b03163314610d255760405162461bcd60e51b81526004016103ac906113a7565b600081815260036020526040902060080154819060ff1615610d4657600080fd5b6000828152600360205260409020600581015460ff16610db75760405162461bcd60e51b815260206004820152602660248201527f546f6b656e56657374696e673a2076657374696e67206973206e6f74207265766044820152656f6361626c6560d01b60648201526084016103ac565b604080516101208101825282546001600160a01b03168152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460ff908116151560a0830152600683015460c0830152600783015460e08301526008830154161515610100820152600090610e3890611103565b90508015610e4a57610e4a8482610840565b600082600701548360060154610e6091906113f6565b905080600454610e7091906113f6565b6004555050600801805460ff191660011790555050565b600081815260036020526040812060080154829060ff1615610ea857600080fd5b60008381526003602081815260409283902083516101208101855281546001600160a01b0316815260018201549281019290925260028101549382019390935290820154606082015260048201546080820152600582015460ff908116151560a0830152600683015460c0830152600783015460e08301526008830154161515610100820152610f3790611103565b949350505050565b6000546001600160a01b03163314610f695760405162461bcd60e51b81526004016103ac906113a7565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b610fbc6111cd565b610fc96102bd8484610b7e565b9392505050565b6001600160a01b038116600090815260056020526040812054610bc0908390610b7e565b6000610fff60025490565b82106110575760405162461bcd60e51b815260206004820152602160248201527f546f6b656e56657374696e673a20696e646578206f7574206f6620626f756e646044820152607360f81b60648201526084016103ac565b6002828154811061106a5761106a611422565b90600052602060002001549050919050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806110fd5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016103ac565b50505050565b6020810151600090429081108061111c57508261010001515b1561112a5750600092915050565b8260600151836020015161113e91906113e3565b8110611158578260e001518360c00151610fc991906113f6565b600083602001518261116a91906113f6565b6080850151909150600061117e8284611438565b9050600061118c838361145a565b905060008760600151828960c001516111a5919061145a565b6111af9190611438565b90508760e00151816111c191906113f6565b98975050505050505050565b60405180610120016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000151581525090565b80356001600160a01b038116811461123d57600080fd5b919050565b600080600080600080600060e0888a03121561125d57600080fd5b61126688611226565b96506020880135955060408801359450606088013593506080880135925060a0880135801515811461129757600080fd5b8092505060c0880135905092959891949750929550565b6000602082840312156112c057600080fd5b5035919050565b6000602082840312156112d957600080fd5b610fc982611226565b600080604083850312156112f557600080fd5b50508035926020909101359150565b60006101208201905060018060a01b0383511682526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015260c083015160c083015260e083015160e0830152610100808401516113758285018215159052565b505092915050565b6000806040838503121561139057600080fd5b61139983611226565b946020939093013593505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610bc057610bc06113cd565b81810381811115610bc057610bc06113cd565b60006020828403121561141b57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60008261145557634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610bc057610bc06113cd56fea26469706673582212202ed64d7f201ebcbe845396baa10abbf23829f45892229374b6d98cdd846bca5064736f6c63430008180033000000000000000000000000f36f79feb5d97e18c69078d8d13d941cae447a04

Deployed Bytecode

0x6080604052600436106101015760003560e01c80638da5cb5b1161008f578063ea1bb3d511610061578063ea1bb3d5146102e2578063f2fde38b14610302578063f51321d714610322578063f7c469f014610342578063f9079b371461036257005b80638da5cb5b1461026d57806390be10cc1461028d5780639ef346b4146102a2578063b75c7dc6146102c257005b806348deb471116100d357806348deb471146101b55780635a7bb69a146101ca57806366afd8ef146102005780637e913dc6146102205780638af104da1461024d57005b8063130836171461010a57806317e289e91461012e57806321df0da71461014e5780632e1a7d4d1461019557005b3661010857005b005b34801561011657600080fd5b506002545b6040519081526020015b60405180910390f35b34801561013a57600080fd5b50610108610149366004611242565b610382565b34801561015a57600080fd5b507f000000000000000000000000f36f79feb5d97e18c69078d8d13d941cae447a045b6040516001600160a01b039091168152602001610125565b3480156101a157600080fd5b506101086101b03660046112ae565b610735565b3480156101c157600080fd5b5060045461011b565b3480156101d657600080fd5b5061011b6101e53660046112c7565b6001600160a01b031660009081526005602052604090205490565b34801561020c57600080fd5b5061010861021b3660046112e2565b610840565b34801561022c57600080fd5b5061024061023b3660046112c7565b610ab8565b6040516101259190611304565b34801561025957600080fd5b5061011b61026836600461137d565b610b7e565b34801561027957600080fd5b5060005461017d906001600160a01b031681565b34801561029957600080fd5b5061011b610bc6565b3480156102ae57600080fd5b506102406102bd3660046112ae565b610c66565b3480156102ce57600080fd5b506101086102dd3660046112ae565b610cfb565b3480156102ee57600080fd5b5061011b6102fd3660046112ae565b610e87565b34801561030e57600080fd5b5061010861031d3660046112c7565b610f3f565b34801561032e57600080fd5b5061024061033d36600461137d565b610fb4565b34801561034e57600080fd5b5061011b61035d3660046112c7565b610fd0565b34801561036e57600080fd5b5061011b61037d3660046112ae565b610ff4565b6000546001600160a01b031633146103b55760405162461bcd60e51b81526004016103ac906113a7565b60405180910390fd5b806103be610bc6565b10156104455760405162461bcd60e51b815260206004820152604a60248201527f546f6b656e56657374696e673a2063616e6e6f7420637265617465207665737460448201527f696e67207363686564756c652062656361757365206e6f742073756666696369606482015269656e7420746f6b656e7360b01b608482015260a4016103ac565b600084116104a05760405162461bcd60e51b815260206004820152602260248201527f546f6b656e56657374696e673a206475726174696f6e206d757374206265203e604482015261020360f41b60648201526084016103ac565b600081116104f05760405162461bcd60e51b815260206004820181905260248201527f546f6b656e56657374696e673a20616d6f756e74206d757374206265203e203060448201526064016103ac565b60018310156105575760405162461bcd60e51b815260206004820152602d60248201527f546f6b656e56657374696e673a20736c696365506572696f645365636f6e647360448201526c206d757374206265203e3d203160981b60648201526084016103ac565b848410156105b75760405162461bcd60e51b815260206004820152602760248201527f546f6b656e56657374696e673a206475726174696f6e206d757374206265203e6044820152661e9031b634b33360c91b60648201526084016103ac565b60006105c288610fd0565b905060006105d087896113e3565b60408051610120810182526001600160a01b03808d16825260208083018581528385018e8152606085018d8152608086018d81528c151560a0880190815260c088018d8152600060e08a018181526101008b018281528f83526003998a90529b90912099518a5499166001600160a01b031990991698909817895594516001890155925160028801559051938601939093559151600480860191909155915160058501805491151560ff19928316179055905160068501559151600784015592516008909201805492151592909116919091179055549091506106b49084906113e3565b6004556002805460018181019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018390556001600160a01b038a166000908152600560205260409020549061070d9082906113e3565b6001600160a01b03909a16600090815260056020526040902099909955505050505050505050565b6001546001146107745760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016103ac565b60026001556000546001600160a01b031633146107a35760405162461bcd60e51b81526004016103ac906113a7565b806107ac610bc6565b101561080e5760405162461bcd60e51b815260206004820152602b60248201527f546f6b656e56657374696e673a206e6f7420656e6f756768207769746864726160448201526a7761626c652066756e647360a81b60648201526084016103ac565b6108397f000000000000000000000000f36f79feb5d97e18c69078d8d13d941cae447a04338361107c565b5060018055565b60015460011461087f5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064016103ac565b6002600155600082815260036020526040902060080154829060ff16156108a557600080fd5b6000838152600360205260408120805491549091336001600160a01b039182168114929091161481806108d55750805b6109525760405162461bcd60e51b815260206004820152604260248201527f546f6b656e56657374696e673a206f6e6c792062656e6566696369617279206160448201527f6e64206f776e65722063616e2072656c656173652076657374656420746f6b656064820152616e7360f01b608482015260a4016103ac565b604080516101208101825284546001600160a01b03168152600185015460208201526002850154918101919091526003840154606082015260048401546080820152600584015460ff908116151560a0830152600685015460c0830152600785015460e083015260088501541615156101008201526000906109d390611103565b905085811015610a4b5760405162461bcd60e51b815260206004820152603d60248201527f546f6b656e56657374696e673a2063616e6e6f742072656c6561736520746f6b60448201527f656e732c206e6f7420656e6f7567682076657374656420746f6b656e7300000060648201526084016103ac565b858460070154610a5b91906113e3565b600785015583546004546001600160a01b0390911690610a7c9088906113f6565b600455610aaa7f000000000000000000000000f36f79feb5d97e18c69078d8d13d941cae447a04828961107c565b505060018055505050505050565b610ac06111cd565b6001600160a01b03821660009081526005602052604081205460039190610aef908590610268906001906113f6565b8152602080820192909252604090810160002081516101208101835281546001600160a01b031681526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460ff908116151560a0840152600682015460c0840152600782015460e084015260089091015416151561010082015292915050565b6040516bffffffffffffffffffffffff19606084901b166020820152603481018290526000906054016040516020818303038152906040528051906020012090505b92915050565b600480546040516370a0823160e01b815230928101929092526000917f000000000000000000000000f36f79feb5d97e18c69078d8d13d941cae447a046001600160a01b0316906370a0823190602401602060405180830381865afa158015610c33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c579190611409565b610c6191906113f6565b905090565b610c6e6111cd565b5060009081526003602081815260409283902083516101208101855281546001600160a01b0316815260018201549281019290925260028101549382019390935290820154606082015260048201546080820152600582015460ff908116151560a0830152600683015460c0830152600783015460e0830152600890920154909116151561010082015290565b6000546001600160a01b03163314610d255760405162461bcd60e51b81526004016103ac906113a7565b600081815260036020526040902060080154819060ff1615610d4657600080fd5b6000828152600360205260409020600581015460ff16610db75760405162461bcd60e51b815260206004820152602660248201527f546f6b656e56657374696e673a2076657374696e67206973206e6f74207265766044820152656f6361626c6560d01b60648201526084016103ac565b604080516101208101825282546001600160a01b03168152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460ff908116151560a0830152600683015460c0830152600783015460e08301526008830154161515610100820152600090610e3890611103565b90508015610e4a57610e4a8482610840565b600082600701548360060154610e6091906113f6565b905080600454610e7091906113f6565b6004555050600801805460ff191660011790555050565b600081815260036020526040812060080154829060ff1615610ea857600080fd5b60008381526003602081815260409283902083516101208101855281546001600160a01b0316815260018201549281019290925260028101549382019390935290820154606082015260048201546080820152600582015460ff908116151560a0830152600683015460c0830152600783015460e08301526008830154161515610100820152610f3790611103565b949350505050565b6000546001600160a01b03163314610f695760405162461bcd60e51b81526004016103ac906113a7565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b610fbc6111cd565b610fc96102bd8484610b7e565b9392505050565b6001600160a01b038116600090815260056020526040812054610bc0908390610b7e565b6000610fff60025490565b82106110575760405162461bcd60e51b815260206004820152602160248201527f546f6b656e56657374696e673a20696e646578206f7574206f6620626f756e646044820152607360f81b60648201526084016103ac565b6002828154811061106a5761106a611422565b90600052602060002001549050919050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806110fd5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016103ac565b50505050565b6020810151600090429081108061111c57508261010001515b1561112a5750600092915050565b8260600151836020015161113e91906113e3565b8110611158578260e001518360c00151610fc991906113f6565b600083602001518261116a91906113f6565b6080850151909150600061117e8284611438565b9050600061118c838361145a565b905060008760600151828960c001516111a5919061145a565b6111af9190611438565b90508760e00151816111c191906113f6565b98975050505050505050565b60405180610120016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000151581525090565b80356001600160a01b038116811461123d57600080fd5b919050565b600080600080600080600060e0888a03121561125d57600080fd5b61126688611226565b96506020880135955060408801359450606088013593506080880135925060a0880135801515811461129757600080fd5b8092505060c0880135905092959891949750929550565b6000602082840312156112c057600080fd5b5035919050565b6000602082840312156112d957600080fd5b610fc982611226565b600080604083850312156112f557600080fd5b50508035926020909101359150565b60006101208201905060018060a01b0383511682526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015260c083015160c083015260e083015160e0830152610100808401516113758285018215159052565b505092915050565b6000806040838503121561139057600080fd5b61139983611226565b946020939093013593505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610bc057610bc06113cd565b81810381811115610bc057610bc06113cd565b60006020828403121561141b57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60008261145557634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610bc057610bc06113cd56fea26469706673582212202ed64d7f201ebcbe845396baa10abbf23829f45892229374b6d98cdd846bca5064736f6c63430008180033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000f36f79feb5d97e18c69078d8d13d941cae447a04

-----Decoded View---------------
Arg [0] : token_ (address): 0xF36f79feb5d97e18C69078d8D13d941CaE447A04

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f36f79feb5d97e18c69078d8d13d941cae447a04


Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.