Contract
0x1066a8eb3d90af0ad3f89839b974658577e75be2
14
Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
RewardEscrow
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; // Inheritance import "./utils/Owned.sol"; import "./interfaces/IRewardEscrow.sol"; // Libraries import "./libraries/SafeDecimalMath.sol"; // Internal references import "./interfaces/IKwenta.sol"; import "./interfaces/IStakingRewards.sol"; contract RewardEscrow is Owned, IRewardEscrow { using SafeDecimalMath for uint; /* ========== CONSTANTS/IMMUTABLES ========== */ /* Max escrow duration */ uint public constant MAX_DURATION = 2 * 52 weeks; // Default max 2 years duration IKwenta private immutable kwenta; /* ========== STATE VARIABLES ========== */ IStakingRewards public stakingRewards; mapping(address => mapping(uint256 => VestingEntries.VestingEntry)) public vestingSchedules; mapping(address => uint256[]) public accountVestingEntryIDs; // Counter for new vesting entry ids uint256 public nextEntryId; // An account's total escrowed KWENTA balance to save recomputing this for fee extraction purposes mapping(address => uint256) override public totalEscrowedAccountBalance; // An account's total vested reward KWENTA mapping(address => uint256) override public totalVestedAccountBalance; // The total remaining escrowed balance, for verifying the actual KWENTA balance of this contract against uint256 public totalEscrowedBalance; // notice treasury address may change address public treasuryDAO; /* ========== MODIFIERS ========== */ modifier onlyStakingRewards() { require(msg.sender == address(stakingRewards), "Only the StakingRewards can perform this action"); _; } /* ========== EVENTS ========== */ event Vested(address indexed beneficiary, uint value); event VestingEntryCreated(address indexed beneficiary, uint value, uint duration, uint entryID); event StakingRewardsSet(address stakingRewards); event TreasuryDAOSet(address treasuryDAO); /* ========== CONSTRUCTOR ========== */ constructor(address _owner, address _kwenta) Owned(_owner) { nextEntryId = 1; // set the Kwenta contract address as we need to transfer KWENTA when the user vests kwenta = IKwenta(_kwenta); } /* ========== SETTERS ========== */ /* * @notice Function used to define the StakingRewards to use */ function setStakingRewards(address _stakingRewards) public onlyOwner { require(address(stakingRewards) == address(0), "Staking Rewards already set"); stakingRewards = IStakingRewards(_stakingRewards); emit StakingRewardsSet(address(_stakingRewards)); } /// @notice set treasuryDAO address /// @dev only owner may change address function setTreasuryDAO(address _treasuryDAO) external onlyOwner { require(_treasuryDAO != address(0), "RewardEscrow: Zero Address"); treasuryDAO = _treasuryDAO; emit TreasuryDAOSet(treasuryDAO); } /* ========== VIEW FUNCTIONS ========== */ /** * @notice helper function to return kwenta address */ function getKwentaAddress() override external view returns (address) { return address(kwenta); } /** * @notice A simple alias to totalEscrowedAccountBalance: provides ERC20 balance integration. */ function balanceOf(address account) override public view returns (uint) { return totalEscrowedAccountBalance[account]; } /** * @notice The number of vesting dates in an account's schedule. */ function numVestingEntries(address account) override external view returns (uint) { return accountVestingEntryIDs[account].length; } /** * @notice Get a particular schedule entry for an account. * @return endTime the vesting entry object * @return escrowAmount rate per second emission. */ function getVestingEntry(address account, uint256 entryID) override external view returns (uint64 endTime, uint256 escrowAmount, uint256 duration) { endTime = vestingSchedules[account][entryID].endTime; escrowAmount = vestingSchedules[account][entryID].escrowAmount; duration = vestingSchedules[account][entryID].duration; } function getVestingSchedules( address account, uint256 index, uint256 pageSize ) override external view returns (VestingEntries.VestingEntryWithID[] memory) { uint256 endIndex = index + pageSize; // If index starts after the endIndex return no results if (endIndex <= index) { return new VestingEntries.VestingEntryWithID[](0); } // If the page extends past the end of the accountVestingEntryIDs, truncate it. if (endIndex > accountVestingEntryIDs[account].length) { endIndex = accountVestingEntryIDs[account].length; } uint256 n = endIndex - index; VestingEntries.VestingEntryWithID[] memory vestingEntries = new VestingEntries.VestingEntryWithID[](n); for (uint256 i; i < n; i++) { uint256 entryID = accountVestingEntryIDs[account][i + index]; VestingEntries.VestingEntry memory entry = vestingSchedules[account][entryID]; vestingEntries[i] = VestingEntries.VestingEntryWithID({ endTime: uint64(entry.endTime), escrowAmount: entry.escrowAmount, entryID: entryID }); } return vestingEntries; } function getAccountVestingEntryIDs( address account, uint256 index, uint256 pageSize ) override external view returns (uint256[] memory) { uint256 endIndex = index + pageSize; // If the page extends past the end of the accountVestingEntryIDs, truncate it. if (endIndex > accountVestingEntryIDs[account].length) { endIndex = accountVestingEntryIDs[account].length; } if (endIndex <= index) { return new uint256[](0); } uint256 n = endIndex - index; uint256[] memory page = new uint256[](n); for (uint256 i; i < n; i++) { page[i] = accountVestingEntryIDs[account][i + index]; } return page; } function getVestingQuantity(address account, uint256[] calldata entryIDs) override external view returns (uint total, uint totalFee) { for (uint i = 0; i < entryIDs.length; i++) { VestingEntries.VestingEntry memory entry = vestingSchedules[account][entryIDs[i]]; /* Skip entry if escrowAmount == 0 */ if (entry.escrowAmount != 0) { (uint256 quantity, uint256 fee) = _claimableAmount(entry); /* add quantity to total */ total += quantity; totalFee += fee; } } } function getVestingEntryClaimable(address account, uint256 entryID) override external view returns (uint quantity, uint fee) { VestingEntries.VestingEntry memory entry = vestingSchedules[account][entryID]; (quantity, fee) = _claimableAmount(entry); } function _claimableAmount(VestingEntries.VestingEntry memory _entry) internal view returns (uint256 quantity, uint256 fee) { uint256 escrowAmount = _entry.escrowAmount; if (escrowAmount != 0) { /* Full escrow amounts claimable if block.timestamp equal to or after entry endTime */ if (block.timestamp >= _entry.endTime) { quantity = escrowAmount; } else { fee = _earlyVestFee(_entry); quantity = escrowAmount - fee; } } } function _earlyVestFee(VestingEntries.VestingEntry memory _entry) internal view returns (uint256 earlyVestFee) { uint timeUntilVest = _entry.endTime - block.timestamp; // Fee starts at 90% and falls linearly uint initialFee = _entry.escrowAmount * 9 / 10; earlyVestFee = initialFee * timeUntilVest / _entry.duration; } function _isEscrowStaked(address _account) internal view returns (bool) { return stakingRewards.escrowedBalanceOf(_account) > 0; } /* ========== MUTATIVE FUNCTIONS ========== */ /** * Vest escrowed amounts that are claimable * Allows users to vest their vesting entries based on msg.sender */ function vest(uint256[] calldata entryIDs) override external { uint256 total; uint256 totalFee; for (uint i = 0; i < entryIDs.length; i++) { VestingEntries.VestingEntry storage entry = vestingSchedules[msg.sender][entryIDs[i]]; /* Skip entry if escrowAmount == 0 already vested */ if (entry.escrowAmount != 0) { (uint256 quantity, uint256 fee) = _claimableAmount(entry); /* update entry to remove escrowAmount */ entry.escrowAmount = 0; /* add quantity to total */ total += quantity; totalFee += fee; } } /* Transfer vested tokens. Will revert if total > totalEscrowedAccountBalance */ if (total != 0) { // Withdraw staked escrowed kwenta if needed for reward if (_isEscrowStaked(msg.sender)) { uint totalWithFee = total + totalFee; uint unstakedEscrow = totalEscrowedAccountBalance[msg.sender] - stakingRewards.escrowedBalanceOf(msg.sender); if (totalWithFee > unstakedEscrow) { uint amountToUnstake = totalWithFee - unstakedEscrow; unstakeEscrow(amountToUnstake); } } // Send any fee to Treasury if (totalFee != 0) { _reduceAccountEscrowBalances(msg.sender, totalFee); require( IKwenta(address(kwenta)) .transfer(treasuryDAO, totalFee), "RewardEscrow: Token Transfer Failed" ); } // Transfer kwenta _transferVestedTokens(msg.sender, total); } } /** * @notice Create an escrow entry to lock KWENTA for a given duration in seconds * @dev This call expects that the depositor (msg.sender) has already approved the Reward escrow contract * to spend the the amount being escrowed. */ function createEscrowEntry( address beneficiary, uint256 deposit, uint256 duration ) override external { require(beneficiary != address(0), "Cannot create escrow with address(0)"); /* Transfer KWENTA from msg.sender */ require(kwenta.transferFrom(msg.sender, address(this), deposit), "Token transfer failed"); /* Append vesting entry for the beneficiary address */ _appendVestingEntry(beneficiary, deposit, duration); } /** * @notice Add a new vesting entry at a given time and quantity to an account's schedule. * @dev A call to this should accompany a previous successful call to kwenta.transfer(rewardEscrow, amount), * to ensure that when the funds are withdrawn, there is enough balance. * @param account The account to append a new vesting entry to. * @param quantity The quantity of KWENTA that will be escrowed. * @param duration The duration that KWENTA will be emitted. */ function appendVestingEntry( address account, uint256 quantity, uint256 duration ) override external onlyStakingRewards { _appendVestingEntry(account, quantity, duration); } /** * @notice Stakes escrowed KWENTA. * @dev No tokens are transfered during this process, but the StakingRewards escrowed balance is updated. * @param _amount The amount of escrowed KWENTA to be staked. */ function stakeEscrow(uint256 _amount) override external { require(_amount + stakingRewards.escrowedBalanceOf(msg.sender) <= totalEscrowedAccountBalance[msg.sender], "Insufficient unstaked escrow"); stakingRewards.stakeEscrow(msg.sender, _amount); } /** * @notice Unstakes escrowed KWENTA. * @dev No tokens are transfered during this process, but the StakingRewards escrowed balance is updated. * @param _amount The amount of escrowed KWENTA to be unstaked. */ function unstakeEscrow(uint256 _amount) override public { stakingRewards.unstakeEscrow(msg.sender, _amount); } /* Transfer vested tokens and update totalEscrowedAccountBalance, totalVestedAccountBalance */ function _transferVestedTokens(address _account, uint256 _amount) internal { _reduceAccountEscrowBalances(_account, _amount); totalVestedAccountBalance[_account] += _amount; kwenta.transfer(_account, _amount); emit Vested(_account, _amount); } function _reduceAccountEscrowBalances(address _account, uint256 _amount) internal { // Reverts if amount being vested is greater than the account's existing totalEscrowedAccountBalance totalEscrowedBalance -= _amount; totalEscrowedAccountBalance[_account] -= _amount; } /* ========== INTERNALS ========== */ function _appendVestingEntry( address account, uint256 quantity, uint256 duration ) internal { /* No empty or already-passed vesting entries allowed. */ require(quantity != 0, "Quantity cannot be zero"); require(duration > 0 && duration <= MAX_DURATION, "Cannot escrow with 0 duration OR above max_duration"); /* There must be enough balance in the contract to provide for the vesting entry. */ totalEscrowedBalance += quantity; require( totalEscrowedBalance <= kwenta.balanceOf(address(this)), "Must be enough balance in the contract to provide for the vesting entry" ); /* Escrow the tokens for duration. */ uint endTime = block.timestamp + duration; /* Add quantity to account's escrowed balance */ totalEscrowedAccountBalance[account] += quantity; uint entryID = nextEntryId; vestingSchedules[account][entryID] = VestingEntries.VestingEntry({endTime: uint64(endTime), escrowAmount: quantity, duration: duration}); accountVestingEntryIDs[account].push(entryID); /* Increment the next entry id. */ nextEntryId++; emit VestingEntryCreated(account, quantity, duration, entryID); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // https://docs.synthetix.io/contracts/source/contracts/owned contract Owned { address public owner; address public nominatedOwner; constructor(address _owner) { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library VestingEntries { struct VestingEntry { uint64 endTime; uint256 escrowAmount; uint256 duration; } struct VestingEntryWithID { uint64 endTime; uint256 escrowAmount; uint256 entryID; } } interface IRewardEscrow { // Views function getKwentaAddress() external view returns (address); function balanceOf(address account) external view returns (uint256); function numVestingEntries(address account) external view returns (uint256); function totalEscrowedAccountBalance(address account) external view returns (uint256); function totalVestedAccountBalance(address account) external view returns (uint256); function getVestingQuantity(address account, uint256[] calldata entryIDs) external view returns (uint256, uint256); function getVestingSchedules( address account, uint256 index, uint256 pageSize ) external view returns (VestingEntries.VestingEntryWithID[] memory); function getAccountVestingEntryIDs( address account, uint256 index, uint256 pageSize ) external view returns (uint256[] memory); function getVestingEntryClaimable(address account, uint256 entryID) external view returns (uint256, uint256); function getVestingEntry(address account, uint256 entryID) external view returns ( uint64, uint256, uint256 ); // Mutative functions function vest(uint256[] calldata entryIDs) external; function createEscrowEntry( address beneficiary, uint256 deposit, uint256 duration ) external; function appendVestingEntry( address account, uint256 quantity, uint256 duration ) external; function stakeEscrow(uint256 _amount) external; function unstakeEscrow(uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // https://docs.synthetix.io/contracts/source/libraries/safedecimalmath library SafeDecimalMath { /* Number of decimal places in the representations. */ uint8 public constant decimals = 18; uint8 public constant highPrecisionDecimals = 27; /* The number representing 1.0. */ uint256 public constant UNIT = 10**uint256(decimals); /* The number representing 1.0 for higher fidelity numbers. */ uint256 public constant PRECISE_UNIT = 10**uint256(highPrecisionDecimals); uint256 private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint256(highPrecisionDecimals - decimals); /** * @return Provides an interface to UNIT. */ function unit() external pure returns (uint256) { return UNIT; } /** * @return Provides an interface to PRECISE_UNIT. */ function preciseUnit() external pure returns (uint256) { return PRECISE_UNIT; } /** * @return The result of multiplying x and y, interpreting the operands as fixed-point * decimals. * * @dev A unit factor is divided out after the product of x and y is evaluated, * so that product must be less than 2**256. As this is an integer division, * the internal division always rounds down. This helps save on gas. Rounding * is more expensive on gas. */ function multiplyDecimal(uint256 x, uint256 y) internal pure returns (uint256) { /* Divide by UNIT to remove the extra factor introduced by the product. */ return (x * y) / UNIT; } /** * @return The result of safely dividing x and y. The return value is a high * precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and UNIT must be less than 2**256. As * this is an integer division, the result is always rounded down. * This helps save on gas. Rounding is more expensive on gas. */ function divideDecimal(uint256 x, uint256 y) internal pure returns (uint256) { /* Reintroduce the UNIT factor that will be divided out by y. */ return (x * UNIT) / y; } /** * @dev Convert a standard decimal representation to a high precision one. */ function decimalToPreciseDecimal(uint256 i) internal pure returns (uint256) { return i * UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR; } /** * @dev Convert a high precision decimal to a standard decimal representation. */ function preciseDecimalToDecimal(uint256 i) internal pure returns (uint256) { uint256 quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } // Computes `a - b`, setting the value to 0 if b > a. function floorsub(uint256 a, uint256 b) internal pure returns (uint256) { return b >= a ? 0 : a - b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20.sol"; interface IKwenta is IERC20 { function mint(address account, uint amount) external; function burn(uint amount) external; function setSupplySchedule(address _supplySchedule) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IStakingRewards { /// VIEWS // token state function totalSupply() external view returns (uint256); // staking state function balanceOf(address account) external view returns (uint256); function escrowedBalanceOf(address account) external view returns (uint256); function nonEscrowedBalanceOf(address account) external view returns (uint256); // rewards function getRewardForDuration() external view returns (uint256); function rewardPerToken() external view returns (uint256); function lastTimeRewardApplicable() external view returns (uint256); function earned(address account) external view returns (uint256); /// MUTATIVE // Staking/Unstaking function stake(uint256 amount) external; function unstake(uint256 amount) external; function stakeEscrow(address account, uint256 amount) external; function unstakeEscrow(address account, uint256 amount) external; function exit() external; // claim rewards function getReward() external; // settings function notifyRewardAmount(uint256 reward) external; function setRewardsDuration(uint256 _rewardsDuration) external; // pausable function pauseStakingRewards() external; function unpauseStakingRewards() external; // misc. function recoverERC20(address tokenAddress, uint256 tokenAmount) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0 <0.9.0; /** * @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); }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../contracts/RewardEscrow.sol"; contract $RewardEscrow is RewardEscrow { constructor(address _owner, address _kwenta) RewardEscrow(_owner, _kwenta) {} function $_claimableAmount(VestingEntries.VestingEntry calldata _entry) external view returns (uint256, uint256) { return super._claimableAmount(_entry); } function $_earlyVestFee(VestingEntries.VestingEntry calldata _entry) external view returns (uint256) { return super._earlyVestFee(_entry); } function $_isEscrowStaked(address _account) external view returns (bool) { return super._isEscrowStaked(_account); } function $_transferVestedTokens(address _account,uint256 _amount) external { return super._transferVestedTokens(_account,_amount); } function $_reduceAccountEscrowBalances(address _account,uint256 _amount) external { return super._reduceAccountEscrowBalances(_account,_amount); } function $_appendVestingEntry(address account,uint256 quantity,uint256 duration) external { return super._appendVestingEntry(account,quantity,duration); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/interfaces/IERC20.sol"; abstract contract $IERC20 is IERC20 { constructor() {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/interfaces/IKwenta.sol"; abstract contract $IKwenta is IKwenta { constructor() {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/interfaces/IRewardEscrow.sol"; contract $VestingEntries { constructor() {} } abstract contract $IRewardEscrow is IRewardEscrow { constructor() {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/interfaces/IStakingRewards.sol"; abstract contract $IStakingRewards is IStakingRewards { constructor() {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.6.0; import "../../contracts/utils/Owned.sol"; contract $Owned is Owned { constructor(address _owner) Owned(_owner) {} }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_kwenta","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"stakingRewards","type":"address"}],"name":"StakingRewardsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"treasuryDAO","type":"address"}],"name":"TreasuryDAOSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Vested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"entryID","type":"uint256"}],"name":"VestingEntryCreated","type":"event"},{"inputs":[],"name":"MAX_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"accountVestingEntryIDs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"appendVestingEntry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"createEscrowEntry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getAccountVestingEntryIDs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getKwentaAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"entryID","type":"uint256"}],"name":"getVestingEntry","outputs":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"entryID","type":"uint256"}],"name":"getVestingEntryClaimable","outputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"entryIDs","type":"uint256[]"}],"name":"getVestingQuantity","outputs":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"totalFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getVestingSchedules","outputs":[{"components":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"},{"internalType":"uint256","name":"entryID","type":"uint256"}],"internalType":"struct VestingEntries.VestingEntryWithID[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextEntryId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numVestingEntries","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingRewards","type":"address"}],"name":"setStakingRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasuryDAO","type":"address"}],"name":"setTreasuryDAO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingRewards","outputs":[{"internalType":"contract IStakingRewards","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalEscrowedAccountBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalEscrowedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalVestedAccountBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryDAO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unstakeEscrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"entryIDs","type":"uint256[]"}],"name":"vest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"vestingSchedules","outputs":[{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint256","name":"escrowAmount","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162001ee038038062001ee0833981016040819052620000349162000121565b816001600160a01b038116620000905760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a150600160055560601b6001600160601b0319166080525062000159565b80516001600160a01b03811681146200011c57600080fd5b919050565b600080604083850312156200013557600080fd5b620001408362000104565b9150620001506020840162000104565b90509250929050565b60805160601c611d4c62000194600039600081816101ca0152818161084001528181610eb9015281816114fa01526118c00152611d4c6000f3fe608060405234801561001057600080fd5b50600436106101c35760003560e01c806370a08231116100f9578063a86c3cde11610097578063b1724b4611610071578063b1724b46146104b2578063e6b2cf6c146104bd578063eac62489146104c6578063eddaee92146104e657600080fd5b8063a86c3cde14610479578063ad18e97e1461048c578063ae5825491461049f57600080fd5b806379ba5097116100d357806379ba5097146104385780638da5cb5b14610440578063a0416ed314610453578063a46eddcf1461046657600080fd5b806370a08231146103e657806371e780f31461040f578063773ab39f1461041857600080fd5b806334c7fec9116101665780636154c343116101405780636154c3431461035f57806364b87a70146103ad5780636dc05bd3146103c05780636fb83a57146103d357600080fd5b806334c7fec9146102ce57806345626bd6146102e157806353a47bb71461034c57600080fd5b8063204b676a116101a2578063204b676a1461022f578063227d517a1461026657806330104c5f14610286578063326a3cfb146102ae57600080fd5b80624d37e2146101c85780631627540c146102075780631bb47b441461021c575b600080fd5b7f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020015b60405180910390f35b61021a610215366004611a4d565b6104f9565b005b61021a61022a366004611ae5565b610563565b61025861023d366004611a4d565b6001600160a01b031660009081526004602052604090205490565b6040519081526020016101fe565b610258610274366004611a4d565b60076020526000908152604090205481565b610299610294366004611abb565b6105f8565b604080519283526020830191909152016101fe565b6102586102bc366004611a4d565b60066020526000908152604090205481565b61021a6102dc366004611b18565b61065c565b6103266102ef366004611abb565b600360209081526000928352604080842090915290825290208054600182015460029092015467ffffffffffffffff909116919083565b6040805167ffffffffffffffff90941684526020840192909252908201526060016101fe565b6001546101ea906001600160a01b031681565b61032661036d366004611abb565b6001600160a01b03919091166000908152600360209081526040808320938352929052208054600182015460029092015467ffffffffffffffff90911692565b6002546101ea906001600160a01b031681565b6102996103ce366004611a68565b610940565b61021a6103e1366004611a4d565b610a12565b6102586103f4366004611a4d565b6001600160a01b031660009081526006602052604090205490565b61025860085481565b61042b610426366004611ae5565b610ace565b6040516101fe9190611ba2565b61021a610d04565b6000546101ea906001600160a01b031681565b61021a610461366004611ae5565b610e03565b61021a610474366004611a4d565b610f89565b61021a610487366004611b70565b611042565b6009546101ea906001600160a01b031681565b6102586104ad366004611abb565b6110c3565b6102586303bfc40081565b61025860055481565b6104d96104d4366004611ae5565b6110f4565b6040516101fe9190611c05565b61021a6104f4366004611b70565b611229565b610501611360565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b6002546001600160a01b031633146105e85760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c7920746865205374616b696e67526577617264732063616e207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084015b60405180910390fd5b6105f38383836113e2565b505050565b6001600160a01b038216600090815260036020908152604080832084845282528083208151606081018352815467ffffffffffffffff168152600182015493810193909352600201549082015281906106508161174b565b90969095509350505050565b60008060005b83811015610725573360009081526003602052604081208187878581811061068c5761068c611cea565b905060200201358152602001908152602001600020905080600101546000146107125760408051606081018252825467ffffffffffffffff1681526001830154602082015260028301549181019190915260009081906106eb9061174b565b6000600186015590925090506107018287611c49565b955061070d8186611c49565b945050505b508061071d81611cb9565b915050610662565b50811561093a5761073533611793565b156108075760006107468284611c49565b60025460405163057a601b60e01b81523360048201529192506000916001600160a01b039091169063057a601b9060240160206040518083038186803b15801561078f57600080fd5b505afa1580156107a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c79190611b89565b336000908152600660205260409020546107e19190611ca2565b9050808211156108045760006107f78284611ca2565b905061080281611042565b505b50505b801561093057610817338261181b565b60095460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb90604401602060405180830381600087803b15801561088657600080fd5b505af115801561089a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108be9190611b4e565b6109305760405162461bcd60e51b815260206004820152602360248201527f526577617264457363726f773a20546f6b656e205472616e736665722046616960448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526084016105df565b61093a3383611863565b50505050565b60008060005b83811015610a09576001600160a01b03861660009081526003602052604081208187878581811061097957610979611cea565b602090810292909201358352508181019290925260409081016000208151606081018352815467ffffffffffffffff1681526001820154938101849052600290910154918101919091529150156109f6576000806109d68361174b565b90925090506109e58287611c49565b95506109f18186611c49565b945050505b5080610a0181611cb9565b915050610946565b50935093915050565b610a1a611360565b6002546001600160a01b031615610a735760405162461bcd60e51b815260206004820152601b60248201527f5374616b696e67205265776172647320616c726561647920736574000000000060448201526064016105df565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fb63c81227c62f4cb3e2b1120e3afbf3a2ed5dd8b9d99b8bef7275b084e6a98cb90602001610558565b60606000610adc8385611c49565b9050838111610b45576040805160008082526020820190925290610b3c565b610b296040518060600160405280600067ffffffffffffffff16815260200160008152602001600081525090565b815260200190600190039081610afb5790505b50915050610cfd565b6001600160a01b038516600090815260046020526040902054811115610b8057506001600160a01b0384166000908152600460205260409020545b6000610b8c8583611ca2565b905060008167ffffffffffffffff811115610ba957610ba9611d00565b604051908082528060200260200182016040528015610c0857816020015b610bf56040518060600160405280600067ffffffffffffffff16815260200160008152602001600081525090565b815260200190600190039081610bc75790505b50905060005b82811015610cf7576001600160a01b0388166000908152600460205260408120610c388984611c49565b81548110610c4857610c48611cea565b60009182526020808320909101546001600160a01b038c168352600382526040808420828552835292839020835160608082018652825467ffffffffffffffff90811683526001840154838701908152600290940154838801528651918201875282511681529151938201939093529283018190528551909350909190859085908110610cd757610cd7611cea565b602002602001018190525050508080610cef90611cb9565b915050610c0e565b50925050505b9392505050565b6001546001600160a01b03163314610d845760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e657273686970000000000000000000000060648201526084016105df565b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600180546000805473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b03841617909155169055565b6001600160a01b038316610e7e5760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f742063726561746520657363726f7720776974682061646472657360448201527f732830290000000000000000000000000000000000000000000000000000000060648201526084016105df565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b158015610f0557600080fd5b505af1158015610f19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3d9190611b4e565b6105e85760405162461bcd60e51b815260206004820152601560248201527f546f6b656e207472616e73666572206661696c6564000000000000000000000060448201526064016105df565b610f91611360565b6001600160a01b038116610fe75760405162461bcd60e51b815260206004820152601a60248201527f526577617264457363726f773a205a65726f204164647265737300000000000060448201526064016105df565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd780e06c55efd6b3157e8c26704d2fd7bd2750bd9d0e71d2e5f675572dfad7a290602001610558565b6002546040517fc9c7da16000000000000000000000000000000000000000000000000000000008152336004820152602481018390526001600160a01b039091169063c9c7da16906044015b600060405180830381600087803b1580156110a857600080fd5b505af11580156110bc573d6000803e3d6000fd5b5050505050565b600460205281600052604060002081815481106110df57600080fd5b90600052602060002001600091509150505481565b606060006111028385611c49565b6001600160a01b03861660009081526004602052604090205490915081111561114057506001600160a01b0384166000908152600460205260409020545b83811161115d576040805160008082526020820190925290610b3c565b60006111698583611ca2565b905060008167ffffffffffffffff81111561118657611186611d00565b6040519080825280602002602001820160405280156111af578160200160208202803683370190505b50905060005b82811015610cf7576001600160a01b03881660009081526004602052604090206111df8883611c49565b815481106111ef576111ef611cea565b906000526020600020015482828151811061120c5761120c611cea565b60209081029190910101528061122181611cb9565b9150506111b5565b336000818152600660205260409081902054600254915163057a601b60e01b81526004810193909352916001600160a01b039091169063057a601b9060240160206040518083038186803b15801561128057600080fd5b505afa158015611294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b89190611b89565b6112c29083611c49565b11156113105760405162461bcd60e51b815260206004820152601c60248201527f496e73756666696369656e7420756e7374616b656420657363726f770000000060448201526064016105df565b6002546040517f985134fb000000000000000000000000000000000000000000000000000000008152336004820152602481018390526001600160a01b039091169063985134fb9060440161108e565b6000546001600160a01b031633146113e05760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e000000000000000000000000000000000060648201526084016105df565b565b8161142f5760405162461bcd60e51b815260206004820152601760248201527f5175616e746974792063616e6e6f74206265207a65726f00000000000000000060448201526064016105df565b60008111801561144357506303bfc4008111155b6114b55760405162461bcd60e51b815260206004820152603360248201527f43616e6e6f7420657363726f7720776974682030206475726174696f6e204f5260448201527f2061626f7665206d61785f6475726174696f6e0000000000000000000000000060648201526084016105df565b81600860008282546114c79190611c49565b90915550506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561154457600080fd5b505afa158015611558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157c9190611b89565b60085411156116195760405162461bcd60e51b815260206004820152604760248201527f4d75737420626520656e6f7567682062616c616e636520696e2074686520636f60448201527f6e747261637420746f2070726f7669646520666f72207468652076657374696e60648201527f6720656e74727900000000000000000000000000000000000000000000000000608482015260a4016105df565b60006116258242611c49565b6001600160a01b038516600090815260066020526040812080549293508592909190611652908490611c49565b9091555050600580546040805160608101825267ffffffffffffffff858116825260208083018981528385018981526001600160a01b038c1660008181526003855287812089825285528781209651875467ffffffffffffffff19169616959095178655915160018087019190915590516002909501949094558252600481529281208054928301815581529182200182905582549192906116f383611cb9565b909155505060408051858152602081018590529081018290526001600160a01b038616907fc11d912f381a0760d4ed857b120f217d7571b1c550471b92880b0b94b1d42bee9060600160405180910390a25050505050565b60208101516000908190801561178d57835167ffffffffffffffff1642106117755780925061178d565b61177e84611983565b915061178a8282611ca2565b92505b50915091565b60025460405163057a601b60e01b81526001600160a01b038381166004830152600092839291169063057a601b9060240160206040518083038186803b1580156117dc57600080fd5b505afa1580156117f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118149190611b89565b1192915050565b806008600082825461182d9190611ca2565b90915550506001600160a01b0382166000908152600660205260408120805483929061185a908490611ca2565b90915550505050565b61186d828261181b565b6001600160a01b03821660009081526007602052604081208054839290611895908490611c49565b909155505060405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561190457600080fd5b505af1158015611918573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193c9190611b4e565b50816001600160a01b03167ed5958799b183a7b738d3ad5e711305293dd5076a37a4e3b7e6611dea6114f38260405161197791815260200190565b60405180910390a25050565b60008042836000015167ffffffffffffffff166119a09190611ca2565b90506000600a846020015160096119b79190611c83565b6119c19190611c61565b60408501519091506119d38383611c83565b6119dd9190611c61565b949350505050565b80356001600160a01b03811681146119fc57600080fd5b919050565b60008083601f840112611a1357600080fd5b50813567ffffffffffffffff811115611a2b57600080fd5b6020830191508360208260051b8501011115611a4657600080fd5b9250929050565b600060208284031215611a5f57600080fd5b610cfd826119e5565b600080600060408486031215611a7d57600080fd5b611a86846119e5565b9250602084013567ffffffffffffffff811115611aa257600080fd5b611aae86828701611a01565b9497909650939450505050565b60008060408385031215611ace57600080fd5b611ad7836119e5565b946020939093013593505050565b600080600060608486031215611afa57600080fd5b611b03846119e5565b95602085013595506040909401359392505050565b60008060208385031215611b2b57600080fd5b823567ffffffffffffffff811115611b4257600080fd5b61065085828601611a01565b600060208284031215611b6057600080fd5b81518015158114610cfd57600080fd5b600060208284031215611b8257600080fd5b5035919050565b600060208284031215611b9b57600080fd5b5051919050565b602080825282518282018190526000919060409081850190868401855b82811015611bf8578151805167ffffffffffffffff16855286810151878601528501518585015260609093019290850190600101611bbf565b5091979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c3d57835183529284019291840191600101611c21565b50909695505050505050565b60008219821115611c5c57611c5c611cd4565b500190565b600082611c7e57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611c9d57611c9d611cd4565b500290565b600082821015611cb457611cb4611cd4565b500390565b6000600019821415611ccd57611ccd611cd4565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220068d218e10b60891e3b611aa3c81f5331feadee6f39a174c937f3fe292f8376664736f6c63430008070033000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c000000000000000000000000920cf626a271321c151d027030d5d08af699456b
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c000000000000000000000000920cf626a271321c151d027030d5d08af699456b
-----Decoded View---------------
Arg [0] : _owner (address): 0xe029c32d412972C5F3D107DA6d6eCF8F1C1E788C
Arg [1] : _kwenta (address): 0x920Cf626a271321C151D027030D5d08aF699456b
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000e029c32d412972c5f3d107da6d6ecf8f1c1e788c
Arg [1] : 000000000000000000000000920cf626a271321c151d027030d5d08af699456b
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.