Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xF9A2002b471f600A5484da5a735a2A053d377078
Balance 0 ETH
Nonce 1
Code Size 8383 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

8383 bytes
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639c52a7f111610104578063d8a8e03a116100a2578063e529780d11610071578063e529780d146104fe578063e7657e151461051b578063f52981f414610523578063fc5a5b6314610540576101cf565b8063d8a8e03a14610452578063db64ff8f1461047e578063dc2c788f146104c4578063e054720f146104e1576101cf565b8063bf8712c5116100de578063bf8712c5146103ca578063c659cd45146103fb578063cdf4349714610418578063d4e8fd2e14610435576101cf565b80639c52a7f11461035b578063bb7c46f314610381578063bf353dbb146103a4576101cf565b806353e8863d116101715780636a760b801161014b5780636a760b80146102fc5780637bd2bea7146103195780637d8d270214610321578063892de51d1461033e576101cf565b806353e8863d146102b157806360fb494b146102ce57806365fae35e146102d6576101cf565b806329ae8114116101ad57806329ae811414610246578063355274ea146102695780633c433d5f14610271578063509aaa1d1461028e576101cf565b80631a8d3a6c146101d457806321f6c0cf146101f857806326e027f114610227575b600080fd5b6101dc6105c5565b604080516001600160a01b039092168252519081900360200190f35b6102156004803603602081101561020e57600080fd5b50356105e9565b60408051918252519081900360200190f35b6102446004803603602081101561023d57600080fd5b503561060d565b005b6102446004803603604081101561025c57600080fd5b508035906020013561061a565b610215610758565b6102446004803603602081101561028757600080fd5b503561075e565b610244600480360360408110156102a457600080fd5b50803590602001356108c4565b610215600480360360208110156102c757600080fd5b50356108d2565b6102156109ee565b610244600480360360208110156102ec57600080fd5b50356001600160a01b03166109f6565b6102446004803603602081101561031257600080fd5b5035610a8d565b6101dc610a99565b6102446004803603602081101561033757600080fd5b5035610abd565b6102156004803603602081101561035457600080fd5b5035610c1d565b6102446004803603602081101561037157600080fd5b50356001600160a01b0316610c3b565b6102446004803603604081101561039757600080fd5b5080359060200135610cd1565b610215600480360360208110156103ba57600080fd5b50356001600160a01b0316610cdb565b6103e7600480360360208110156103e057600080fd5b5035610ced565b604080519115158252519081900360200190f35b6101dc6004803603602081101561041157600080fd5b5035610d17565b6102156004803603602081101561042e57600080fd5b5035610d32565b6102156004803603602081101561044b57600080fd5b5035610d53565b6102446004803603604081101561046857600080fd5b50803590602001356001600160a01b0316610d73565b610215600480360360c081101561049457600080fd5b506001600160a01b03813581169160208101359160408201359160608101359160808201359160a0013516610ee2565b6101dc600480360360208110156104da57600080fd5b503561144d565b610215600480360360208110156104f757600080fd5b5035611473565b6102156004803603602081101561051457600080fd5b5035611498565b6102156114b6565b6102156004803603602081101561053957600080fd5b50356114bc565b61055d6004803603602081101561055657600080fd5b50356115c7565b604080516001600160a01b03998a16815265ffffffffffff98891660208201529688168782015294909616606086015291909516608084015260ff90941660a08301526001600160801b0393841660c08301529190921660e083015251908190036101000190f35b7f000000000000000000000000be8e3e3618f7474f8cb1d074a26affef007e98fb81565b600081815260016020526040902054600160a01b900465ffffffffffff165b919050565b6106178142611637565b50565b6004541561065d576040805162461bcd60e51b81526020600482015260156024820152600080516020612026833981519152604482015290519081900360640190fd5b6001600481905533600090815260208190526040902054146106b4576040805162461bcd60e51b81526020600482015260166024820152600080516020612046833981519152604482015290519081900360640190fd5b816206361760ec1b14156106cc576002819055610719565b6040805162461bcd60e51b815260206004820152601f60248201527f447373566573742f66696c652d756e7265636f676e697a65642d706172616d00604482015290519081900360640190fd5b60408051828152905183917fe986e40cc8c151830d4f61050f4fb2e4add8567caad2d5f5496f9158e91fe4c7919081900360200190a250506000600455565b60025481565b600454156107a1576040805162461bcd60e51b81526020600482015260156024820152600080516020612026833981519152604482015290519081900360640190fd5b60016004819055600082815260209190915260409020546001600160a01b03168061080b576040805162461bcd60e51b8152602060048201526015602482015274111cdcd5995cdd0bda5b9d985b1a590b585dd85c99605a1b604482015290519081900360640190fd5b336000908152602081905260409020546001148061083157506001600160a01b03811633145b610870576040805162461bcd60e51b81526020600482015260166024820152600080516020612046833981519152604482015290519081900360640190fd5b6000828152600160208190526040808320909101805460ff60d01b1916600160d01b1790555183917f9247a2bf1b75bc397d4043d99b9cebce531548a01dbb56a5d4c5f5ca26051e8d91a250506000600455565b6108ce8282611637565b5050565b60006108dc611fe1565b5060008281526001602081815260409283902083516101008101855281546001600160a01b03808216808452600160a01b830465ffffffffffff90811696850196909652600160d01b92839004861697840197909752948301549384166060830152600160301b840490941660808201529290910460ff1660a0830152600201546001600160801b0380821660c0840152600160801b9091041660e0820152906109c5576040805162461bcd60e51b8152602060048201526015602482015274111cdcd5995cdd0bda5b9d985b1a590b585dd85c99605a1b604482015290519081900360640190fd5b6109e7428260200151836040015184606001518560c001518660e001516119c2565b9392505050565b632598060081565b33600090815260208190526040902054600114610a48576040805162461bcd60e51b81526020600482015260166024820152600080516020612046833981519152604482015290519081900360640190fd5b6001600160a01b03811660008181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b61061781600019611a04565b7f000000000000000000000000c20059e0317de91738d13af027dfc4a50781b06681565b60045415610b00576040805162461bcd60e51b81526020600482015260156024820152600080516020612026833981519152604482015290519081900360640190fd5b60016004819055600082815260209190915260409020546001600160a01b031680610b6a576040805162461bcd60e51b8152602060048201526015602482015274111cdcd5995cdd0bda5b9d985b1a590b585dd85c99605a1b604482015290519081900360640190fd5b3360009081526020819052604090205460011480610b9057506001600160a01b03811633145b610bcf576040805162461bcd60e51b81526020600482015260166024820152600080516020612046833981519152604482015290519081900360640190fd5b6000828152600160208190526040808320909101805460ff60d01b191690555183917f3d1b575f06b2d660af77eec35d9b3ffcfa956b6c1fdbc840992d4b03b03e622b91a250506000600455565b6000908152600160205260409020600201546001600160801b031690565b33600090815260208190526040902054600114610c8d576040805162461bcd60e51b81526020600482015260166024820152600080516020612046833981519152604482015290519081900360640190fd5b6001600160a01b038116600081815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b6108ce8282611a04565b60006020819052908152604090205481565b6000908152600160205260409020600201546001600160801b03808216600160801b909204161090565b6000908152600160205260409020546001600160a01b031690565b600090815260016020526040902054600160d01b900465ffffffffffff1690565b60009081526001602081905260409091200154600160d01b900460ff1690565b60045415610db6576040805162461bcd60e51b81526020600482015260156024820152600080516020612026833981519152604482015290519081900360640190fd5b60016004819055600083815260209190915260409020546001600160a01b03163314610e29576040805162461bcd60e51b815260206004820152601a60248201527f447373566573742f6f6e6c792d757365722d63616e2d6d6f7665000000000000604482015290519081900360640190fd5b6001600160a01b038116610e84576040805162461bcd60e51b815260206004820152601c60248201527f447373566573742f7a65726f2d616464726573732d696e76616c696400000000604482015290519081900360640190fd5b60008281526001602052604080822080546001600160a01b0319166001600160a01b0385169081179091559051909184917f8ceddd02f4fb8ef0d5d6212cf4c91d59d366e04b977e8b2b944168d2a6d850819190a350506000600455565b6000600454600014610f29576040805162461bcd60e51b81526020600482015260156024820152600080516020612026833981519152604482015290519081900360640190fd5b600160048190553360009081526020819052604090205414610f80576040805162461bcd60e51b81526020600482015260166024820152600080516020612046833981519152604482015290519081900360640190fd5b6001600160a01b038716610fd2576040805162461bcd60e51b81526020600482015260146024820152732239b9ab32b9ba17b4b73b30b634b216bab9b2b960611b604482015290519081900360640190fd5b60008611611027576040805162461bcd60e51b815260206004820152601c60248201527f447373566573742f6e6f2d766573742d746f74616c2d616d6f756e7400000000604482015290519081900360640190fd5b611035426325980600611c70565b851061107e576040805162461bcd60e51b81526020600482015260136024820152722239b9ab32b9ba17b133b716ba37b796b330b960691b604482015290519081900360640190fd5b61108c426325980600611cc5565b85116110df576040805162461bcd60e51b815260206004820152601860248201527f447373566573742f62676e2d746f6f2d6c6f6e672d61676f0000000000000000604482015290519081900360640190fd5b60008411611127576040805162461bcd60e51b815260206004820152601060248201526f447373566573742f7461752d7a65726f60801b604482015290519081900360640190fd5b60025484878161113357fe5b04111561117f576040805162461bcd60e51b8152602060048201526015602482015274088e6e6accae6e85ee4c2e8ca5ae8dede5ad0d2ced605b1b604482015290519081900360640190fd5b63259806008411156111cf576040805162461bcd60e51b8152602060048201526014602482015273447373566573742f7461752d746f6f2d6c6f6e6760601b604482015290519081900360640190fd5b8383111561121b576040805162461bcd60e51b8152602060048201526014602482015273447373566573742f6574612d746f6f2d6c6f6e6760601b604482015290519081900360640190fd5b6000196003541061126a576040805162461bcd60e51b8152602060048201526014602482015273447373566573742f6964732d6f766572666c6f7760601b604482015290519081900360640190fd5b5060038054600101908190556040805161010081019091526001600160a01b03881681526020810161129b87611d15565b65ffffffffffff1681526020016112ba6112b58887611c70565b611d15565b65ffffffffffff1681526020016112d46112b58888611c70565b65ffffffffffff1681526001600160a01b03841660208201526000604082015260600161130088611d72565b6001600160801b03908116825260006020928301819052848152600180845260408083208651815496880151888401516001600160a01b03199098166001600160a01b039283161765ffffffffffff60a01b1916600160a01b65ffffffffffff92831602176001600160d01b0316600160d01b98821689021783556060890151948301805460808b015160a08c015165ffffffffffff1990921697909316969096176601000000000000600160d01b031916600160301b928416929092029190911760ff60d01b191660ff9095169097029390931790955560c08601516002909501805460e0909701516001600160801b0319909716958516959095178416600160801b96909416959095029290921790925591519189169183917f2e3cc5298d3204a0f0fc2be0f6fdefcef002025f4c75caf950b23e6cfbfb78d091a360006004559695505050505050565b60009081526001602081905260409091200154600160301b90046001600160a01b031690565b600090815260016020526040902060020154600160801b90046001600160801b031690565b6000908152600160208190526040909120015465ffffffffffff1690565b60035481565b60006114c6611fe1565b5060008281526001602081815260409283902083516101008101855281546001600160a01b03808216808452600160a01b830465ffffffffffff90811696850196909652600160d01b92839004861697840197909752948301549384166060830152600160301b840490941660808201529290910460ff1660a0830152600201546001600160801b0380821660c0840152600160801b9091041660e0820152906115af576040805162461bcd60e51b8152602060048201526015602482015274111cdcd5995cdd0bda5b9d985b1a590b585dd85c99605a1b604482015290519081900360640190fd5b6109e742826020015183606001518460c00151611dd0565b60016020819052600091825260409091208054918101546002909101546001600160a01b038084169365ffffffffffff600160a01b8204811694600160d01b9283900482169491811693600160301b8204169260ff910416906001600160801b0380821691600160801b90041688565b6004541561167a576040805162461bcd60e51b81526020600482015260156024820152600080516020612026833981519152604482015290519081900360640190fd5b600160048190553360009081526020819052604090205414806116be575060008281526001602081905260409091200154600160301b90046001600160a01b031633145b6116fd576040805162461bcd60e51b81526020600482015260166024820152600080516020612046833981519152604482015290519081900360640190fd5b611705611fe1565b5060008281526001602081815260409283902083516101008101855281546001600160a01b03808216808452600160a01b830465ffffffffffff90811696850196909652600160d01b92839004861697840197909752948301549384166060830152600160301b840490941660808201529290910460ff1660a0830152600201546001600160801b0380821660c0840152600160801b9091041660e0820152906117ee576040805162461bcd60e51b8152602060048201526015602482015274111cdcd5995cdd0bda5b9d985b1a590b585dd85c99605a1b604482015290519081900360640190fd5b428210156117fa574291505b806060015165ffffffffffff1682101561198257600061181983611d15565b600085815260016020818152604090922001805465ffffffffffff191665ffffffffffff848116918217909255918501519293509190911611156118b3576000848152600160205260409020805465ffffffffffff60a01b1916600160a01b65ffffffffffff8416908102919091176001600160d01b0316600160d01b9190910217815560020180546001600160801b0319169055611980565b816040015165ffffffffffff168165ffffffffffff16101561191057600084815260016020526040902080546001600160d01b0316600160d01b65ffffffffffff84160217815560020180546001600160801b0319169055611980565b61195061194b611938858560200151866040015187606001518860c001518960e001516119c2565b8460e001516001600160801b0316611c70565b611d72565b600085815260016020526040902060020180546001600160801b0319166001600160801b03929092169190911790555b505b60408051838152905184917f6f2a3ed78a3066d89360b6c89e52bf3313f52e859401a3ea5fa0f033fd540c3c919081900360200190a25050600060045550565b60008465ffffffffffff1687106119f6576119f16119e288888787611dd0565b836001600160801b0316611cc5565b6119f9565b60005b979650505050505050565b60045415611a47576040805162461bcd60e51b81526020600482015260156024820152600080516020612026833981519152604482015290519081900360640190fd5b6001600455611a54611fe1565b5060008281526001602081815260409283902083516101008101855281546001600160a01b03808216808452600160a01b830465ffffffffffff90811696850196909652600160d01b92839004861697840197909752948301549384166060830152600160301b840490941660808201529290910460ff1660a0830152600201546001600160801b0380821660c0840152600160801b9091041660e082015290611b3d576040805162461bcd60e51b8152602060048201526015602482015274111cdcd5995cdd0bda5b9d985b1a590b585dd85c99605a1b604482015290519081900360640190fd5b60a081015160ff161580611b5a575080516001600160a01b031633145b611bab576040805162461bcd60e51b815260206004820152601b60248201527f447373566573742f6f6e6c792d757365722d63616e2d636c61696d0000000000604482015290519081900360640190fd5b6000611bcf428360200151846040015185606001518660c001518760e001516119c2565b9050611bdb8184611e5a565b9050611bf761194b8360e001516001600160801b031683611c70565b600085815260016020526040902060020180546001600160801b03928316600160801b0292169190911790558151611c2f9082611e6f565b60408051828152905185917fa2906882572b0e9dfe893158bb064bc308eb1bd87d1da481850f9d17fc293847919081900360200190a2505060006004555050565b80820182811015611cbf576040805162461bcd60e51b8152602060048201526014602482015273447373566573742f6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b92915050565b80820382811115611cbf576040805162461bcd60e51b8152602060048201526015602482015274447373566573742f7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b8065ffffffffffff81168114610608576040805162461bcd60e51b815260206004820152601760248201527f447373566573742f75696e7434382d6f766572666c6f77000000000000000000604482015290519081900360640190fd5b806001600160801b0381168114610608576040805162461bcd60e51b815260206004820152601860248201527f447373566573742f75696e743132382d6f766572666c6f770000000000000000604482015290519081900360640190fd5b60008365ffffffffffff16851015611dea57506000611e52565b8265ffffffffffff168510611e0957506001600160801b038116611e52565b611e238365ffffffffffff168565ffffffffffff16611cc5565b611e47836001600160801b0316611e42888865ffffffffffff16611cc5565b611f7e565b81611e4e57fe5b0490505b949350505050565b6000818311611e6957826109e7565b50919050565b7f000000000000000000000000c20059e0317de91738d13af027dfc4a50781b0666001600160a01b03166323b872dd7f000000000000000000000000be8e3e3618f7474f8cb1d074a26affef007e98fb84846040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b158015611f1757600080fd5b505af1158015611f2b573d6000803e3d6000fd5b505050506040513d6020811015611f4157600080fd5b50516108ce5760405162461bcd60e51b81526004018080602001828103825260248152602001806120666024913960400191505060405180910390fd5b6000811580611f9957505080820282828281611f9657fe5b04145b611cbf576040805162461bcd60e51b8152602060048201526014602482015273447373566573742f6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091529056fe447373566573742f73797374656d2d6c6f636b65640000000000000000000000447373566573742f6e6f742d617574686f72697a656400000000000000000000447373566573745472616e736665727261626c652f6661696c65642d7472616e73666572a264697066735822122070c6655d2fddd6541b3d9a4c897bab2c677ca1581501bfeb3fea9b0cfc28e14964736f6c634300060c0033

