Address Contract Partially Verified
Address
0xed0527fB909BbE5CE0CD3b80a556D3524500bfdc
Balance
0 ETH
Nonce
1
Code Size
7760 bytes
Creator
0xe0415762...a1c4 at tx 0x3aa1bdd4...fedd28
Indexed Transactions
0 (1 on-chain, 1.6% indexed)
Contract Bytecode
7760 bytes
0x6080604052600436106101985760003560e01c806385701c4d116100e0578063b1e1053311610084578063f2fde38b11610061578063f2fde38b14610514578063f51321d714610534578063f7c469f014610554578063f9079b37146105c957005b8063b1e105331461048e578063dd62ed3e146104ae578063ea1bb3d5146104f457005b806395d89b41116100bd57806395d89b41146104195780639ef346b41461042e578063a457c2d71461044e578063a9059cbb1461046e57005b806385701c4d1461036f5780638af104da1461038f5780638da5cb5b146103f157005b8063313ce567116101475780635a7bb69a116101245780635a7bb69a146102c157806370a08231146102f7578063715018a61461032d5780637e913dc61461034257005b8063313ce56714610270578063395093511461028c57806348deb471146102ac57005b806317e289e91161017557806317e289e91461021b57806318160ddd1461023b57806323b872dd1461025057005b806306fdde03146101a1578063095ea7b3146101cc57806313083617146101fc57005b3661019f57005b005b3480156101ad57600080fd5b506101b66105e9565b6040516101c39190611a58565b60405180910390f35b3480156101d857600080fd5b506101ec6101e7366004611ae7565b61067b565b60405190151581526020016101c3565b34801561020857600080fd5b506006545b6040519081526020016101c3565b34801561022757600080fd5b5061019f610236366004611b21565b610691565b34801561024757600080fd5b5060025461020d565b34801561025c57600080fd5b506101ec61026b366004611b84565b610ad6565b34801561027c57600080fd5b50604051601281526020016101c3565b34801561029857600080fd5b506101ec6102a7366004611ae7565b610b95565b3480156102b857600080fd5b5060085461020d565b3480156102cd57600080fd5b5061020d6102dc366004611bc0565b6001600160a01b031660009081526009602052604090205490565b34801561030357600080fd5b5061020d610312366004611bc0565b6001600160a01b031660009081526020819052604090205490565b34801561033957600080fd5b5061019f610bd1565b34801561034e57600080fd5b5061036261035d366004611bc0565b610c37565b6040516101c39190611bdb565b34801561037b57600080fd5b5061020d61038a366004611bc0565b610d6c565b34801561039b57600080fd5b5061020d6103aa366004611ae7565b6040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b3480156103fd57600080fd5b506005546040516001600160a01b0390911681526020016101c3565b34801561042557600080fd5b506101b6610e27565b34801561043a57600080fd5b50610362610449366004611c66565b610e36565b34801561045a57600080fd5b506101ec610469366004611ae7565b610f3a565b34801561047a57600080fd5b506101ec610489366004611ae7565b610feb565b34801561049a57600080fd5b5061019f6104a9366004611c7f565b610ff8565b3480156104ba57600080fd5b5061020d6104c9366004611ce2565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561050057600080fd5b5061020d61050f366004611c66565b611075565b34801561052057600080fd5b5061019f61052f366004611bc0565b6111e7565b34801561054057600080fd5b5061036261054f366004611ae7565b6112c9565b34801561056057600080fd5b5061020d61056f366004611bc0565b6001600160a01b0381166000908152600960209081526040808320548151606086901b6bffffffffffffffffffffffff19168185015260348082019290925282518082039092018252605401909152805191012092915050565b3480156105d557600080fd5b5061020d6105e4366004611c66565b61137e565b6060600380546105f890611d15565b80601f016020809104026020016040519081016040528092919081815260200182805461062490611d15565b80156106715780601f1061064657610100808354040283529160200191610671565b820191906000526020600020905b81548152906001019060200180831161065457829003601f168201915b5050505050905090565b6000610688338484611431565b50600192915050565b6005546001600160a01b031633146106f05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600084116107405760405162461bcd60e51b815260206004820152601460248201527f6475726174696f6e206d757374206265203e203000000000000000000000000060448201526064016106e7565b600081116107905760405162461bcd60e51b815260206004820152601260248201527f616d6f756e74206d757374206265203e2030000000000000000000000000000060448201526064016106e7565b838511156107e05760405162461bcd60e51b815260206004820152600d60248201527f696e76616c696420636c6966660000000000000000000000000000000000000060448201526064016106e7565b60018310156108315760405162461bcd60e51b815260206004820152601f60248201527f736c696365506572696f645365636f6e6473206d757374206265203e3d20310060448201526064016106e7565b6040517ff7c469f00000000000000000000000000000000000000000000000000000000081526001600160a01b0388166004820152600090309063f7c469f090602401602060405180830381865afa158015610891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b59190611d4a565b905060006108c3888861140d565b90506040518061014001604052806001151581526020018a6001600160a01b03168152602001828152602001898152602001878152602001868152602001851515815260200184815260200160008152602001600015158152506007600084815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010155606082015181600201556080820151816003015560a0820151816004015560c08201518160050160006101000a81548160ff02191690831515021790555060e0820151816006015561010082015181600701556101208201518160080160006101000a81548160ff021916908315150217905550905050610a138360085461140d90919063ffffffff16565b6008556006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f018390556001600160a01b038a1660009081526009602052604090205490610a6c90829061140d565b6001600160a01b038b166000818152600960209081526040918290209390935580518681529283019190915281018590527f9c550cbfc002e2d474c81a28bfec4830553d15cadbf57242afdc7510f2cb67149060600160405180910390a150505050505050505050565b6000610ae3848484611589565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610b7d5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084016106e7565b610b8a8533858403611431565b506001949350505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610688918590610bcc908690611d79565b611431565b6005546001600160a01b03163314610c2b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e7565b610c3560006117ad565b565b610c9c60405180610140016040528060001515815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000151581525090565b6001600160a01b03821660009081526009602052604081205460079190610ccb9085906103aa90600190611d91565b81526020808201929092526040908101600020815161014081018352815460ff808216151583526001600160a01b036101009283900416958301959095526001830154938201939093526002820154606082015260038201546080820152600482015460a082015260058201548416151560c0820152600682015460e082015260078201549281019290925260080154909116151561012082015292915050565b6001600160a01b038116600090815260096020526040812054600654811115610dd75760405162461bcd60e51b815260206004820152601360248201527f696e646578206f7574206f6620626f756e64730000000000000000000000000060448201526064016106e7565b6000805b82811015610e1f576000610def86836112c9565b90506000610dfc82611817565b9050610e08848261140d565b935050508080610e1790611da8565b915050610ddb565b509392505050565b6060600480546105f890611d15565b610e9b60405180610140016040528060001515815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000151581525090565b50600090815260076020818152604092839020835161014081018552815460ff808216151583526001600160a01b036101009283900416948301949094526001830154958201959095526002820154606082015260038201546080820152600482015460a082015260058201548316151560c0820152600682015460e08201529281015493830193909352600890920154909116151561012082015290565b3360009081526001602090815260408083206001600160a01b038616845290915281205482811015610fd45760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016106e7565b610fe13385858403611431565b5060019392505050565b6000610688338484611589565b6005546001600160a01b031633146110525760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e7565b6110618786868686868c610691565b61106b8787610feb565b5050505050505050565b600081815260076020526040812054829060ff1615156001146110da5760405162461bcd60e51b815260206004820152600e60248201527f6e6f7420696e7469616c697a656400000000000000000000000000000000000060448201526064016106e7565b60008181526007602052604090206008015460ff161561113c5760405162461bcd60e51b815260206004820152600f60248201527f616c7265616479207265766f6b6564000000000000000000000000000000000060448201526064016106e7565b600083815260076020818152604092839020835161014081018552815460ff808216151583526001600160a01b036101009283900416948301949094526001830154958201959095526002820154606082015260038201546080820152600482015460a082015260058201548316151560c0820152600682015460e0820152928101549383019390935260088301541615156101208201526111dd906118ee565b9250505b50919050565b6005546001600160a01b031633146112415760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106e7565b6001600160a01b0381166112bd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106e7565b6112c6816117ad565b50565b61132e60405180610140016040528060001515815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000151581525090565b60408051606085901b6bffffffffffffffffffffffff19166020808301919091526034808301869052835180840390910181526054909201909252805191012061137790610e36565b9392505050565b600061138960065490565b82106113d75760405162461bcd60e51b815260206004820152601360248201527f696e646578206f7574206f6620626f756e64730000000000000000000000000060448201526064016106e7565b600682815481106113ea576113ea611dc3565b90600052602060002001549050919050565b60006113778284611d91565b505050565b60006113778284611d79565b60006113778284611dd9565b60006113778284611dfb565b6001600160a01b0383166114ac5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016106e7565b6001600160a01b0382166115285760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016106e7565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166116055760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106e7565b6001600160a01b0382166116815760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106e7565b61168c8383836119bf565b6001600160a01b0383166000908152602081905260409020548181101561171b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016106e7565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290611752908490611d79565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161179e91815260200190565b60405180910390a35b50505050565b600580546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61012081015160009042901515600114156118355750600092915050565b826040015181101561184a57505060e0015190565b6080830151606084015161185d9161140d565b811061186c5750600092915050565b60006118858460600151836113fc90919063ffffffff16565b60a085015190915060006118998383611419565b905060006118a78284611425565b905060006118d088608001516118ca848b60e0015161142590919063ffffffff16565b90611419565b60e08901519091506118e290826113fc565b98975050505050505050565b6040810151600090429081108061190c575061012083015115156001145b1561191a5750600092915050565b6080830151606084015161192d9161140d565b81106119475761010083015160e0840151611377916113fc565b60006119608460600151836113fc90919063ffffffff16565b60a085015190915060006119748383611419565b905060006119828284611425565b905060006119a588608001516118ca848b60e0015161142590919063ffffffff16565b90506118e2886101000151826113fc90919063ffffffff16565b60006119ca84610d6c565b90506001600160a01b03841615611a5357611a04816119fe866001600160a01b031660009081526020819052604090205490565b906113fc565b821115611a535760405162461bcd60e51b815260206004820152601860248201527f636865636b2076657374696e67206f722062616c616e6365000000000000000060448201526064016106e7565b6117a7565b600060208083528351808285015260005b81811015611a8557858101830151858201604001528201611a69565b81811115611a97576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b80356001600160a01b0381168114611ae257600080fd5b919050565b60008060408385031215611afa57600080fd5b611b0383611acb565b946020939093013593505050565b80358015158114611ae257600080fd5b600080600080600080600060e0888a031215611b3c57600080fd5b611b4588611acb565b965060208801359550604088013594506060880135935060808801359250611b6f60a08901611b11565b915060c0880135905092959891949750929550565b600080600060608486031215611b9957600080fd5b611ba284611acb565b9250611bb060208501611acb565b9150604084013590509250925092565b600060208284031215611bd257600080fd5b61137782611acb565b81511515815261014081016020830151611c0060208401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151608083015260a083015160a083015260c0830151611c3c60c084018215159052565b5060e083810151908301526101008084015190830152610120928301511515929091019190915290565b600060208284031215611c7857600080fd5b5035919050565b600080600080600080600060e0888a031215611c9a57600080fd5b611ca388611acb565b96506020880135955060408801359450606088013593506080880135925060a08801359150611cd460c08901611b11565b905092959891949750929550565b60008060408385031215611cf557600080fd5b611cfe83611acb565b9150611d0c60208401611acb565b90509250929050565b600181811c90821680611d2957607f821691505b602082108114156111e157634e487b7160e01b600052602260045260246000fd5b600060208284031215611d5c57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115611d8c57611d8c611d63565b500190565b600082821015611da357611da3611d63565b500390565b6000600019821415611dbc57611dbc611d63565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600082611df657634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611e1557611e15611d63565b50029056fea264697066735822122020d2276b9032f8308842431cbd6d7974842f3c1101e37025c94bf831f26bb91564736f6c634300080b0033
Verified Source Code Partial Match
Compiler: v0.8.11+commit.d7f03943
EVM: london
Optimization: Yes (2000 runs)
Token.sol 580 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
pragma solidity ^0.8.0;
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
pragma solidity ^0.8.0;
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
pragma solidity ^0.8.0;
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
pragma solidity ^0.8.11;
contract Token is ERC20, Ownable {
using SafeMath for uint256;
struct VestingSchedule{
bool initialized;
address beneficiary;
uint256 cliff;
uint256 start;
uint256 duration;
uint256 slicePeriodSeconds;
bool revocable;
uint256 amountTotal;
uint256 released;
bool revoked;
}
bytes32[] private vestingSchedulesIds;
mapping(bytes32 => VestingSchedule) private vestingSchedules;
uint256 private vestingSchedulesTotalAmount;
mapping(address => uint256) private holdersVestingCount;
event Released(uint256 amount);
event Revoked(bytes32);
event VestingCreated(bytes32, address, uint256);
modifier onlyIfVestingScheduleExists(bytes32 vestingScheduleId) {
require(vestingSchedules[vestingScheduleId].initialized == true, "not intialized");
_;
}
modifier onlyIfVestingScheduleNotRevoked(bytes32 vestingScheduleId) {
require(vestingSchedules[vestingScheduleId].initialized == true, "not intialized");
require(vestingSchedules[vestingScheduleId].revoked == false, "already revoked");
_;
}
constructor(
string memory name,
string memory symbol,
uint256 initialSupply
) ERC20(name, symbol) {
_mint(msg.sender, initialSupply);
}
receive() external payable {}
fallback() external payable {}
function getVestingSchedulesCountByBeneficiary(address _beneficiary)
public
view
returns(uint256){
return holdersVestingCount[_beneficiary];
}
function getVestingIdAtIndex(uint256 index)
external
view
returns(bytes32){
require(index < getVestingSchedulesCount(), "index out of bounds");
return vestingSchedulesIds[index];
}
function getVestingScheduleByAddressAndIndex(address holder, uint256 index)
public
view
returns(VestingSchedule memory){
return getVestingSchedule(computeVestingScheduleIdForAddressAndIndex(holder, index));
}
function getVestingSchedulesTotalAmount()
external
view
returns(uint256){
return vestingSchedulesTotalAmount;
}
function createVestingSchedule(
address _beneficiary,
uint256 _start,
uint256 _cliff,
uint256 _duration,
uint256 _slicePeriodSeconds,
bool _revocable,
uint256 _amount
) onlyOwner() public {
require(_duration > 0, "duration must be > 0");
require(_amount > 0, "amount must be > 0");
require(_cliff <= _duration, "invalid cliff");
require(_slicePeriodSeconds >= 1, "slicePeriodSeconds must be >= 1");
bytes32 vestingScheduleId = this.computeNextVestingScheduleIdForHolder(_beneficiary);
uint256 cliff = _start.add(_cliff);
vestingSchedules[vestingScheduleId] = VestingSchedule(
true,
_beneficiary,
cliff,
_start,
_duration,
_slicePeriodSeconds,
_revocable,
_amount,
0,
false
);
vestingSchedulesTotalAmount = vestingSchedulesTotalAmount.add(_amount);
vestingSchedulesIds.push(vestingScheduleId);
uint256 currentVestingCount = holdersVestingCount[_beneficiary];
holdersVestingCount[_beneficiary] = currentVestingCount.add(1);
emit VestingCreated(vestingScheduleId, _beneficiary, _amount);
}
function getVestingSchedulesCount()
public
view
returns(uint256){
return vestingSchedulesIds.length;
}
function computeReleasableAmount(bytes32 vestingScheduleId)
public
onlyIfVestingScheduleNotRevoked(vestingScheduleId)
view
returns(uint256){
VestingSchedule storage vestingSchedule = vestingSchedules[vestingScheduleId];
return _computeReleasableAmount(vestingSchedule);
}
function computeLockedAmount(address holder)
public
view
returns(uint256) {
uint count = getVestingSchedulesCountByBeneficiary(holder);
require(count <= getVestingSchedulesCount(), "index out of bounds");
uint totalLocked = 0;
for (uint i = 0; i < count; i++) {
VestingSchedule memory vestingSchedule = getVestingScheduleByAddressAndIndex(holder, i);
uint256 lockedAmount = _computeLockedAmount(vestingSchedule);
totalLocked = totalLocked.add(lockedAmount);
}
return totalLocked;
}
function getVestingSchedule(bytes32 vestingScheduleId)
public
view
returns(VestingSchedule memory){
return vestingSchedules[vestingScheduleId];
}
function computeNextVestingScheduleIdForHolder(address holder)
public
view
returns(bytes32){
return computeVestingScheduleIdForAddressAndIndex(holder, holdersVestingCount[holder]);
}
function getLastVestingScheduleForHolder(address holder)
public
view
returns(VestingSchedule memory){
return vestingSchedules[computeVestingScheduleIdForAddressAndIndex(holder, holdersVestingCount[holder] - 1)];
}
function computeVestingScheduleIdForAddressAndIndex(address holder, uint256 index)
public
pure
returns(bytes32){
return keccak256(abi.encodePacked(holder, index));
}
function _computeReleasableAmount(VestingSchedule memory vestingSchedule)
internal
view
returns(uint256){
uint256 currentTime = getCurrentTime();
if ((currentTime < vestingSchedule.cliff) || vestingSchedule.revoked == true) {
return 0;
} else if (currentTime >= vestingSchedule.start.add(vestingSchedule.duration)) {
return vestingSchedule.amountTotal.sub(vestingSchedule.released);
} else {
uint256 timeFromStart = currentTime.sub(vestingSchedule.start);
uint secondsPerSlice = vestingSchedule.slicePeriodSeconds;
uint256 vestedSlicePeriods = timeFromStart.div(secondsPerSlice);
uint256 vestedSeconds = vestedSlicePeriods.mul(secondsPerSlice);
uint256 vestedAmount = vestingSchedule.amountTotal.mul(vestedSeconds).div(vestingSchedule.duration);
vestedAmount = vestedAmount.sub(vestingSchedule.released);
return vestedAmount;
}
}
function _computeLockedAmount(VestingSchedule memory vestingSchedule)
internal
view
returns(uint256){
uint256 currentTime = getCurrentTime();
if (vestingSchedule.revoked == true) {
return 0;
} else if ((currentTime < vestingSchedule.cliff)) {
return vestingSchedule.amountTotal;
} else if (currentTime >= vestingSchedule.start.add(vestingSchedule.duration)) {
return 0;
} else {
uint256 timeFromStart = currentTime.sub(vestingSchedule.start);
uint secondsPerSlice = vestingSchedule.slicePeriodSeconds;
uint256 vestedSlicePeriods = timeFromStart.div(secondsPerSlice);
uint256 vestedSeconds = vestedSlicePeriods.mul(secondsPerSlice);
uint256 vestedAmount = vestingSchedule.amountTotal.mul(vestedSeconds).div(vestingSchedule.duration);
return vestingSchedule.amountTotal.sub(vestedAmount);
}
}
function getCurrentTime()
internal
virtual
view
returns(uint256){
return block.timestamp;
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal override virtual {
uint totalLocked = computeLockedAmount(from);
if (from != address(0)) require(amount <= balanceOf(from).sub(totalLocked), 'check vesting or balance');
super._beforeTokenTransfer(from, to, amount);
}
function vestedTransfer(
address _recipient,
uint256 _amount,
uint256 _start,
uint256 _cliff,
uint256 _duration,
uint256 _slicePeriodSeconds,
bool _revocable
) onlyOwner() public virtual {
createVestingSchedule(_recipient, _start, _cliff, _duration, _slicePeriodSeconds, _revocable, _amount);
super.transfer(_recipient, _amount);
}
}
Read Contract
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
computeLockedAmount 0x85701c4d → uint256
computeNextVestingScheduleIdForHolder 0xf7c469f0 → bytes32
computeReleasableAmount 0xea1bb3d5 → uint256
computeVestingScheduleIdForAddressAndIndex 0x8af104da → bytes32
decimals 0x313ce567 → uint8
getLastVestingScheduleForHolder 0x7e913dc6 → tuple
getVestingIdAtIndex 0xf9079b37 → bytes32
getVestingSchedule 0x9ef346b4 → tuple
getVestingScheduleByAddressAndIndex 0xf51321d7 → tuple
getVestingSchedulesCount 0x13083617 → uint256
getVestingSchedulesCountByBeneficiary 0x5a7bb69a → uint256
getVestingSchedulesTotalAmount 0x48deb471 → uint256
name 0x06fdde03 → string
owner 0x8da5cb5b → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address spender
uint256 amount
returns: bool
createVestingSchedule 0x17e289e9
address _beneficiary
uint256 _start
uint256 _cliff
uint256 _duration
uint256 _slicePeriodSeconds
bool _revocable
uint256 _amount
decreaseAllowance 0xa457c2d7
address spender
uint256 subtractedValue
returns: bool
increaseAllowance 0x39509351
address spender
uint256 addedValue
returns: bool
renounceOwnership 0x715018a6
No parameters
transfer 0xa9059cbb
address recipient
uint256 amount
returns: bool
transferFrom 0x23b872dd
address sender
address recipient
uint256 amount
returns: bool
transferOwnership 0xf2fde38b
address newOwner
vestedTransfer 0xb1e10533
address _recipient
uint256 _amount
uint256 _start
uint256 _cliff
uint256 _duration
uint256 _slicePeriodSeconds
bool _revocable
Recent Transactions
This address has 1 on-chain transactions, but only 1.6% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →