Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 2 txns
Misc:
Address Watch: Add To Watch List
Contract Creator: 0x372427ce1d7cda259597896d3433243c73774724at txn 0xf259077c98196dca42e521c209b5dd1714c975a0ffdb711801e58467f51a0643
Token Balance:
 Latest 2 txns

TxHash Age From To Value [TxFee]
0x76720de480eaa3f60d349ab5f76fb317d2fcc63b5319c1eb6dc6481aef62c94564 days 23 hrs ago0x372427ce1d7cda259597896d3433243c73774724  IN   0xd698dc82f4cd43097009e5ddc4e0adc1e43875a30 Ether0.000451725
0xf3a587a3fe4f345dd2d4b7fe2a2a4371ba326786f7676e60b32c14b3d2d8e02c64 days 23 hrs ago0x372427ce1d7cda259597896d3433243c73774724  IN   0xd698dc82f4cd43097009e5ddc4e0adc1e43875a30 Ether0.001798095
0xf259077c98196dca42e521c209b5dd1714c975a0ffdb711801e58467f51a064365 days 1 hr ago0x372427ce1d7cda259597896d3433243c73774724  IN    Contract Creation0 Ether0.0090496
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Similar Match)
Note: Displaying Similar Match Verified Source Code At Contract 0x1a6c9ff63f4786667ea2548a144cd695f6c2d458(Excluding Constructor Arguments if any)
Contract Name: Vault12LockedTokens
Compiler Text: v0.4.24+commit.e67f0147
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity 0.4.24;

// File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * See https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address _who) public view returns (uint256);
  function transfer(address _to, uint256 _value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address _owner, address _spender)
    public view returns (uint256);

  function transferFrom(address _from, address _to, uint256 _value)
    public returns (bool);

  function approve(address _spender, uint256 _value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (_a == 0) {
      return 0;
    }

    c = _a * _b;
    assert(c / _a == _b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
    // assert(_b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = _a / _b;
    // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
    return _a / _b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
    assert(_b <= _a);
    return _a - _b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    c = _a + _b;
    assert(c >= _a);
    return c;
  }
}

// File: contracts/Vault12LockedTokens.sol

contract Vault12LockedTokens {
    using SafeMath for uint256;
    uint256 constant internal SECONDS_PER_YEAR = 31561600;

    modifier onlyV12MultiSig {
        require(msg.sender == v12MultiSig, "not owner");
        _;
    }

    modifier onlyValidAddress(address _recipient) {
        require(_recipient != address(0) && _recipient != address(this) && _recipient != address(token), "not valid _recipient");
        _;
    }

    struct Grant {
        uint256 startTime;
        uint256 amount;
        uint256 vestingDuration;
        uint256 yearsClaimed;
        uint256 totalClaimed;
    }

    event GrantAdded(address recipient, uint256 amount);
    event GrantTokensClaimed(address recipient, uint256 amountClaimed);
    event ChangedMultisig(address multisig);

    ERC20 public token;
    
    mapping (address => Grant) public tokenGrants;
    address public v12MultiSig;

    constructor(ERC20 _token) public {
        require(address(_token) != address(0));
        v12MultiSig = msg.sender;
        token = _token;
    }
    
    function addTokenGrant(
        address _recipient,
        uint256 _startTime,
        uint256 _amount,
        uint256 _vestingDurationInYears
    )
        onlyV12MultiSig
        onlyValidAddress(_recipient)
        external
    {
        require(!grantExist(_recipient), "grant already exist");
        require(_vestingDurationInYears <= 25, "more than 25 years");
        uint256 amountVestedPerYear = _amount.div(_vestingDurationInYears);
        require(amountVestedPerYear > 0, "amountVestedPerYear > 0");

        // Transfer the grant tokens under the control of the vesting contract
        require(token.transferFrom(msg.sender, address(this), _amount), "transfer failed");

        Grant memory grant = Grant({
            startTime: _startTime == 0 ? currentTime() : _startTime,
            amount: _amount,
            vestingDuration: _vestingDurationInYears,
            yearsClaimed: 0,
            totalClaimed: 0
        });
        tokenGrants[_recipient] = grant;
        emit GrantAdded(_recipient, _amount);
    }

    /// @notice Calculate the vested and unclaimed months and tokens available for `_grantId` to claim
    /// Due to rounding errors once grant duration is reached, returns the entire left grant amount
    /// Returns (0, 0) if cliff has not been reached
    function calculateGrantClaim(address _recipient) public view returns (uint256, uint256) {
        Grant storage tokenGrant = tokenGrants[_recipient];

        // For grants created with a future start date, that hasn't been reached, return 0, 0
        if (currentTime() < tokenGrant.startTime) {
            return (0, 0);
        }

        uint256 elapsedTime = currentTime().sub(tokenGrant.startTime);
        uint256 elapsedYears = elapsedTime.div(SECONDS_PER_YEAR);
        
        // If over vesting duration, all tokens vested
        if (elapsedYears >= tokenGrant.vestingDuration) {
            uint256 remainingGrant = tokenGrant.amount.sub(tokenGrant.totalClaimed);
            uint256 remainingYears = tokenGrant.vestingDuration.sub(tokenGrant.yearsClaimed);
            return (remainingYears, remainingGrant);
        } else {
            uint256 i = 0;
            uint256 tokenGrantAmount = tokenGrant.amount;
            uint256 totalVested = 0;
            for(i; i < elapsedYears; i++){
                totalVested = (tokenGrantAmount.mul(10)).div(100).add(totalVested); 
                tokenGrantAmount = tokenGrant.amount.sub(totalVested);
            }
            uint256 amountVested = totalVested.sub(tokenGrant.totalClaimed);
            return (elapsedYears, amountVested);
        }
    }

    /// @notice Allows a grant recipient to claim their vested tokens. Errors if no tokens have vested
    /// It is advised recipients check they are entitled to claim via `calculateGrantClaim` before calling this
    function claimVestedTokens(address _recipient) external {
        uint256 yearsVested;
        uint256 amountVested;
        (yearsVested, amountVested) = calculateGrantClaim(_recipient);
        require(amountVested > 0, "amountVested is 0");

        Grant storage tokenGrant = tokenGrants[_recipient];
        tokenGrant.yearsClaimed = yearsVested;
        tokenGrant.totalClaimed = tokenGrant.totalClaimed.add(amountVested);
        
        require(token.transfer(_recipient, amountVested), "no tokens");
        emit GrantTokensClaimed(_recipient, amountVested);
    }

    function currentTime() public view returns(uint256) {
        return block.timestamp;
    }

    function changeMultiSig(address _newMultisig) 
        external 
        onlyV12MultiSig
        onlyValidAddress(_newMultisig)
    {
        v12MultiSig = _newMultisig;
        emit ChangedMultisig(_newMultisig);
    }

    function grantExist(address _recipient) public view returns(bool) {
        return tokenGrants[_recipient].amount > 0;
    }

}

    Contract ABI  