Verified Source Code Full Match

Compiler: v0.6.12+commit.27d51765 EVM: istanbul Optimization: Yes (200 runs)
DssVest.sol 500 lines
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// DssVest - Token vesting contract
//
// Copyright (C) 2021 Dai Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity 0.6.12;

interface MintLike {
    function mint(address, uint256) external;
}

interface ChainlogLike {
    function getAddress(bytes32) external view returns (address);
}

interface JoinLike {
    function exit(address, uint256) external;
    function vat() external view returns (address);
}

interface VatLike {
    function hope(address) external;
    function suck(address, address, uint256) external;
    function live() external view returns (uint256);
}

interface TokenLike {
    function transferFrom(address, address, uint256) external returns (bool);
}

abstract contract DssVest {
    // --- Data ---
    mapping (address => uint256) public wards;

    struct Award {
        address usr;   // Vesting recipient
        uint48  bgn;   // Start of vesting period  [timestamp]
        uint48  clf;   // The cliff date           [timestamp]
        uint48  fin;   // End of vesting period    [timestamp]
        address mgr;   // A manager address that can yank
        uint8   res;   // Restricted
        uint128 tot;   // Total reward amount
        uint128 rxd;   // Amount of vest claimed
    }
    mapping (uint256 => Award) public awards;

    uint256 public cap; // Maximum per-second issuance token rate

    uint256 public ids; // Total vestings

    uint256 internal locked;

    uint256 public constant  TWENTY_YEARS = 20 * 365 days;

    // --- Events ---
    event Rely(address indexed usr);
    event Deny(address indexed usr);

    event File(bytes32 indexed what, uint256 data);

    event Init(uint256 indexed id, address indexed usr);
    event Vest(uint256 indexed id, uint256 amt);
    event Restrict(uint256 indexed id);
    event Unrestrict(uint256 indexed id);
    event Yank(uint256 indexed id, uint256 end);
    event Move(uint256 indexed id, address indexed dst);

    // Getters to access only to the value desired
    function usr(uint256 _id) external view returns (address) {
        return awards[_id].usr;
    }

    function bgn(uint256 _id) external view returns (uint256) {
        return awards[_id].bgn;
    }

    function clf(uint256 _id) external view returns (uint256) {
        return awards[_id].clf;
    }

    function fin(uint256 _id) external view returns (uint256) {
        return awards[_id].fin;
    }

    function mgr(uint256 _id) external view returns (address) {
        return awards[_id].mgr;
    }

    function res(uint256 _id) external view returns (uint256) {
        return awards[_id].res;
    }

    function tot(uint256 _id) external view returns (uint256) {
        return awards[_id].tot;
    }

    function rxd(uint256 _id) external view returns (uint256) {
        return awards[_id].rxd;
    }

    /**
        @dev Base vesting logic contract constructor
    */
    constructor() public {
        wards[msg.sender] = 1;
        emit Rely(msg.sender);
    }

    // --- Mutex ---
    modifier lock {
        require(locked == 0, "DssVest/system-locked");
        locked = 1;
        _;
        locked = 0;
    }

    // --- Auth ---
    modifier auth {
        require(wards[msg.sender] == 1, "DssVest/not-authorized");
        _;
    }

    function rely(address _usr) external auth {
        wards[_usr] = 1;
        emit Rely(_usr);
    }
    function deny(address _usr) external auth {
        wards[_usr] = 0;
        emit Deny(_usr);
    }

    /**
        @dev (Required) Set the per-second token issuance rate.
        @param what  The tag of the value to change (ex. bytes32("cap"))
        @param data  The value to update (ex. cap of 1000 tokens/yr == 1000*WAD/365 days)
    */
    function file(bytes32 what, uint256 data) external lock auth {
        if      (what == "cap")         cap = data;     // The maximum amount of tokens that can be streamed per-second per vest
        else revert("DssVest/file-unrecognized-param");
        emit File(what, data);
    }

    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x > y ? y : x;
    }
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "DssVest/add-overflow");
    }
    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "DssVest/sub-underflow");
    }
    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "DssVest/mul-overflow");
    }
    function toUint48(uint256 x) internal pure returns (uint48 z) {
        require((z = uint48(x)) == x, "DssVest/uint48-overflow");
    }
    function toUint128(uint256 x) internal pure returns (uint128 z) {
        require((z = uint128(x)) == x, "DssVest/uint128-overflow");
    }

    /**
        @dev Govanance adds a vesting contract
        @param _usr The recipient of the reward
        @param _tot The total amount of the vest
        @param _bgn The starting timestamp of the vest
        @param _tau The duration of the vest (in seconds)
        @param _eta The cliff duration in seconds (i.e. 1 years)
        @param _mgr An optional manager for the contract. Can yank if vesting ends prematurely.
        @return id  The id of the vesting contract
    */
    function create(address _usr, uint256 _tot, uint256 _bgn, uint256 _tau, uint256 _eta, address _mgr) external lock auth returns (uint256 id) {
        require(_usr != address(0),                        "DssVest/invalid-user");
        require(_tot > 0,                                  "DssVest/no-vest-total-amount");
        require(_bgn < add(block.timestamp, TWENTY_YEARS), "DssVest/bgn-too-far");
        require(_bgn > sub(block.timestamp, TWENTY_YEARS), "DssVest/bgn-too-long-ago");
        require(_tau > 0,                                  "DssVest/tau-zero");
        require(_tot / _tau <= cap,                        "DssVest/rate-too-high");
        require(_tau <= TWENTY_YEARS,                      "DssVest/tau-too-long");
        require(_eta <= _tau,                              "DssVest/eta-too-long");
        require(ids < type(uint256).max,                   "DssVest/ids-overflow");

        id = ++ids;
        awards[id] = Award({
            usr: _usr,
            bgn: toUint48(_bgn),
            clf: toUint48(add(_bgn, _eta)),
            fin: toUint48(add(_bgn, _tau)),
            tot: toUint128(_tot),
            rxd: 0,
            mgr: _mgr,
            res: 0
        });
        emit Init(id, _usr);
    }

    /**
        @dev Anyone (or only owner of a vesting contract if restricted) calls this to claim all available rewards
        @param _id     The id of the vesting contract
    */
    function vest(uint256 _id) external {
        _vest(_id, type(uint256).max);
    }

    /**
        @dev Anyone (or only owner of a vesting contract if restricted) calls this to claim rewards
        @param _id     The id of the vesting contract
        @param _maxAmt The maximum amount to vest
    */
    function vest(uint256 _id, uint256 _maxAmt) external {
        _vest(_id, _maxAmt);
    }

    /**
        @dev Anyone (or only owner of a vesting contract if restricted) calls this to claim rewards
        @param _id     The id of the vesting contract
        @param _maxAmt The maximum amount to vest
    */
    function _vest(uint256 _id, uint256 _maxAmt) internal lock {
        Award memory _award = awards[_id];
        require(_award.usr != address(0), "DssVest/invalid-award");
        require(_award.res == 0 || _award.usr == msg.sender, "DssVest/only-user-can-claim");
        uint256 amt = unpaid(block.timestamp, _award.bgn, _award.clf, _award.fin, _award.tot, _award.rxd);
        amt = min(amt, _maxAmt);
        awards[_id].rxd = toUint128(add(_award.rxd, amt));
        pay(_award.usr, amt);
        emit Vest(_id, amt);
    }

    /**
        @dev amount of tokens accrued, not accounting for tokens paid
        @param _id  The id of the vesting contract
        @return amt The accrued amount
    */
    function accrued(uint256 _id) external view returns (uint256 amt) {
        Award memory _award = awards[_id];
        require(_award.usr != address(0), "DssVest/invalid-award");
        amt = accrued(block.timestamp, _award.bgn, _award.fin, _award.tot);
    }

    /**
        @dev amount of tokens accrued, not accounting for tokens paid
        @param _time The timestamp to perform the calculation
        @param _bgn  The start time of the contract
        @param _fin  The end time of the contract
        @param _tot  The total amount of the contract
        @return amt  The accrued amount
    */
    function accrued(uint256 _time, uint48 _bgn, uint48 _fin, uint128 _tot) internal pure returns (uint256 amt) {
        if (_time < _bgn) {
            amt = 0;
        } else if (_time >= _fin) {
            amt = _tot;
        } else {
            amt = mul(_tot, sub(_time, _bgn)) / sub(_fin, _bgn); // 0 <= amt < _award.tot
        }
    }

    /**
        @dev return the amount of vested, claimable GEM for a given ID
        @param _id  The id of the vesting contract
        @return amt The claimable amount
    */
    function unpaid(uint256 _id) external view returns (uint256 amt) {
        Award memory _award = awards[_id];
        require(_award.usr != address(0), "DssVest/invalid-award");
        amt = unpaid(block.timestamp, _award.bgn, _award.clf, _award.fin, _award.tot, _award.rxd);
    }

    /**
        @dev amount of tokens accrued, not accounting for tokens paid
        @param _time The timestamp to perform the calculation
        @param _bgn  The start time of the contract
        @param _clf  The timestamp of the cliff
        @param _fin  The end time of the contract
        @param _tot  The total amount of the contract
        @param _rxd  The number of gems received
        @return amt  The claimable amount
    */
    function unpaid(uint256 _time, uint48 _bgn, uint48 _clf, uint48 _fin, uint128 _tot, uint128 _rxd) internal pure returns (uint256 amt) {
        amt = _time < _clf ? 0 : sub(accrued(_time, _bgn, _fin, _tot), _rxd);
    }

    /**
        @dev Allows governance or the owner to restrict vesting to the owner only
        @param _id The id of the vesting contract
    */
    function restrict(uint256 _id) external lock {
        address usr_ = awards[_id].usr;
        require(usr_ != address(0), "DssVest/invalid-award");
        require(wards[msg.sender] == 1 || usr_ == msg.sender, "DssVest/not-authorized");
        awards[_id].res = 1;
        emit Restrict(_id);
    }

    /**
        @dev Allows governance or the owner to enable permissionless vesting
        @param _id The id of the vesting contract
    */
    function unrestrict(uint256 _id) external lock {
        address usr_ = awards[_id].usr;
        require(usr_ != address(0), "DssVest/invalid-award");
        require(wards[msg.sender] == 1 || usr_ == msg.sender, "DssVest/not-authorized");
        awards[_id].res = 0;
        emit Unrestrict(_id);
    }

    /**
        @dev Allows governance or the manager to remove a vesting contract immediately
        @param _id The id of the vesting contract
    */
    function yank(uint256 _id) external {
        _yank(_id, block.timestamp);
    }

    /**
        @dev Allows governance or the manager to remove a vesting contract at a future time
        @param _id  The id of the vesting contract
        @param _end A scheduled time to end the vest
    */
    function yank(uint256 _id, uint256 _end) external {
        _yank(_id, _end);
    }

    /**
        @dev Allows governance or the manager to end pre-maturely a vesting contract
        @param _id  The id of the vesting contract
        @param _end A scheduled time to end the vest
    */
    function _yank(uint256 _id, uint256 _end) internal lock {
        require(wards[msg.sender] == 1 || awards[_id].mgr == msg.sender, "DssVest/not-authorized");
        Award memory _award = awards[_id];
        require(_award.usr != address(0), "DssVest/invalid-award");
        if (_end < block.timestamp) {
            _end = block.timestamp;
        }
        if (_end < _award.fin) {
            uint48 end = toUint48(_end);
            awards[_id].fin = end;
            if (end < _award.bgn) {
                awards[_id].bgn = end;
                awards[_id].clf = end;
                awards[_id].tot = 0;
            } else if (end < _award.clf) {
                awards[_id].clf = end;
                awards[_id].tot = 0;
            } else {
                awards[_id].tot = toUint128(
                                    add(
                                        unpaid(_end, _award.bgn, _award.clf, _award.fin, _award.tot, _award.rxd),
                                        _award.rxd
                                    )
                                );
            }
        }

        emit Yank(_id, _end);
    }

    /**
        @dev Allows owner to move a contract to a different address
        @param _id  The id of the vesting contract
        @param _dst The address to send ownership of the contract to
    */
    function move(uint256 _id, address _dst) external lock {
        require(awards[_id].usr == msg.sender, "DssVest/only-user-can-move");
        require(_dst != address(0), "DssVest/zero-address-invalid");
        awards[_id].usr = _dst;
        emit Move(_id, _dst);
    }

    /**
        @dev Return true if a contract is valid
        @param _id The id of the vesting contract
        @return isValid True for valid contract
    */
    function valid(uint256 _id) external view returns (bool isValid) {
        isValid = awards[_id].rxd < awards[_id].tot;
    }

    /**
        @dev Override this to implement payment logic.
        @param _guy The payment target.
        @param _amt The payment amount. [units are implementation-specific]
    */
    function pay(address _guy, uint256 _amt) virtual internal;
}

