Balance:
23,535.668985730817669093 MATIC
MATIC Value:
$26,218.74 (@ $1.11/MATIC)
Token:
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
KyberRewardLocker
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; pragma abicoder v2; import {IERC20Ext} from '@kyber.network/utils-sc/contracts/IERC20Ext.sol'; import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol'; import {SafeCast} from '@openzeppelin/contracts/utils/SafeCast.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {EnumerableSet} from '@openzeppelin/contracts/utils/EnumerableSet.sol'; import {PermissionAdmin} from '@kyber.network/utils-sc/contracts/PermissionAdmin.sol'; import {IKyberRewardLocker} from '../interfaces/liquidityMining/IKyberRewardLocker.sol'; contract KyberRewardLocker is IKyberRewardLocker, PermissionAdmin { using SafeMath for uint256; using SafeCast for uint256; using SafeERC20 for IERC20Ext; using EnumerableSet for EnumerableSet.AddressSet; struct VestingSchedules { uint256 length; mapping(uint256 => VestingSchedule) data; } uint256 private constant MAX_REWARD_CONTRACTS_SIZE = 100; /// @dev whitelist of reward contracts mapping(IERC20Ext => EnumerableSet.AddressSet) internal rewardContractsPerToken; /// @dev vesting schedule of an account mapping(address => mapping(IERC20Ext => VestingSchedules)) private accountVestingSchedules; /// @dev An account's total escrowed balance per token to save recomputing this for fee extraction purposes mapping(address => mapping(IERC20Ext => uint256)) public accountEscrowedBalance; /// @dev An account's total vested reward per token mapping(address => mapping(IERC20Ext => uint256)) public accountVestedBalance; /// @dev vesting duration for earch token mapping(IERC20Ext => uint256) public vestingDurationPerToken; /* ========== EVENTS ========== */ event RewardContractAdded(address indexed rewardContract, IERC20Ext indexed token, bool isAdded); event SetVestingDuration(IERC20Ext indexed token, uint64 vestingDuration); /* ========== MODIFIERS ========== */ modifier onlyRewardsContract(IERC20Ext token) { require(rewardContractsPerToken[token].contains(msg.sender), 'only reward contract'); _; } constructor(address _admin) PermissionAdmin(_admin) {} /** * @notice Add a whitelisted rewards contract */ function addRewardsContract(IERC20Ext token, address _rewardContract) external onlyAdmin { require( rewardContractsPerToken[token].length() < MAX_REWARD_CONTRACTS_SIZE, 'rewardContracts is too long' ); require(rewardContractsPerToken[token].add(_rewardContract), '_rewardContract is added'); emit RewardContractAdded(_rewardContract, token, true); } /** * @notice Remove a whitelisted rewards contract */ function removeRewardsContract(IERC20Ext token, address _rewardContract) external onlyAdmin { require(rewardContractsPerToken[token].remove(_rewardContract), '_rewardContract is removed'); emit RewardContractAdded(_rewardContract, token, false); } function setVestingDuration(IERC20Ext token, uint64 _vestingDuration) external onlyAdmin { vestingDurationPerToken[token] = _vestingDuration; emit SetVestingDuration(token, _vestingDuration); } function lock( IERC20Ext token, address account, uint256 quantity ) external override payable { lockWithStartBlock(token, account, quantity, _blockNumber()); } /** * @dev vest all completed schedules for multiple tokens */ function vestCompletedSchedulesForMultipleTokens(IERC20Ext[] calldata tokens) external override returns (uint256[] memory vestedAmounts) { vestedAmounts = new uint256[](tokens.length); for (uint256 i = 0; i < tokens.length; i++) { vestedAmounts[i] = vestCompletedSchedules(tokens[i]); } } /** * @dev claim multiple tokens for specific vesting schedule, * if schedule has not ended yet, claiming amounts are linear with vesting blocks */ function vestScheduleForMultipleTokensAtIndices( IERC20Ext[] calldata tokens, uint256[][] calldata indices ) external override returns (uint256[] memory vestedAmounts) { require(tokens.length == indices.length, 'tokens.length != indices.length'); vestedAmounts = new uint256[](tokens.length); for (uint256 i = 0; i < tokens.length; i++) { vestedAmounts[i] = vestScheduleAtIndices(tokens[i], indices[i]); } } function lockWithStartBlock( IERC20Ext token, address account, uint256 quantity, uint256 startBlock ) public override payable onlyRewardsContract(token) { require(quantity > 0, '0 quantity'); if (token == IERC20Ext(0)) { require(msg.value == quantity, 'Invalid msg.value'); } else { // transfer token from reward contract to lock contract token.safeTransferFrom(msg.sender, address(this), quantity); } VestingSchedules storage schedules = accountVestingSchedules[account][token]; uint256 schedulesLength = schedules.length; uint256 endBlock = startBlock.add(vestingDurationPerToken[token]); // combine with the last schedule if they have the same start & end blocks if (schedulesLength > 0) { VestingSchedule storage lastSchedule = schedules.data[schedulesLength - 1]; if (lastSchedule.startBlock == startBlock && lastSchedule.endBlock == endBlock) { lastSchedule.quantity = uint256(lastSchedule.quantity).add(quantity).toUint128(); accountEscrowedBalance[account][token] = accountEscrowedBalance[account][token].add( quantity ); emit VestingEntryQueued(schedulesLength - 1, token, account, quantity); return; } } // append new schedule schedules.data[schedulesLength] = VestingSchedule({ startBlock: startBlock.toUint64(), endBlock: endBlock.toUint64(), quantity: quantity.toUint128(), vestedQuantity: 0 }); schedules.length = schedulesLength + 1; // record total vesting balance of user accountEscrowedBalance[account][token] = accountEscrowedBalance[account][token].add(quantity); emit VestingEntryCreated(token, account, startBlock, endBlock, quantity, schedulesLength); } /** * @dev Allow a user to vest all ended schedules */ function vestCompletedSchedules(IERC20Ext token) public override returns (uint256) { VestingSchedules storage schedules = accountVestingSchedules[msg.sender][token]; uint256 schedulesLength = schedules.length; uint256 totalVesting = 0; for (uint256 i = 0; i < schedulesLength; i++) { VestingSchedule memory schedule = schedules.data[i]; if (_blockNumber() < schedule.endBlock) { continue; } uint256 vestQuantity = uint256(schedule.quantity).sub(schedule.vestedQuantity); if (vestQuantity == 0) { continue; } schedules.data[i].vestedQuantity = schedule.quantity; totalVesting = totalVesting.add(vestQuantity); emit Vested(token, msg.sender, vestQuantity, i); } _completeVesting(token, totalVesting); return totalVesting; } /** * @notice Allow a user to vest with specific schedule */ function vestScheduleAtIndices(IERC20Ext token, uint256[] memory indexes) public override returns (uint256) { VestingSchedules storage schedules = accountVestingSchedules[msg.sender][token]; uint256 schedulesLength = schedules.length; uint256 totalVesting = 0; for (uint256 i = 0; i < indexes.length; i++) { require(indexes[i] < schedulesLength, 'invalid schedule index'); VestingSchedule memory schedule = schedules.data[indexes[i]]; uint256 vestQuantity = _getVestingQuantity(schedule); if (vestQuantity == 0) { continue; } schedules.data[indexes[i]].vestedQuantity = uint256(schedule.vestedQuantity) .add(vestQuantity) .toUint128(); totalVesting = totalVesting.add(vestQuantity); emit Vested(token, msg.sender, vestQuantity, indexes[i]); } _completeVesting(token, totalVesting); return totalVesting; } function vestSchedulesInRange( IERC20Ext token, uint256 startIndex, uint256 endIndex ) public override returns (uint256) { require(startIndex <= endIndex, 'startIndex > endIndex'); uint256[] memory indexes = new uint256[](endIndex - startIndex + 1); for (uint256 index = startIndex; index <= endIndex; index++) { indexes[index - startIndex] = index; } return vestScheduleAtIndices(token, indexes); } /* ========== VIEW FUNCTIONS ========== */ /** * @notice The number of vesting dates in an account's schedule. */ function numVestingSchedules(address account, IERC20Ext token) external override view returns (uint256) { return accountVestingSchedules[account][token].length; } /** * @dev manually get vesting schedule at index */ function getVestingScheduleAtIndex( address account, IERC20Ext token, uint256 index ) external override view returns (VestingSchedule memory) { return accountVestingSchedules[account][token].data[index]; } /** * @dev Get all schedules for an account. */ function getVestingSchedules(address account, IERC20Ext token) external override view returns (VestingSchedule[] memory schedules) { uint256 schedulesLength = accountVestingSchedules[account][token].length; schedules = new VestingSchedule[](schedulesLength); for (uint256 i = 0; i < schedulesLength; i++) { schedules[i] = accountVestingSchedules[account][token].data[i]; } } function getRewardContractsPerToken(IERC20Ext token) external view returns (address[] memory rewardContracts) { rewardContracts = new address[](rewardContractsPerToken[token].length()); for (uint256 i = 0; i < rewardContracts.length; i++) { rewardContracts[i] = rewardContractsPerToken[token].at(i); } } /* ========== INTERNAL FUNCTIONS ========== */ function _completeVesting(IERC20Ext token, uint256 totalVesting) internal { require(totalVesting != 0, '0 vesting amount'); accountEscrowedBalance[msg.sender][token] = accountEscrowedBalance[msg.sender][token].sub( totalVesting ); accountVestedBalance[msg.sender][token] = accountVestedBalance[msg.sender][token].add( totalVesting ); if (token == IERC20Ext(0)) { (bool success, ) = msg.sender.call{value: totalVesting}(''); require(success, 'fail to transfer'); } else { token.safeTransfer(msg.sender, totalVesting); } } /** * @dev implements linear vesting mechanism */ function _getVestingQuantity(VestingSchedule memory schedule) internal view returns (uint256) { if (_blockNumber() >= uint256(schedule.endBlock)) { return uint256(schedule.quantity).sub(schedule.vestedQuantity); } if (_blockNumber() <= uint256(schedule.startBlock)) { return 0; } uint256 lockDuration = uint256(schedule.endBlock).sub(schedule.startBlock); uint256 passedDuration = _blockNumber() - uint256(schedule.startBlock); return passedDuration.mul(schedule.quantity).div(lockDuration).sub(schedule.vestedQuantity); } /** * @dev wrap block.number so we can easily mock it */ function _blockNumber() internal virtual view returns (uint256) { return block.number; } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @dev Interface extending ERC20 standard to include decimals() as * it is optional in the OpenZeppelin IERC20 interface. */ interface IERC20Ext is IERC20 { /** * @dev This function is required as Kyber requires to interact * with token.decimals() with many of its operations. */ function decimals() external view returns (uint8 digits); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { require(value < 2**255, "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; abstract contract PermissionAdmin { address public admin; address public pendingAdmin; event AdminClaimed(address newAdmin, address previousAdmin); event TransferAdminPending(address pendingAdmin); constructor(address _admin) { require(_admin != address(0), "admin 0"); admin = _admin; } modifier onlyAdmin() { require(msg.sender == admin, "only admin"); _; } /** * @dev Allows the current admin to set the pendingAdmin address. * @param newAdmin The address to transfer ownership to. */ function transferAdmin(address newAdmin) public onlyAdmin { require(newAdmin != address(0), "new admin 0"); emit TransferAdminPending(newAdmin); pendingAdmin = newAdmin; } /** * @dev Allows the current admin to set the admin in one tx. Useful initial deployment. * @param newAdmin The address to transfer ownership to. */ function transferAdminQuickly(address newAdmin) public onlyAdmin { require(newAdmin != address(0), "admin 0"); emit TransferAdminPending(newAdmin); emit AdminClaimed(newAdmin, admin); admin = newAdmin; } /** * @dev Allows the pendingAdmin address to finalize the change admin process. */ function claimAdmin() public { require(pendingAdmin == msg.sender, "not pending"); emit AdminClaimed(pendingAdmin, admin); admin = pendingAdmin; pendingAdmin = address(0); } }
// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.7.6; pragma abicoder v2; import {IERC20Ext} from '@kyber.network/utils-sc/contracts/IERC20Ext.sol'; interface IKyberRewardLocker { struct VestingSchedule { uint64 startBlock; uint64 endBlock; uint128 quantity; uint128 vestedQuantity; } event VestingEntryCreated( IERC20Ext indexed token, address indexed beneficiary, uint256 startBlock, uint256 endBlock, uint256 quantity, uint256 index ); event VestingEntryQueued( uint256 indexed index, IERC20Ext indexed token, address indexed beneficiary, uint256 quantity ); event Vested( IERC20Ext indexed token, address indexed beneficiary, uint256 vestedQuantity, uint256 index ); /** * @dev queue a vesting schedule starting from now */ function lock( IERC20Ext token, address account, uint256 amount ) external payable; /** * @dev queue a vesting schedule */ function lockWithStartBlock( IERC20Ext token, address account, uint256 quantity, uint256 startBlock ) external payable; /** * @dev vest all completed schedules for multiple tokens */ function vestCompletedSchedulesForMultipleTokens(IERC20Ext[] calldata tokens) external returns (uint256[] memory vestedAmounts); /** * @dev claim multiple tokens for specific vesting schedule, * if schedule has not ended yet, claiming amounts are linear with vesting blocks */ function vestScheduleForMultipleTokensAtIndices( IERC20Ext[] calldata tokens, uint256[][] calldata indices ) external returns (uint256[] memory vestedAmounts); /** * @dev for all completed schedule, claim token */ function vestCompletedSchedules(IERC20Ext token) external returns (uint256); /** * @dev claim token for specific vesting schedule, * @dev if schedule has not ended yet, claiming amount is linear with vesting blocks */ function vestScheduleAtIndices(IERC20Ext token, uint256[] calldata indexes) external returns (uint256); /** * @dev claim token for specific vesting schedule from startIndex to endIndex */ function vestSchedulesInRange( IERC20Ext token, uint256 startIndex, uint256 endIndex ) external returns (uint256); /** * @dev length of vesting schedules array */ function numVestingSchedules(address account, IERC20Ext token) external view returns (uint256); /** * @dev get detailed of each vesting schedule */ function getVestingScheduleAtIndex( address account, IERC20Ext token, uint256 index ) external view returns (VestingSchedule memory); /** * @dev get vesting shedules array */ function getVestingSchedules(address account, IERC20Ext token) external view returns (VestingSchedule[] memory schedules); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.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: MIT pragma solidity ^0.7.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"}],"name":"AdminClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewardContract","type":"address"},{"indexed":true,"internalType":"contract IERC20Ext","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"isAdded","type":"bool"}],"name":"RewardContractAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Ext","name":"token","type":"address"},{"indexed":false,"internalType":"uint64","name":"vestingDuration","type":"uint64"}],"name":"SetVestingDuration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingAdmin","type":"address"}],"name":"TransferAdminPending","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Ext","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"vestedQuantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Vested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Ext","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"VestingEntryCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":true,"internalType":"contract IERC20Ext","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"VestingEntryQueued","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract IERC20Ext","name":"","type":"address"}],"name":"accountEscrowedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract IERC20Ext","name":"","type":"address"}],"name":"accountVestedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"address","name":"_rewardContract","type":"address"}],"name":"addRewardsContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"}],"name":"getRewardContractsPerToken","outputs":[{"internalType":"address[]","name":"rewardContracts","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getVestingScheduleAtIndex","outputs":[{"components":[{"internalType":"uint64","name":"startBlock","type":"uint64"},{"internalType":"uint64","name":"endBlock","type":"uint64"},{"internalType":"uint128","name":"quantity","type":"uint128"},{"internalType":"uint128","name":"vestedQuantity","type":"uint128"}],"internalType":"struct IKyberRewardLocker.VestingSchedule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"contract IERC20Ext","name":"token","type":"address"}],"name":"getVestingSchedules","outputs":[{"components":[{"internalType":"uint64","name":"startBlock","type":"uint64"},{"internalType":"uint64","name":"endBlock","type":"uint64"},{"internalType":"uint128","name":"quantity","type":"uint128"},{"internalType":"uint128","name":"vestedQuantity","type":"uint128"}],"internalType":"struct IKyberRewardLocker.VestingSchedule[]","name":"schedules","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"}],"name":"lockWithStartBlock","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"contract IERC20Ext","name":"token","type":"address"}],"name":"numVestingSchedules","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"address","name":"_rewardContract","type":"address"}],"name":"removeRewardsContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"uint64","name":"_vestingDuration","type":"uint64"}],"name":"setVestingDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferAdminQuickly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"}],"name":"vestCompletedSchedules","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext[]","name":"tokens","type":"address[]"}],"name":"vestCompletedSchedulesForMultipleTokens","outputs":[{"internalType":"uint256[]","name":"vestedAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"uint256[]","name":"indexes","type":"uint256[]"}],"name":"vestScheduleAtIndices","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext[]","name":"tokens","type":"address[]"},{"internalType":"uint256[][]","name":"indices","type":"uint256[][]"}],"name":"vestScheduleForMultipleTokensAtIndices","outputs":[{"internalType":"uint256[]","name":"vestedAmounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"token","type":"address"},{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"vestSchedulesInRange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Ext","name":"","type":"address"}],"name":"vestingDurationPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162002aa438038062002aa48339810160408190526200003491620000a2565b806001600160a01b0381166200007b576040805162461bcd60e51b8152602060048201526007602482015266061646d696e20360cc1b604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b039290921691909117905550620000d2565b600060208284031215620000b4578081fd5b81516001600160a01b0381168114620000cb578182fd5b9392505050565b6129c280620000e26000396000f3fe6080604052600436106101755760003560e01c806377f50f97116100cb578063bbd8a3281161007f578063f793d77e11610059578063f793d77e14610403578063f851a44014610423578063fdfaaa051461043857610175565b8063bbd8a32814610396578063c33fddf8146103c3578063cb1d086b146103e357610175565b80639059aa6a116100b05780639059aa6a14610343578063a5d21e3114610363578063aaf543851461037657610175565b806377f50f971461030e5780637acc86781461032357610175565b80634c9d00cc1161012d5780636e732b70116101075780636e732b70146102bb57806375829def146102db5780637750c9f0146102fb57610175565b80634c9d00cc1461024c5780634d4f3d931461026e578063679f7f771461029b57610175565b8063267822471161015e57806326782247146101dd5780632f50bd72146101ff5780633b5bfa8b1461022c57610175565b80630a3b7e311461017a5780630f5636c3146101b0575b600080fd5b34801561018657600080fd5b5061019a6101953660046121eb565b610458565b6040516101a791906127f8565b60405180910390f35b3480156101bc57600080fd5b506101d06101cb36600461233f565b6104e8565b6040516101a79190612806565b3480156101e957600080fd5b506101f26106f2565b6040516101a791906124b5565b34801561020b57600080fd5b5061021f61021a3660046121b3565b610701565b6040516101a79190612516565b34801561023857600080fd5b506101d06102473660046121b3565b610831565b34801561025857600080fd5b5061026c6102673660046122d4565b61084e565b005b34801561027a57600080fd5b5061028e61028936600461226b565b610928565b6040516101a79190612558565b3480156102a757600080fd5b506101d06102b63660046121b3565b610a39565b3480156102c757600080fd5b506101d06102d63660046121b3565b610a64565b3480156102e757600080fd5b5061026c6102f6366004612197565b610a81565b61026c6103093660046122e6565b610b93565b34801561031a57600080fd5b5061026c610ba6565b34801561032f57600080fd5b5061026c61033e366004612197565b610c85565b34801561034f57600080fd5b5061028e61035e36600461222b565b610ddf565b61026c6103713660046122fa565b610e7a565b34801561038257600080fd5b506101d0610391366004612197565b61122b565b3480156103a257600080fd5b506103b66103b1366004612197565b61123d565b6040516101a791906124c9565b3480156103cf57600080fd5b506101d06103de366004612402565b611304565b3480156103ef57600080fd5b5061026c6103fe366004612436565b6113b0565b34801561040f57600080fd5b5061026c61041e3660046122d4565b61145d565b34801561042f57600080fd5b506101f261156c565b34801561044457600080fd5b506101d0610453366004612197565b61157b565b610460612127565b506001600160a01b038084166000908152600360209081526040808320938616835292815282822084835260019081018252918390208351608081018552815467ffffffffffffffff8082168352600160401b820416938201939093526001600160801b03600160801b909304831694810194909452909101541660608201525b9392505050565b3360009081526003602090815260408083206001600160a01b03861684529091528120805482805b85518110156106dc578286828151811061052657fe5b6020026020010151106105545760405162461bcd60e51b815260040161054b9061259b565b60405180910390fd5b600084600101600088848151811061056857fe5b602090810291909101810151825281810192909252604090810160009081208251608081018452815467ffffffffffffffff8082168352600160401b820416958201959095526001600160801b03600160801b90950485169381019390935260010154909216606082015291506105de82611714565b9050806105ec5750506106d4565b606082015161060d90610608906001600160801b031683611807565b611861565b8660010160008a868151811061061f57fe5b6020026020010151815260200190815260200160002060010160006101000a8154816001600160801b0302191690836001600160801b0316021790555061066f818561180790919063ffffffff16565b9350336001600160a01b0316896001600160a01b03167f6d06f0a463d80b43fe6cd0b79c61bb2790cfe898790e69828f25e6e12886e178838b87815181106106b357fe5b60200260200101516040516106c992919061280f565b60405180910390a350505b600101610510565b506106e786826118a9565b925050505b92915050565b6001546001600160a01b031681565b6001600160a01b038083166000908152600360209081526040808320938516835292905220546060908067ffffffffffffffff8111801561074157600080fd5b5060405190808252806020026020018201604052801561077b57816020015b610768612127565b8152602001906001900390816107605790505b50915060005b81811015610829576001600160a01b038086166000908152600360209081526040808320938816835292815282822084835260019081018252918390208351608081018552815467ffffffffffffffff8082168352600160401b820416938201939093526001600160801b03600160801b90930483169481019490945290910154166060820152835184908390811061081657fe5b6020908102919091010152600101610781565b505092915050565b600560209081526000928352604080842090915290825290205481565b6000546001600160a01b0316331461089a576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b03821660009081526002602052604090206108bc9082611a01565b6108d85760405162461bcd60e51b815260040161054b90612640565b816001600160a01b0316816001600160a01b03167f88a8c998079a07d6a1e59a32ce0c359a00e4c94ce7a6068350a9574e7e0f993d600060405161091c9190612590565b60405180910390a35050565b60608382146109495760405162461bcd60e51b815260040161054b90612753565b8367ffffffffffffffff8111801561096057600080fd5b5060405190808252806020026020018201604052801561098a578160200160208202803683370190505b50905060005b84811015610a3057610a118686838181106109a757fe5b90506020020160208101906109bc9190612197565b8585848181106109c857fe5b90506020028101906109da919061284d565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506104e892505050565b828281518110610a1d57fe5b6020908102919091010152600101610990565b50949350505050565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b600460209081526000928352604080842090915290825290205481565b6000546001600160a01b03163314610acd576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b038116610b28576040805162461bcd60e51b815260206004820152600b60248201527f6e65772061646d696e2030000000000000000000000000000000000000000000604482015290519081900360640190fd5b604080516001600160a01b038316815290517f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc409181900360200190a16001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b610ba1838383610371611a16565b505050565b6001546001600160a01b03163314610c05576040805162461bcd60e51b815260206004820152600b60248201527f6e6f742070656e64696e67000000000000000000000000000000000000000000604482015290519081900360640190fd5b600154600054604080516001600160a01b03938416815292909116602083015280517f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed9281900390910190a1600180546000805473ffffffffffffffffffffffffffffffffffffffff199081166001600160a01b03841617909155169055565b6000546001600160a01b03163314610cd1576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b038116610d2c576040805162461bcd60e51b815260206004820152600760248201527f61646d696e203000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b604080516001600160a01b038316815290517f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc409181900360200190a1600054604080516001600160a01b038085168252909216602083015280517f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed9281900390910190a16000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60608167ffffffffffffffff81118015610df857600080fd5b50604051908082528060200260200182016040528015610e22578160200160208202803683370190505b50905060005b82811015610e7357610e54848483818110610e3f57fe5b90506020020160208101906104539190612197565b828281518110610e6057fe5b6020908102919091010152600101610e28565b5092915050565b6001600160a01b03841660009081526002602052604090208490610e9e9033611a1a565b610eba5760405162461bcd60e51b815260040161054b9061271c565b60008311610eda5760405162461bcd60e51b815260040161054b9061278a565b6001600160a01b038516610f0c57823414610f075760405162461bcd60e51b815260040161054b90612677565b610f21565b610f216001600160a01b038616333086611a2f565b6001600160a01b03808516600090815260036020908152604080832093891683529281528282208054600690925292822054909190610f61908690611807565b9050811561108c57600019820160009081526001840160205260409020805467ffffffffffffffff1686148015610fa957508054600160401b900467ffffffffffffffff1682145b1561108a578054610fce9061060890600160801b90046001600160801b031689611807565b81546001600160801b03918216600160801b0291161781556001600160a01b038089166000908152600460209081526040808320938d16835292905220546110169088611807565b6001600160a01b03808a166000818152600460209081526040808320948f1680845294909152908190209390935591516000198601907fa6fd3a57929c9152d86fa5f83c8478f1af480353a0aef0cacc3240d63b57076790611079908c90612806565b60405180910390a450505050611224565b505b60405180608001604052806110a087611abd565b67ffffffffffffffff1681526020016110b883611abd565b67ffffffffffffffff1681526020016110d088611861565b6001600160801b039081168252600060209283018190528581526001808801845260408083208651815488880151898501518816600160801b0267ffffffffffffffff918216600160401b027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9290941667ffffffffffffffff1990931692909217169190911786161781556060909601519582018054969094166fffffffffffffffffffffffffffffffff19969096169590951790925590850186556001600160a01b03808b16825260048352838220908c16825290915220546111b59087611807565b6001600160a01b038089166000818152600460209081526040808320948e1680845294909152908190209390935591517ffb1fd0fee690638acf30008a00d7fc669e970dd6fa8912488ee11171986edabb9061121890899086908c90899061281d565b60405180910390a35050505b5050505050565b60066020526000908152604090205481565b6001600160a01b038116600090815260026020526040902060609061126190611b01565b67ffffffffffffffff8111801561127757600080fd5b506040519080825280602002602001820160405280156112a1578160200160208202803683370190505b50905060005b81518110156112fe576001600160a01b03831660009081526002602052604090206112d29082611b0c565b8282815181106112de57fe5b6001600160a01b03909216602092830291909101909101526001016112a7565b50919050565b6000818311156113265760405162461bcd60e51b815260040161054b906126ae565b600083830360010167ffffffffffffffff8111801561134457600080fd5b5060405190808252806020026020018201604052801561136e578160200160208202803683370190505b509050835b83811161139c5780828683038151811061138957fe5b6020908102919091010152600101611373565b506113a785826104e8565b95945050505050565b6000546001600160a01b031633146113fc576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b0382166000818152600660205260409081902067ffffffffffffffff84169055517f8604b95f1c6f11de3cf58583f6524c5b1aaa150f2391ec1544bb059d7517723690611451908490612838565b60405180910390a25050565b6000546001600160a01b031633146114a9576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9030b236b4b760b11b604482015290519081900360640190fd5b6001600160a01b03821660009081526002602052604090206064906114cd90611b01565b106114ea5760405162461bcd60e51b815260040161054b906127c1565b6001600160a01b038216600090815260026020526040902061150c9082611b18565b6115285760405162461bcd60e51b815260040161054b90612609565b816001600160a01b0316816001600160a01b03167f88a8c998079a07d6a1e59a32ce0c359a00e4c94ce7a6068350a9574e7e0f993d600160405161091c9190612590565b6000546001600160a01b031681565b3360009081526003602090815260408083206001600160a01b03851684529091528120805482805b828110156116ff576000818152600180860160209081526040928390208351608081018552815467ffffffffffffffff8082168352600160401b8204169382018490526001600160801b03600160801b909104811695820195909552920154909216606082015290611613611a16565b101561161f57506116f7565b600061164e82606001516001600160801b031683604001516001600160801b0316611b2d90919063ffffffff16565b90508061165c5750506116f7565b6040828101516000858152600189810160205292902090910180546fffffffffffffffffffffffffffffffff19166001600160801b039092169190911790556116a58482611807565b9350336001600160a01b0316886001600160a01b03167f6d06f0a463d80b43fe6cd0b79c61bb2790cfe898790e69828f25e6e12886e17883866040516116ec92919061280f565b60405180910390a350505b6001016115a3565b5061170a85826118a9565b925050505b919050565b6000816020015167ffffffffffffffff1661172d611a16565b106117665761175f82606001516001600160801b031683604001516001600160801b0316611b2d90919063ffffffff16565b905061170f565b815167ffffffffffffffff1661177a611a16565b116117875750600061170f565b815160208301516000916117a89167ffffffffffffffff9081169116611b2d565b90506000836000015167ffffffffffffffff166117c3611a16565b03905061170a84606001516001600160801b0316611801846117fb88604001516001600160801b031686611b8a90919063ffffffff16565b90611be3565b90611b2d565b6000828201838110156104e1576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000600160801b82106118a55760405162461bcd60e51b81526004018080602001828103825260278152602001806128cf6027913960400191505060405180910390fd5b5090565b806118c65760405162461bcd60e51b815260040161054b906126e5565b3360009081526004602090815260408083206001600160a01b03861684529091529020546118f49082611b2d565b3360008181526004602090815260408083206001600160a01b03881680855290835281842095909555928252600581528282209382529290925290205461193b9082611807565b3360009081526005602090815260408083206001600160a01b0387168085529252909120919091556119e9576000336001600160a01b031682604051611980906124b2565b60006040518083038185875af1925050503d80600081146119bd576040519150601f19603f3d011682016040523d82523d6000602084013e6119c2565b606091505b50509050806119e35760405162461bcd60e51b815260040161054b906125d2565b506119fd565b6119fd6001600160a01b0383163383611c4a565b5050565b60006104e1836001600160a01b038416611cca565b4390565b60006104e1836001600160a01b038416611d90565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052611ab7908590611da8565b50505050565b6000600160401b82106118a55760405162461bcd60e51b815260040180806020018281038252602681526020018061293d6026913960400191505060405180910390fd5b60006106ec82611e59565b60006104e18383611e5d565b60006104e1836001600160a01b038416611ec1565b600082821115611b84576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082611b99575060006106ec565b82820282848281611ba657fe5b04146104e15760405162461bcd60e51b815260040180806020018281038252602181526020018061291c6021913960400191505060405180910390fd5b6000808211611c39576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611c4257fe5b049392505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610ba1908490611da8565b60008181526001830160205260408120548015611d865783546000198083019190810190600090879083908110611cfd57fe5b9060005260206000200154905080876000018481548110611d1a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611d4a57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506106ec565b60009150506106ec565b60009081526001919091016020526040902054151590565b6000611dfd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611f0b9092919063ffffffff16565b805190915015610ba157808060200190516020811015611e1c57600080fd5b5051610ba15760405162461bcd60e51b815260040180806020018281038252602a815260200180612963602a913960400191505060405180910390fd5b5490565b81546000908210611e9f5760405162461bcd60e51b81526004018080602001828103825260228152602001806128ad6022913960400191505060405180910390fd5b826000018281548110611eae57fe5b9060005260206000200154905092915050565b6000611ecd8383611d90565b611f03575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106ec565b5060006106ec565b6060611f1a8484600085611f22565b949350505050565b606082471015611f635760405162461bcd60e51b81526004018080602001828103825260268152602001806128f66026913960400191505060405180910390fd5b611f6c8561207d565b611fbd576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b60208310611ffb5780518252601f199092019160209182019101611fdc565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461205d576040519150601f19603f3d011682016040523d82523d6000602084013e612062565b606091505b5091509150612072828286612083565b979650505050505050565b3b151590565b606083156120925750816104e1565b8251156120a25782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156120ec5781810151838201526020016120d4565b50505050905090810190601f1680156121195780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60408051608081018252600080825260208201819052918101829052606081019190915290565b60008083601f84011261215f578081fd5b50813567ffffffffffffffff811115612176578182fd5b602083019150836020808302850101111561219057600080fd5b9250929050565b6000602082840312156121a8578081fd5b81356104e181612894565b600080604083850312156121c5578081fd5b82356121d081612894565b915060208301356121e081612894565b809150509250929050565b6000806000606084860312156121ff578081fd5b833561220a81612894565b9250602084013561221a81612894565b929592945050506040919091013590565b6000806020838503121561223d578182fd5b823567ffffffffffffffff811115612253578283fd5b61225f8582860161214e565b90969095509350505050565b60008060008060408587031215612280578081fd5b843567ffffffffffffffff80821115612297578283fd5b6122a38883890161214e565b909650945060208701359150808211156122bb578283fd5b506122c88782880161214e565b95989497509550505050565b600080604083850312156121c5578182fd5b6000806000606084860312156121ff578283fd5b6000806000806080858703121561230f578384fd5b843561231a81612894565b9350602085013561232a81612894565b93969395505050506040820135916060013590565b60008060408385031215612351578182fd5b823561235c81612894565b915060208381013567ffffffffffffffff80821115612379578384fd5b818601915086601f83011261238c578384fd5b81358181111561239857fe5b838102604051858282010181811085821117156123b157fe5b604052828152858101935084860182860187018b10156123cf578788fd5b8795505b838610156123f15780358552600195909501949386019386016123d3565b508096505050505050509250929050565b600080600060608486031215612416578283fd5b833561242181612894565b95602085013595506040909401359392505050565b60008060408385031215612448578182fd5b823561245381612894565b9150602083013567ffffffffffffffff811681146121e0578182fd5b67ffffffffffffffff8082511683528060208301511660208401525060408101516001600160801b03808216604085015280606084015116606085015250505050565b90565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b8181101561250a5783516001600160a01b0316835292840192918401916001016124e5565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561250a5761254583855161246f565b9284019260809290920191600101612532565b6020808252825182820181905260009190848201906040850190845b8181101561250a57835183529284019291840191600101612574565b901515815260200190565b60208082526016908201527f696e76616c6964207363686564756c6520696e64657800000000000000000000604082015260600190565b60208082526010908201527f6661696c20746f207472616e7366657200000000000000000000000000000000604082015260600190565b60208082526018908201527f5f726577617264436f6e74726163742069732061646465640000000000000000604082015260600190565b6020808252601a908201527f5f726577617264436f6e74726163742069732072656d6f766564000000000000604082015260600190565b60208082526011908201527f496e76616c6964206d73672e76616c7565000000000000000000000000000000604082015260600190565b60208082526015908201527f7374617274496e646578203e20656e64496e6465780000000000000000000000604082015260600190565b60208082526010908201527f302076657374696e6720616d6f756e7400000000000000000000000000000000604082015260600190565b60208082526014908201527f6f6e6c792072657761726420636f6e7472616374000000000000000000000000604082015260600190565b6020808252601f908201527f746f6b656e732e6c656e67746820213d20696e64696365732e6c656e67746800604082015260600190565b6020808252600a908201527f30207175616e7469747900000000000000000000000000000000000000000000604082015260600190565b6020808252601b908201527f726577617264436f6e74726163747320697320746f6f206c6f6e670000000000604082015260600190565b608081016106ec828461246f565b90815260200190565b918252602082015260400190565b93845260208401929092526040830152606082015260800190565b67ffffffffffffffff91909116815260200190565b6000808335601e19843603018112612863578283fd5b83018035915067ffffffffffffffff82111561287d578283fd5b602090810192508102360382131561219057600080fd5b6001600160a01b03811681146128a957600080fd5b5056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647353616665436173743a2076616c756520646f65736e27742066697420696e203132382062697473416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e20363420626974735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220e0b483f0d329a972258bccc19504d9ecb469685ad5f636d2337af628681fbddc64736f6c634300070600330000000000000000000000004bd6037e5cf0cadb0cce85691a5723bc94ae2fae
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004bd6037e5cf0cadb0cce85691a5723bc94ae2fae
-----Decoded View---------------
Arg [0] : _admin (address): 0x4bd6037e5cf0cadb0cce85691a5723bc94ae2fae
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000004bd6037e5cf0cadb0cce85691a5723bc94ae2fae
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.