[{"constant":true,"inputs":[{"name":"_recipient","type":"address"}],"name":"grantExist","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newMultisig","type":"address"}],"name":"changeMultiSig","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_startTime","type":"uint256"},{"name":"_amount","type":"uint256"},{"name":"_vestingDurationInYears","type":"uint256"}],"name":"addTokenGrant","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"}],"name":"claimVestedTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"tokenGrants","outputs":[{"name":"startTime","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"vestingDuration","type":"uint256"},{"name":"yearsClaimed","type":"uint256"},{"name":"totalClaimed","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"v12MultiSig","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_recipient","type":"address"}],"name":"calculateGrantClaim","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_token","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"GrantAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amountClaimed","type":"uint256"}],"name":"GrantTokensClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"multisig","type":"address"}],"name":"ChangedMultisig","type":"event"}]

  Contract Creation Code Switch To Opcodes View
608060405234801561001057600080fd5b50604051602080610c6e8339810160405251600160a060020a038116151561003757600080fd5b60028054600160a060020a0319908116331790915560008054600160a060020a039390931692909116919091179055610bf9806100756000396000f3006080604052600436106100985763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663106a7be2811461009d5780632902a0ca146100d25780633615b26a146100f557806398f3b12d1461011f578063b81a4d8f14610140578063d18e81b31461018c578063d531ebc0146101b3578063fc0c546a146101e4578063fd75b8d4146101f9575b600080fd5b3480156100a957600080fd5b506100be600160a060020a0360043516610233565b604080519115158252519081900360200190f35b3480156100de57600080fd5b506100f3600160a060020a0360043516610252565b005b34801561010157600080fd5b506100f3600160a060020a03600435166024356044356064356103a8565b34801561012b57600080fd5b506100f3600160a060020a0360043516610786565b34801561014c57600080fd5b50610161600160a060020a036004351661098a565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561019857600080fd5b506101a16109b8565b60408051918252519081900360200190f35b3480156101bf57600080fd5b506101c86109bc565b60408051600160a060020a039092168252519081900360200190f35b3480156101f057600080fd5b506101c86109cb565b34801561020557600080fd5b5061021a600160a060020a03600435166109da565b6040805192835260208301919091528051918290030190f35b600160a060020a03166000908152600160208190526040822001541190565b600254600160a060020a031633146102b4576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b80600160a060020a038116158015906102d65750600160a060020a0381163014155b80156102f05750600054600160a060020a03828116911614155b1515610346576040805160e560020a62461bcd02815260206004820152601460248201527f6e6f742076616c6964205f726563697069656e74000000000000000000000000604482015290519081900360640190fd5b60028054600160a060020a03841673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f1095c9869752f7f59b0736661c1ccc9e0314e35c10af8ee5482f57836852f2079181900360200190a15050565b60006103b2610b9d565b600254600160a060020a03163314610414576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b85600160a060020a038116158015906104365750600160a060020a0381163014155b80156104505750600054600160a060020a03828116911614155b15156104a6576040805160e560020a62461bcd02815260206004820152601460248201527f6e6f742076616c6964205f726563697069656e74000000000000000000000000604482015290519081900360640190fd5b6104af87610233565b15610504576040805160e560020a62461bcd02815260206004820152601360248201527f6772616e7420616c726561647920657869737400000000000000000000000000604482015290519081900360640190fd5b601984111561055d576040805160e560020a62461bcd02815260206004820152601260248201527f6d6f7265207468616e2032352079656172730000000000000000000000000000604482015290519081900360640190fd5b61056d858563ffffffff610b3e16565b9250600083116105c7576040805160e560020a62461bcd02815260206004820152601760248201527f616d6f756e7456657374656450657259656172203e2030000000000000000000604482015290519081900360640190fd5b60008054604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018990529051600160a060020a03909216926323b872dd926064808401936020939083900390910190829087803b15801561063b57600080fd5b505af115801561064f573d6000803e3d6000fd5b505050506040513d602081101561066557600080fd5b505115156106bd576040805160e560020a62461bcd02815260206004820152600f60248201527f7472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b60a060405190810160405280876000146106d757876106df565b6106df6109b8565b815260208082018890526040808301889052600060608085018290526080948501829052600160a060020a038d1680835260018086529284902087518155878601519381019390935586840151600284015590860151600383015593850151600490910155805192835290820188905280519294507f9d2a1eab91557a277ec725fe26546609d5a33a550c3f3476982ee177252be8f492918290030190a150505050505050565b6000806000610794846109da565b9093509150600082116107f1576040805160e560020a62461bcd02815260206004820152601160248201527f616d6f756e745665737465642069732030000000000000000000000000000000604482015290519081900360640190fd5b50600160a060020a0383166000908152600160205260409020600381018390556004810154610826908363ffffffff610b5516565b81600401819055506000809054906101000a9004600160a060020a0316600160a060020a031663a9059cbb85846040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b1580156108be57600080fd5b505af11580156108d2573d6000803e3d6000fd5b505050506040513d60208110156108e857600080fd5b50511515610940576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f20746f6b656e730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60408051600160a060020a03861681526020810184905281517fc6cbb4aa8681b18644bf64921eea8f2b9f44cbd58d64fc07a110bfccc2038296929181900390910190a150505050565b6001602081905260009182526040909120805491810154600282015460038301546004909301549192909185565b4290565b600254600160a060020a031681565b600054600160a060020a031681565b600160a060020a0381166000908152600160205260408120805482919082908190819081908190819081908190610a0f6109b8565b1015610a215760009a508a9950610b30565b8854610a3b90610a2f6109b8565b9063ffffffff610b6216565b9750610a51886301e1978063ffffffff610b3e16565b60028a01549097508710610aa257600489015460018a0154610a789163ffffffff610b6216565b9550610a9589600301548a60020154610b6290919063ffffffff16565b945084869a509a50610b30565b6000935088600101549250600091505b86841015610b1157610aec82610ae06064610ad487600a63ffffffff610b7416565b9063ffffffff610b3e16565b9063ffffffff610b5516565b60018a0154909250610b04908363ffffffff610b6216565b6001909401939250610ab2565b6004890154610b2790839063ffffffff610b6216565b905086819a509a505b505050505050505050915091565b60008183811515610b4b57fe5b0490505b92915050565b81810182811015610b4f57fe5b600082821115610b6e57fe5b50900390565b6000821515610b8557506000610b4f565b50818102818382811515610b9557fe5b0414610b4f57fe5b60a060405190810160405280600081526020016000815260200160008152602001600081526020016000815250905600a165627a7a72305820763969cdc7571cead30ff9fa84d5f18984e3bf713f5288d7b0977e92e50c206c0029000000000000000000000000cc394f10545aeef24483d2347b32a34a44f20e6f

   Swarm Source:
bzzr://763969cdc7571cead30ff9fa84d5f18984e3bf713f5288d7b0977e92e50c206c

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.