contract DssVestMintable is DssVest {

    MintLike public immutable gem;

    /**
        @dev This contract must be authorized to 'mint' on the token
        @param _gem The contract address of the mintable token
    */
    constructor(address _gem) public DssVest() {
        require(_gem != address(0), "DssVestMintable/Invalid-token-address");
        gem = MintLike(_gem);
    }

    /**
        @dev Override pay to handle mint logic
        @param _guy The recipient of the minted token
        @param _amt The amount of token units to send to the _guy
    */
    function pay(address _guy, uint256 _amt) override internal {
        gem.mint(_guy, _amt);
    }
}

contract DssVestSuckable is DssVest {

    uint256 internal constant RAY = 10**27;

    ChainlogLike public immutable chainlog;
    VatLike      public immutable vat;
    JoinLike     public immutable join;

    /**
        @dev This contract must be authorized to 'suck' on the vat
        @param _chainlog The contract address of the MCD chainlog
        @param _join The native join contract from MCD
    */
    constructor(address _chainlog, address _join) public DssVest() {
        require(_chainlog != address(0), "DssVestSuckable/invalid-chainlog-address");
        ChainlogLike chainlog_ = chainlog = ChainlogLike(_chainlog);

        VatLike vat_ = vat = VatLike(chainlog_.getAddress("MCD_VAT"));

        require(JoinLike(_join).vat() == address(vat_), "DssVestSuckable/invalid-join-vat");
        join = JoinLike(_join);

        vat_.hope(_join);
    }

    /**
        @dev Override pay to handle suck logic
        @param _guy The recipient of the ERC-20 Dai
        @param _amt The amount of Dai to send to the _guy [WAD]
    */
    function pay(address _guy, uint256 _amt) override internal {
        require(vat.live() == 1, "DssVestSuckable/vat-not-live");
        vat.suck(chainlog.getAddress("MCD_VOW"), address(this), mul(_amt, RAY));
        join.exit(_guy, _amt);
    }

    /**
        @dev Compatibility with older implementations of `DssVestSuckable`
    */
    function daiJoin() external view returns (address) {
        return address(join);
    }
}

