Forkchoice Ethereum Mainnet

Address Contract Partially Verified

Address 0xe8abfBc0443d3119C623d52Eb5E584dff3efaddf
Balance 0 ETH
Nonce 1
Code Size 2094 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

2094 bytes
0x608060405234801561001057600080fd5b50600436106100935760003560e01c806378e979251161006657806378e979251461017d57806379203dc41461019b578063b3a56077146101b9578063db8e8e9b146101d7578063fc0c546a1461022557610093565b80631c7afe941461009857806326c25962146100b65780632e1a7d4d146101315780633197cbb61461015f575b600080fd5b6100a0610259565b6040518082815260200191505060405180910390f35b6100e2600480360360208110156100cc57600080fd5b810190808035906020019092919050505061025f565b604051808781526020018673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001838152602001828152602001965050505050505060405180910390f35b61015d6004803603602081101561014757600080fd5b81019080803590602001909291905050506102bb565b005b61016761067f565b6040518082815260200191505060405180910390f35b610185610685565b6040518082815260200191505060405180910390f35b6101a361068b565b6040518082815260200191505060405180910390f35b6101c1610691565b6040518082815260200191505060405180910390f35b610223600480360360408110156101ed57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610697565b005b61022d61079e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60015481565b60066020528060005260406000206000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154905086565b6000600660008381526020019081526020016000209050600081600301541161034c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4e6f20636f696e73206c65667420746f2077697468647261770000000000000081525060200191505060405180910390fd5b600060035442106103635781600301549050610495565b427382d7630c5eb722557de6d76575c9a7b8de71850063f4f3bdc1909184600501546040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156103c057600080fd5b505af41580156103d4573d6000803e3d6000fd5b505050506040513d60208110156103ea57600080fd5b81019080805190602001909291905050507382d7630c5eb722557de6d76575c9a7b8de718500631d3b9edf909184600401546040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561045757600080fd5b505af415801561046b573d6000803e3d6000fd5b505050506040513d602081101561048157600080fd5b810190808051906020019092919050505090505b81600301547382d7630c5eb722557de6d76575c9a7b8de71850063f4f3bdc19091836040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156104f257600080fd5b505af4158015610506573d6000803e3d6000fd5b505050506040513d602081101561051c57600080fd5b8101908080519060200190929190505050826003018190555042826005018190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156105f357600080fd5b505af1158015610607573d6000803e3d6000fd5b505050506040513d602081101561061d57600080fd5b8101908080519060200190929190505050507f9c444ca536e256f46459550ce8cc4ff4c578fd67037ddb7bf99e79e1288b692f8382846003015460405180848152602001838152602001828152602001935050505060405180910390a1505050565b60035481565b60025481565b60055481565b60045481565b60006006600084815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610756576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806107c36036913960400191505060405180910390fd5b818160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fe43616e206f6e6c79206368616e67652064657374696e6174696f6e20696620796f7520617265207468652064657374696e6174696f6ea2646970667358221220cd836f2485640fc7fa2ed417fa9f076e6968a9c0f44bbcfde34f5a6feba6da6164736f6c63430007040033

Verified Source Code Partial Match

Compiler: v0.7.4+commit.3f05b770 EVM: istanbul Optimization: No
UniformTimeVault.sol 175 lines
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity 0.7.4;

library SafeMathLib {
  function times(uint a, uint b) public pure returns (uint) {
    uint c = a * b;
    require(a == 0 || c / a == b, 'Overflow detected');
    return c;
  }

  function minus(uint a, uint b) public pure returns (uint) {
    require(b <= a, 'Underflow detected');
    return a - b;
  }

  function plus(uint a, uint b) public pure returns (uint) {
    uint c = a + b;
    require(c>=a && c>=b, 'Overflow detected');
    return c;
  }

}


/**
 * @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);
}

contract UniformTimeVault {
    using SafeMathLib for uint;

    IERC20 public token;
    uint public numTranches = 0;
    uint public startTime = 0;
    uint public endTime = 0;
    uint public vestingPeriodLength = 0;
    uint public totalAllocation = 0;

    struct Tranche {
        uint id;
        address destination;
        uint totalCoins;
        uint currentCoins;
        uint coinsPerSecond;
        uint lastWithdrawalTime;
    }

    mapping (uint => Tranche) public tranches;

    event WithdrawalOccurred(uint trancheId, uint numTokens, uint tokensLeft);
    event TrancheAdded(uint id, address destination, uint totalCoins);

    constructor(address tokenAddr, address[] memory destinations, uint[] memory tokenAllocations, uint _endTime, uint _startTime) {
        token = IERC20(tokenAddr);
        endTime = _endTime;
        startTime = _startTime;
        vestingPeriodLength = endTime - startTime;
        require(vestingPeriodLength > 0 , 'start time must be before end time');

        for (uint i = 0; i < destinations.length; i++)  {
            uint trancheId = i + 1;
            uint coinsPerSecond = tokenAllocations[i] / vestingPeriodLength;
            totalAllocation = totalAllocation.plus(tokenAllocations[i]);
            tranches[trancheId] = Tranche(
                trancheId,
                destinations[i],
                tokenAllocations[i],
                tokenAllocations[i],
                coinsPerSecond,
                _startTime
            );
            emit TrancheAdded(trancheId, destinations[i], tokenAllocations[i]);
        }
        numTranches = destinations.length;
    }

    function withdraw(uint trancheId) external {
        Tranche storage tranche = tranches[trancheId];
        require(tranche.currentCoins >  0, 'No coins left to withdraw');
        uint currentWithdrawal = 0;

        // if after vesting period ends, give them the remaining coins
        if (block.timestamp >= endTime) {
            currentWithdrawal = tranche.currentCoins;
        } else {
            // compute allowed withdrawal
            currentWithdrawal = (block.timestamp.minus(tranche.lastWithdrawalTime)).times(tranche.coinsPerSecond);
        }

        // update struct
        tranche.currentCoins = tranche.currentCoins.minus(currentWithdrawal);
        tranche.lastWithdrawalTime = block.timestamp;

        // transfer the tokens, brah
        token.transfer(tranche.destination, currentWithdrawal);
        emit WithdrawalOccurred(trancheId, currentWithdrawal, tranche.currentCoins);
    }

    function changeDestination(uint trancheId, address newDestination) external {
        Tranche storage tranche = tranches[trancheId];
        require(tranche.destination == msg.sender, 'Can only change destination if you are the destination');
        tranche.destination = newDestination;
    }
}

Read Contract

endTime 0x3197cbb6 → uint256
numTranches 0x1c7afe94 → uint256
startTime 0x78e97925 → uint256
token 0xfc0c546a → address
totalAllocation 0x79203dc4 → uint256
tranches 0x26c25962 → uint256, address, uint256, uint256, uint256, uint256
vestingPeriodLength 0xb3a56077 → uint256

Write Contract 2 functions

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

changeDestination 0xdb8e8e9b
uint256 trancheId
address newDestination
withdraw 0x2e1a7d4d
uint256 trancheId

Recent Transactions

No transactions found for this address