/*
    Transferrable token DssVest. Can be used to enable streaming payments of
     any arbitrary token from an address (i.e. CU multisig) to individual
     contributors.
*/
contract DssVestTransferrable is DssVest {

    address   public immutable czar;
    TokenLike public immutable gem;

    /**
        @dev This contract must be approved for transfer of the gem on the czar
        @param _czar The owner of the tokens to be distributed
        @param _gem  The token to be distributed
    */
    constructor(address _czar, address _gem) public DssVest() {
        require(_czar != address(0), "DssVestTransferrable/Invalid-distributor-address");
        require(_gem  != address(0), "DssVestTransferrable/Invalid-token-address");
        czar = _czar;
        gem  = TokenLike(_gem);
    }

    /**
        @dev Override pay to handle transfer logic
        @param _guy The recipient of the ERC-20 Dai
        @param _amt The amount of gem to send to the _guy (in native token units)
    */
    function pay(address _guy, uint256 _amt) override internal {
        require(gem.transferFrom(czar, _guy, _amt), "DssVestTransferrable/failed-transfer");
    }
}

Read Contract

TWENTY_YEARS 0x60fb494b → uint256
accrued 0xf52981f4 → uint256
awards 0xfc5a5b63 → address, uint48, uint48, uint48, address, uint8, uint128, uint128
bgn 0x21f6c0cf → uint256
cap 0x355274ea → uint256
clf 0xcdf43497 → uint256
czar 0x1a8d3a6c → address
fin 0xe529780d → uint256
gem 0x7bd2bea7 → address
ids 0xe7657e15 → uint256
mgr 0xdc2c788f → address
res 0xd4e8fd2e → uint256
rxd 0xe054720f → uint256
tot 0x892de51d → uint256
unpaid 0x53e8863d → uint256
usr 0xc659cd45 → address
valid 0xbf8712c5 → bool
wards 0xbf353dbb → uint256

Write Contract 11 functions

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

create 0xdb64ff8f
address _usr
uint256 _tot
uint256 _bgn
uint256 _tau
uint256 _eta
address _mgr
returns: uint256
deny 0x9c52a7f1
address _usr
file 0x29ae8114
bytes32 what
uint256 data
move 0xd8a8e03a
uint256 _id
address _dst
rely 0x65fae35e
address _usr
restrict 0x3c433d5f
uint256 _id
unrestrict 0x7d8d2702
uint256 _id
vest 0x6a760b80
uint256 _id
vest 0xbb7c46f3
uint256 _id
uint256 _maxAmt
yank 0x26e027f1
uint256 _id
yank 0x509aaa1d
uint256 _id
uint256 _end

Recent Transactions

No transactions found for this address