More Info
Private Name Tags
ContractCreator
Multi Chain
Multichain Addresses
9 addresses found via
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
vlCvxExtraRewardDistribution
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-10-08 */ // File: contracts\interfaces\ILockedCvx.sol // SPDX-License-Identifier: MIT pragma solidity 0.6.12; interface ILockedCvx{ function lock(address _account, uint256 _amount, uint256 _spendRatio) external; function processExpiredLocks(bool _relock, uint256 _spendRatio, address _withdrawTo) external; function getReward(address _account, bool _stake) external; function balanceAtEpochOf(uint256 _epoch, address _user) view external returns(uint256 amount); function totalSupplyAtEpoch(uint256 _epoch) view external returns(uint256 supply); function epochCount() external view returns(uint256); function checkpointEpoch() external; } // File: contracts\interfaces\BoringMath.sol pragma solidity 0.6.12; /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). library BoringMath { function add(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "BoringMath: division by zero"); return a / b; } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= uint128(-1), "BoringMath: uint128 Overflow"); c = uint128(a); } function to64(uint256 a) internal pure returns (uint64 c) { require(a <= uint64(-1), "BoringMath: uint64 Overflow"); c = uint64(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= uint32(-1), "BoringMath: uint32 Overflow"); c = uint32(a); } function to40(uint256 a) internal pure returns (uint40 c) { require(a <= uint40(-1), "BoringMath: uint40 Overflow"); c = uint40(a); } function to112(uint256 a) internal pure returns (uint112 c) { require(a <= uint112(-1), "BoringMath: uint112 Overflow"); c = uint112(a); } function to224(uint256 a) internal pure returns (uint224 c) { require(a <= uint224(-1), "BoringMath: uint224 Overflow"); c = uint224(a); } function to208(uint256 a) internal pure returns (uint208 c) { require(a <= uint208(-1), "BoringMath: uint208 Overflow"); c = uint208(a); } function to216(uint256 a) internal pure returns (uint216 c) { require(a <= uint216(-1), "BoringMath: uint216 Overflow"); c = uint216(a); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint128. library BoringMath128 { function add(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint64. library BoringMath64 { function add(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. library BoringMath32 { function add(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint32 a, uint32 b) internal pure returns (uint32 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint32 a, uint32 b) internal pure returns (uint32) { require(b > 0, "BoringMath: division by zero"); return a / b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint112. library BoringMath112 { function add(uint112 a, uint112 b) internal pure returns (uint112 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint112 a, uint112 b) internal pure returns (uint112 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint112 a, uint112 b) internal pure returns (uint112 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint112 a, uint112 b) internal pure returns (uint112) { require(b > 0, "BoringMath: division by zero"); return a / b; } } /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint224. library BoringMath224 { function add(uint224 a, uint224 b) internal pure returns (uint224 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint224 a, uint224 b) internal pure returns (uint224 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint224 a, uint224 b) internal pure returns (uint224 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function div(uint224 a, uint224 b) internal pure returns (uint224) { require(b > 0, "BoringMath: division by zero"); return a / b; } } // File: @openzeppelin\contracts\token\ERC20\IERC20.sol pragma solidity >=0.6.0 <0.8.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); } // File: node_modules\@openzeppelin\contracts\math\SafeMath.sol pragma solidity >=0.6.0 <0.8.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; } } // File: node_modules\@openzeppelin\contracts\utils\Address.sol pragma solidity >=0.6.2 <0.8.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); } } } } // File: @openzeppelin\contracts\token\ERC20\SafeERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @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"); } } } // File: contracts\vlCvxExtraRewardDistribution.sol pragma solidity 0.6.12; //Distribute various rewards to locked cvx holders // - Rewards added are assigned to the previous epoch (it was the previous epoch lockers who deserve today's rewards) // - As soon as claiming for a token at an epoch is eligibe, no more tokens should be allowed to be added // - To allow multiple txs to add to the same token, rewards added during the current epoch (and assigned to previous) will not // be claimable until the beginning of the next epoch. The "reward assigning phase" must be complete first //example: //Current epoch: 10 //During this week all addReward() calls are assigned to users in epoch 9 //Users who were locked in epoch 9 can claim once epoch 11 begins // -> epoch 10 is the assigning phase for epoch 9, thus we must wait until 10 is complete before claiming 9 contract vlCvxExtraRewardDistribution { using SafeERC20 for IERC20; using BoringMath for uint256; ILockedCvx public constant cvxlocker = ILockedCvx(0xD18140b4B819b895A3dba5442F959fA44994AF50); uint256 public constant rewardsDuration = 86400 * 7; mapping(address => mapping(uint256 => uint256)) public rewardData; // token -> epoch -> amount mapping(address => uint256[]) public rewardEpochs; // token -> epochList mapping(address => mapping(address => uint256)) public userClaims; //token -> account -> last claimed epoch index constructor() public {} function rewardEpochsCount(address _token) external view returns(uint256) { return rewardEpochs[_token].length; } //add a reward to a specific epoch function addRewardToEpoch(address _token, uint256 _amount, uint256 _epoch) external { //checkpoint locker cvxlocker.checkpointEpoch(); //if adding a reward to a specific epoch, make sure it's //a.) an epoch older than the previous epoch (in which case use addReward) //b.) more recent than the previous reward //this means addRewardToEpoch can only be called *once* for a specific reward for a specific epoch //because they will be claimable immediately and amount shouldnt change after claiming begins // //conversely rewards can be piled up with addReward() because claiming is only available to completed epochs require(_epoch < cvxlocker.epochCount() - 2, "!prev epoch"); uint256 l = rewardEpochs[_token].length; require(l == 0 || rewardEpochs[_token][l - 1] < _epoch, "old epoch"); _addReward(_token, _amount, _epoch); } //add a reward to the current epoch. can be called multiple times for the same reward token function addReward(address _token, uint256 _amount) external { //checkpoint locker cvxlocker.checkpointEpoch(); //assign to previous epoch uint256 prevEpoch = cvxlocker.epochCount() - 2; _addReward(_token, _amount, prevEpoch); } function _addReward(address _token, uint256 _amount, uint256 _epoch) internal { //convert to reward per token uint256 supply = cvxlocker.totalSupplyAtEpoch(_epoch); uint256 rPerT = _amount.mul(1e20).div(supply); rewardData[_token][_epoch] = rewardData[_token][_epoch].add(rPerT); //add epoch to list uint256 l = rewardEpochs[_token].length; if (l == 0 || rewardEpochs[_token][l - 1] < _epoch) { rewardEpochs[_token].push(_epoch); } //pull IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount); //event emit RewardAdded(_token, _epoch, _amount); } //get claimable rewards for a specific token function claimableRewards(address _account, address _token) external view returns(uint256) { (uint256 rewards,) = _allClaimableRewards(_account, _token); return rewards; } //get claimable rewards for a token at a specific epoch function claimableRewardsAtEpoch(address _account, address _token, uint256 _epoch) external view returns(uint256) { return _claimableRewards(_account, _token, _epoch); } //get all claimable rewards function _allClaimableRewards(address _account, address _token) internal view returns(uint256,uint256) { uint256 epochIndex = userClaims[_token][_account]; uint256 prevEpoch = cvxlocker.epochCount() - 2; uint256 claimableTokens = 0; for (uint256 i = epochIndex; i < rewardEpochs[_token].length; i++) { //only claimable after rewards are "locked in" if (rewardEpochs[_token][i] < prevEpoch) { claimableTokens = claimableTokens.add(_claimableRewards(_account, _token, rewardEpochs[_token][i])); //return index user claims should be set to epochIndex = i+1; } } return (claimableTokens, epochIndex); } //get claimable rewards for a token at a specific epoch function _claimableRewards(address _account, address _token, uint256 _epoch) internal view returns(uint256) { //get balance and calc share uint256 balance = cvxlocker.balanceAtEpochOf(_epoch, _account); return balance.mul(rewardData[_token][_epoch]).div(1e20); } //claim rewards for a specific token at a specific epoch function getReward(address _account, address _token) public { //get claimable tokens (uint256 claimableTokens, uint256 index) = _allClaimableRewards(_account, _token); if (claimableTokens > 0) { //set claim checkpoint userClaims[_token][_account] = index; //send IERC20(_token).safeTransfer(_account, claimableTokens); //event emit RewardPaid(_account, _token, claimableTokens); } } //claim multiple tokens function getRewards(address _account, address[] calldata _tokens) external { for(uint i = 0; i < _tokens.length; i++){ getReward(_account, _tokens[i]); } } //Because claims cycle through all periods that a specific reward was given //there becomes a situation where, for example, a new user could lock //2 years from now and try to claim a token that was given out every week prior. //This would result in a 2mil gas checkpoint.(about 20k gas * 52 weeks * 2 years) // //allow a user to set their claimed index forward without claiming rewards function forfeitRewards(address _token, uint256 _index) external { require(_index > 0 && _index < rewardEpochs[_token].length-1, "!past"); require(_index >= userClaims[_token][msg.sender], "already claimed"); //set claim checkpoint. next claim starts from index+1 userClaims[_token][msg.sender] = _index + 1; emit RewardForfeited(msg.sender, _token, _index); } /* ========== EVENTS ========== */ event RewardAdded(address indexed _token, uint256 indexed _epoch, uint256 _reward); event RewardPaid(address indexed _user, address indexed _rewardsToken, uint256 _reward); event RewardForfeited(address indexed _user, address indexed _rewardsToken, uint256 _index); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":true,"internalType":"uint256","name":"_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_rewardsToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"}],"name":"RewardForfeited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_rewardsToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"_reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"addRewardToEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"claimableRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"claimableRewardsAtEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvxlocker","outputs":[{"internalType":"contract ILockedCvx","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"forfeitRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"getRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardData","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardEpochs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"rewardEpochsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506111c9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063408ad08b1161008c5780636be9dcce116100665780636be9dcce146102b85780639feb8f50146102e6578063d527f4b914610312578063f8f6608514610338576100cf565b8063408ad08b1461023057806361544f601461025e5780636b0916951461028a576100cf565b8063221edb3b146100d457806329919002146101025780632fae1e1414610134578063381748621461017c578063386a9525146101a85780633d8e846e146101b0575b600080fd5b610100600480360360408110156100ea57600080fd5b506001600160a01b03813516906020013561035c565b005b6101006004803603606081101561011857600080fd5b506001600160a01b03813516906020810135906040013561048c565b61016a6004803603606081101561014a57600080fd5b506001600160a01b03813581169160208101359091169060400135610657565b60408051918252519081900360200190f35b61016a6004803603604081101561019257600080fd5b506001600160a01b03813516906020013561066e565b61016a610688565b610100600480360360408110156101c657600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156101f157600080fd5b82018360208201111561020357600080fd5b8035906020019184602083028401116401000000008311171561022557600080fd5b50909250905061068f565b61016a6004803603604081101561024657600080fd5b506001600160a01b03813581169160200135166106c7565b61016a6004803603604081101561027457600080fd5b506001600160a01b0381351690602001356106e4565b610100600480360360408110156102a057600080fd5b506001600160a01b0381358116916020013516610712565b61016a600480360360408110156102ce57600080fd5b506001600160a01b03813581169160200135166107b1565b610100600480360360408110156102fc57600080fd5b506001600160a01b0381351690602001356107c9565b61016a6004803603602081101561032857600080fd5b50356001600160a01b03166108c0565b6103406108db565b604080516001600160a01b039092168252519081900360200190f35b60008111801561038757506001600160a01b0382166000908152600160205260409020546000190181105b6103c0576040805162461bcd60e51b8152602060048201526005602482015264085c185cdd60da1b604482015290519081900360640190fd5b6001600160a01b038216600090815260026020908152604080832033845290915290205481101561042a576040805162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b604482015290519081900360640190fd5b6001600160a01b03821660008181526002602090815260408083203380855290835292819020600186019055805185815290517fdeef6364f7ce8c2fc21e3df048b8f1b79714f67289c433ad888cd76cc1267f9f929181900390910190a35050565b73d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663c1009f4b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104db57600080fd5b505af11580156104ef573d6000803e3d6000fd5b50505050600273d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663829965cc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054257600080fd5b505afa158015610556573d6000803e3d6000fd5b505050506040513d602081101561056c57600080fd5b50510381106105b0576040805162461bcd60e51b815260206004820152600b60248201526a042e0e4caec40cae0dec6d60ab1b604482015290519081900360640190fd5b6001600160a01b03831660009081526001602052604090205480158061060957506001600160a01b0384166000908152600160205260409020805483919060001984019081106105fc57fe5b9060005260206000200154105b610646576040805162461bcd60e51b81526020600482015260096024820152680ded8c840cae0dec6d60bb1b604482015290519081900360640190fd5b6106518484846108f3565b50505050565b6000610664848484610ac5565b90505b9392505050565b600060208181529281526040808220909352908152205481565b62093a8081565b60005b81811015610651576106bf848484848181106106aa57fe5b905060200201356001600160a01b0316610712565b600101610692565b600260209081526000928352604080842090915290825290205481565b600160205281600052604060002081815481106106fd57fe5b90600052602060002001600091509150505481565b60008061071f8484610ba5565b90925090508115610651576001600160a01b038084166000818152600260209081526040808320948916835293905291909120829055610760908584610d15565b826001600160a01b0316846001600160a01b03167f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e846040518082815260200191505060405180910390a350505050565b6000806107be8484610ba5565b509150505b92915050565b73d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663c1009f4b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561081857600080fd5b505af115801561082c573d6000803e3d6000fd5b505050506000600273d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663829965cc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561088157600080fd5b505afa158015610895573d6000803e3d6000fd5b505050506040513d60208110156108ab57600080fd5b50510390506108bb8383836108f3565b505050565b6001600160a01b031660009081526001602052604090205490565b73d18140b4b819b895a3dba5442f959fa44994af5081565b600073d18140b4b819b895a3dba5442f959fa44994af506001600160a01b03166370b36d79836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561094d57600080fd5b505afa158015610961573d6000803e3d6000fd5b505050506040513d602081101561097757600080fd5b50519050600061099a826109948668056bc75e2d63100000610d67565b90610dd3565b6001600160a01b0386166000908152602081815260408083208784529091529020549091506109c99082610e3a565b6001600160a01b03861660008181526020818152604080832088845282528083209490945591815260019091522054801580610a3857506001600160a01b038616600090815260016020526040902080548591906000198401908110610a2b57fe5b9060005260206000200154105b15610a68576001600160a01b03861660009081526001602081815260408320805492830181558352909120018490555b610a7d6001600160a01b038716333088610e92565b60408051868152905185916001600160a01b038916917f6a6f77044107a33658235d41bedbbaf2fe9ccdceb313143c947a5e76e1ec84749181900360200190a3505050505050565b60008073d18140b4b819b895a3dba5442f959fa44994af506001600160a01b0316631c60739584876040518363ffffffff1660e01b815260040180838152602001826001600160a01b031681526020019250505060206040518083038186803b158015610b3157600080fd5b505afa158015610b45573d6000803e3d6000fd5b505050506040513d6020811015610b5b57600080fd5b50516001600160a01b038516600090815260208181526040808320878452909152902054909150610b9c9068056bc75e2d6310000090610994908490610d67565b95945050505050565b6001600160a01b03808216600090815260026020818152604080842094871684529381528383205484516320a6597360e21b815294519394859491938593909273d18140b4b819b895a3dba5442f959fa44994af509263829965cc926004808301939192829003018186803b158015610c1d57600080fd5b505afa158015610c31573d6000803e3d6000fd5b505050506040513d6020811015610c4757600080fd5b50510390506000825b6001600160a01b038716600090815260016020526040902054811015610d08576001600160a01b0387166000908152600160205260409020805484919083908110610c9757fe5b90600052602060002001541015610d0057610cf7610cf08989600160008c6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610ce057fe5b9060005260206000200154610ac5565b8390610e3a565b91508060010193505b600101610c50565b5096919550909350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526108bb908490610ee8565b6000811580610d8257505080820282828281610d7f57fe5b04145b6107c3576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604482015290519081900360640190fd5b6000808211610e29576040805162461bcd60e51b815260206004820152601c60248201527f426f72696e674d6174683a206469766973696f6e206279207a65726f00000000604482015290519081900360640190fd5b818381610e3257fe5b049392505050565b818101818110156107c3576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604482015290519081900360640190fd5b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526106519085905b6060610f3d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610f999092919063ffffffff16565b8051909150156108bb57808060200190516020811015610f5c57600080fd5b50516108bb5760405162461bcd60e51b815260040180806020018281038252602a81526020018061116a602a913960400191505060405180910390fd5b6060610664848460008585610fad856110bf565b610ffe576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061103d5780518252601f19909201916020918201910161101e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461109f576040519150601f19603f3d011682016040523d82523d6000602084013e6110a4565b606091505b50915091506110b48282866110c5565b979650505050505050565b3b151590565b606083156110d4575081610667565b8251156110e45782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561112e578181015183820152602001611116565b50505050905090810190601f16801561115b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220c30d8927e61fd3aec6fa15fdae1d7cd11be71a7672ff55f7ce548ef179a0170264736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063408ad08b1161008c5780636be9dcce116100665780636be9dcce146102b85780639feb8f50146102e6578063d527f4b914610312578063f8f6608514610338576100cf565b8063408ad08b1461023057806361544f601461025e5780636b0916951461028a576100cf565b8063221edb3b146100d457806329919002146101025780632fae1e1414610134578063381748621461017c578063386a9525146101a85780633d8e846e146101b0575b600080fd5b610100600480360360408110156100ea57600080fd5b506001600160a01b03813516906020013561035c565b005b6101006004803603606081101561011857600080fd5b506001600160a01b03813516906020810135906040013561048c565b61016a6004803603606081101561014a57600080fd5b506001600160a01b03813581169160208101359091169060400135610657565b60408051918252519081900360200190f35b61016a6004803603604081101561019257600080fd5b506001600160a01b03813516906020013561066e565b61016a610688565b610100600480360360408110156101c657600080fd5b6001600160a01b0382351691908101906040810160208201356401000000008111156101f157600080fd5b82018360208201111561020357600080fd5b8035906020019184602083028401116401000000008311171561022557600080fd5b50909250905061068f565b61016a6004803603604081101561024657600080fd5b506001600160a01b03813581169160200135166106c7565b61016a6004803603604081101561027457600080fd5b506001600160a01b0381351690602001356106e4565b610100600480360360408110156102a057600080fd5b506001600160a01b0381358116916020013516610712565b61016a600480360360408110156102ce57600080fd5b506001600160a01b03813581169160200135166107b1565b610100600480360360408110156102fc57600080fd5b506001600160a01b0381351690602001356107c9565b61016a6004803603602081101561032857600080fd5b50356001600160a01b03166108c0565b6103406108db565b604080516001600160a01b039092168252519081900360200190f35b60008111801561038757506001600160a01b0382166000908152600160205260409020546000190181105b6103c0576040805162461bcd60e51b8152602060048201526005602482015264085c185cdd60da1b604482015290519081900360640190fd5b6001600160a01b038216600090815260026020908152604080832033845290915290205481101561042a576040805162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b604482015290519081900360640190fd5b6001600160a01b03821660008181526002602090815260408083203380855290835292819020600186019055805185815290517fdeef6364f7ce8c2fc21e3df048b8f1b79714f67289c433ad888cd76cc1267f9f929181900390910190a35050565b73d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663c1009f4b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104db57600080fd5b505af11580156104ef573d6000803e3d6000fd5b50505050600273d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663829965cc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054257600080fd5b505afa158015610556573d6000803e3d6000fd5b505050506040513d602081101561056c57600080fd5b50510381106105b0576040805162461bcd60e51b815260206004820152600b60248201526a042e0e4caec40cae0dec6d60ab1b604482015290519081900360640190fd5b6001600160a01b03831660009081526001602052604090205480158061060957506001600160a01b0384166000908152600160205260409020805483919060001984019081106105fc57fe5b9060005260206000200154105b610646576040805162461bcd60e51b81526020600482015260096024820152680ded8c840cae0dec6d60bb1b604482015290519081900360640190fd5b6106518484846108f3565b50505050565b6000610664848484610ac5565b90505b9392505050565b600060208181529281526040808220909352908152205481565b62093a8081565b60005b81811015610651576106bf848484848181106106aa57fe5b905060200201356001600160a01b0316610712565b600101610692565b600260209081526000928352604080842090915290825290205481565b600160205281600052604060002081815481106106fd57fe5b90600052602060002001600091509150505481565b60008061071f8484610ba5565b90925090508115610651576001600160a01b038084166000818152600260209081526040808320948916835293905291909120829055610760908584610d15565b826001600160a01b0316846001600160a01b03167f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e846040518082815260200191505060405180910390a350505050565b6000806107be8484610ba5565b509150505b92915050565b73d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663c1009f4b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561081857600080fd5b505af115801561082c573d6000803e3d6000fd5b505050506000600273d18140b4b819b895a3dba5442f959fa44994af506001600160a01b031663829965cc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561088157600080fd5b505afa158015610895573d6000803e3d6000fd5b505050506040513d60208110156108ab57600080fd5b50510390506108bb8383836108f3565b505050565b6001600160a01b031660009081526001602052604090205490565b73d18140b4b819b895a3dba5442f959fa44994af5081565b600073d18140b4b819b895a3dba5442f959fa44994af506001600160a01b03166370b36d79836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561094d57600080fd5b505afa158015610961573d6000803e3d6000fd5b505050506040513d602081101561097757600080fd5b50519050600061099a826109948668056bc75e2d63100000610d67565b90610dd3565b6001600160a01b0386166000908152602081815260408083208784529091529020549091506109c99082610e3a565b6001600160a01b03861660008181526020818152604080832088845282528083209490945591815260019091522054801580610a3857506001600160a01b038616600090815260016020526040902080548591906000198401908110610a2b57fe5b9060005260206000200154105b15610a68576001600160a01b03861660009081526001602081815260408320805492830181558352909120018490555b610a7d6001600160a01b038716333088610e92565b60408051868152905185916001600160a01b038916917f6a6f77044107a33658235d41bedbbaf2fe9ccdceb313143c947a5e76e1ec84749181900360200190a3505050505050565b60008073d18140b4b819b895a3dba5442f959fa44994af506001600160a01b0316631c60739584876040518363ffffffff1660e01b815260040180838152602001826001600160a01b031681526020019250505060206040518083038186803b158015610b3157600080fd5b505afa158015610b45573d6000803e3d6000fd5b505050506040513d6020811015610b5b57600080fd5b50516001600160a01b038516600090815260208181526040808320878452909152902054909150610b9c9068056bc75e2d6310000090610994908490610d67565b95945050505050565b6001600160a01b03808216600090815260026020818152604080842094871684529381528383205484516320a6597360e21b815294519394859491938593909273d18140b4b819b895a3dba5442f959fa44994af509263829965cc926004808301939192829003018186803b158015610c1d57600080fd5b505afa158015610c31573d6000803e3d6000fd5b505050506040513d6020811015610c4757600080fd5b50510390506000825b6001600160a01b038716600090815260016020526040902054811015610d08576001600160a01b0387166000908152600160205260409020805484919083908110610c9757fe5b90600052602060002001541015610d0057610cf7610cf08989600160008c6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610ce057fe5b9060005260206000200154610ac5565b8390610e3a565b91508060010193505b600101610c50565b5096919550909350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526108bb908490610ee8565b6000811580610d8257505080820282828281610d7f57fe5b04145b6107c3576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a204d756c204f766572666c6f770000000000000000604482015290519081900360640190fd5b6000808211610e29576040805162461bcd60e51b815260206004820152601c60248201527f426f72696e674d6174683a206469766973696f6e206279207a65726f00000000604482015290519081900360640190fd5b818381610e3257fe5b049392505050565b818101818110156107c3576040805162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a20416464204f766572666c6f770000000000000000604482015290519081900360640190fd5b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526106519085905b6060610f3d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610f999092919063ffffffff16565b8051909150156108bb57808060200190516020811015610f5c57600080fd5b50516108bb5760405162461bcd60e51b815260040180806020018281038252602a81526020018061116a602a913960400191505060405180910390fd5b6060610664848460008585610fad856110bf565b610ffe576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061103d5780518252601f19909201916020918201910161101e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461109f576040519150601f19603f3d011682016040523d82523d6000602084013e6110a4565b606091505b50915091506110b48282866110c5565b979650505050505050565b3b151590565b606083156110d4575081610667565b8251156110e45782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561112e578181015183820152602001611116565b50505050905090810190601f16801561115b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220c30d8927e61fd3aec6fa15fdae1d7cd11be71a7672ff55f7ce548ef179a0170264736f6c634300060c0033
Deployed Bytecode Sourcemap
28913:6463:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34634:414;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;34634:414:0;;;;;;;;:::i;:::-;;29705:953;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;29705:953:0;;;;;;;;;;;;;:::i;32070:183::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;32070:183:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;29198:65;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;29198:65:0;;;;;;;;:::i;29138:51::-;;;:::i;34018:191::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34018:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34018:191:0;;-1:-1:-1;34018:191:0;-1:-1:-1;34018:191:0;:::i;29376:65::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;29376:65:0;;;;;;;;;;:::i;29298:49::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;29298:49:0;;;;;;;;:::i;33474:507::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;33474:507:0;;;;;;;;;;:::i;31807:194::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;31807:194:0;;;;;;;;;;:::i;30763:282::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;30763:282:0;;;;;;;;:::i;29530:127::-;;;;;;;;;;;;;;;;-1:-1:-1;29530:127:0;-1:-1:-1;;;;;29530:127:0;;:::i;29038:93::-;;;:::i;:::-;;;;-1:-1:-1;;;;;29038:93:0;;;;;;;;;;;;;;34634:414;34727:1;34718:6;:10;:52;;;;-1:-1:-1;;;;;;34741:20:0;;;;;;34769:1;34741:20;;;;;:27;-1:-1:-1;;34741:29:0;34732:38;;34718:52;34710:70;;;;;-1:-1:-1;;;34710:70:0;;;;;;;;;;;;-1:-1:-1;;;34710:70:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;34809:18:0;;;;;;:10;:18;;;;;;;;34828:10;34809:30;;;;;;;;34799:40;;;34791:68;;;;;-1:-1:-1;;;34791:68:0;;;;;;;;;;;;-1:-1:-1;;;34791:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;34936:18:0;;;;;;:10;:18;;;;;;;;34955:10;34936:30;;;;;;;;;;34978:1;34969:10;;34936:43;;34997;;;;;;;;;;;;;;;;;;34634:414;;:::o;29705:953::-;29088:42;-1:-1:-1;;;;;29829:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30456:1;29088:42;-1:-1:-1;;;;;30431:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30431:22:0;:26;30422:35;;30414:59;;;;;-1:-1:-1;;;30414:59:0;;;;;;;;;;;;-1:-1:-1;;;30414:59:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;30496:20:0;;30484:9;30496:20;;;:12;:20;;;;;:27;30542:6;;;:46;;-1:-1:-1;;;;;;30552:20:0;;;;;;:12;:20;;;;;:27;;30582:6;;30552:20;-1:-1:-1;;30573:5:0;;;30552:27;;;;;;;;;;;;;;:36;30542:46;30534:68;;;;;-1:-1:-1;;;30534:68:0;;;;;;;;;;;;-1:-1:-1;;;30534:68:0;;;;;;;;;;;;;;;30615:35;30626:6;30634:7;30643:6;30615:10;:35::i;:::-;29705:953;;;;:::o;32070:183::-;32175:7;32202:43;32220:8;32230:6;32238;32202:17;:43::i;:::-;32195:50;;32070:183;;;;;;:::o;29198:65::-;;;;;;;;;;;;;;;;;;;;;;:::o;29138:51::-;29180:9;29138:51;:::o;34018:191::-;34108:6;34104:98;34120:18;;;34104:98;;;34159:31;34169:8;34179:7;;34187:1;34179:10;;;;;;;;;;;;;-1:-1:-1;;;;;34179:10:0;34159:9;:31::i;:::-;34140:3;;34104:98;;29376:65;;;;;;;;;;;;;;;;;;;;;;;;:::o;29298:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;33474:507::-;33578:23;33603:13;33620:38;33641:8;33651:6;33620:20;:38::i;:::-;33577:81;;-1:-1:-1;33577:81:0;-1:-1:-1;33675:19:0;;33671:303;;-1:-1:-1;;;;;33747:18:0;;;;;;;:10;:18;;;;;;;;:28;;;;;;;;;;;;:36;;;33820:54;;33766:8;33858:15;33820:27;:54::i;:::-;33938:6;-1:-1:-1;;;;;33917:45:0;33928:8;-1:-1:-1;;;;;33917:45:0;;33946:15;33917:45;;;;;;;;;;;;;;;;;;33474:507;;;;:::o;31807:194::-;31889:7;31910:15;31930:38;31951:8;31961:6;31930:20;:38::i;:::-;-1:-1:-1;31909:59:0;-1:-1:-1;;31807:194:0;;;;;:::o;30763:282::-;29088:42;-1:-1:-1;;;;;30864:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30940:17;30985:1;29088:42;-1:-1:-1;;;;;30960:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30960:22:0;:26;;-1:-1:-1;30999:38:0;31010:6;31018:7;30960:26;30999:10;:38::i;:::-;30763:282;;;:::o;29530:127::-;-1:-1:-1;;;;;29622:20:0;29595:7;29622:20;;;:12;:20;;;;;:27;;29530:127::o;29038:93::-;29088:42;29038:93;:::o;31053:696::-;31181:14;29088:42;-1:-1:-1;;;;;31198:28:0;;31227:6;31198:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31198:36:0;;-1:-1:-1;31245:13:0;31261:29;31198:36;31261:17;:7;31273:4;31261:11;:17::i;:::-;:21;;:29::i;:::-;-1:-1:-1;;;;;31330:18:0;;:10;:18;;;;;;;;;;;:26;;;;;;;;;31245:45;;-1:-1:-1;31330:37:0;;31245:45;31330:30;:37::i;:::-;-1:-1:-1;;;;;31301:18:0;;:10;:18;;;;;;;;;;;:26;;;;;;;;:66;;;;31421:20;;;:12;:20;;;;:27;31463:6;;;:46;;-1:-1:-1;;;;;;31473:20:0;;;;;;:12;:20;;;;;:27;;31503:6;;31473:20;-1:-1:-1;;31494:5:0;;;31473:27;;;;;;;;;;;;;;:36;31463:46;31459:112;;;-1:-1:-1;;;;;31526:20:0;;;;;;:12;:20;;;;;;;:33;;;;;;;;;;;;;;;;31459:112;31599:67;-1:-1:-1;;;;;31599:31:0;;31631:10;31651:4;31658:7;31599:31;:67::i;:::-;31705:36;;;;;;;;31725:6;;-1:-1:-1;;;;;31705:36:0;;;;;;;;;;;;31053:696;;;;;;:::o;33110:294::-;33209:7;33267:15;29088:42;-1:-1:-1;;;;;33285:26:0;;33312:6;33320:8;33285:44;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33285:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33285:44:0;-1:-1:-1;;;;;33359:18:0;;:10;:18;;;33285:44;33359:18;;;;;;;:26;;;;;;;;;33285:44;;-1:-1:-1;33347:49:0;;33391:4;;33347:39;;33285:44;;33347:11;:39::i;:49::-;33340:56;33110:294;-1:-1:-1;;;;;33110:294:0:o;32294:747::-;-1:-1:-1;;;;;32429:18:0;;;32380:7;32429:18;;;:10;:18;;;;;;;;:28;;;;;;;;;;;;32488:22;;-1:-1:-1;;;32488:22:0;;;;32380:7;;;;32429:28;;32380:7;;32429:10;;29088:42;;32488:20;;:22;;;;;32429:18;;32488:22;;;;;29088:42;32488:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32488:22:0;:26;;-1:-1:-1;32525:23:0;32580:10;32563:424;-1:-1:-1;;;;;32596:20:0;;;;;;:12;:20;;;;;:27;32592:31;;32563:424;;;-1:-1:-1;;;;;32709:20:0;;;;;;:12;:20;;;;;:23;;32735:9;;32709:20;32730:1;;32709:23;;;;;;;;;;;;;;:35;32705:271;;;32783:81;32803:60;32821:8;32831:6;32839:12;:20;32852:6;-1:-1:-1;;;;;32839:20:0;-1:-1:-1;;;;;32839:20:0;;;;;;;;;;;;32860:1;32839:23;;;;;;;;;;;;;;;;32803:17;:60::i;:::-;32783:15;;:19;:81::i;:::-;32765:99;;32957:1;32959;32957:3;32944:16;;32705:271;32625:3;;32563:424;;;-1:-1:-1;33005:15:0;33022:10;;-1:-1:-1;32294:747:0;;-1:-1:-1;;;;32294:747:0:o;24952:177::-;25062:58;;;-1:-1:-1;;;;;25062:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25062:58:0;-1:-1:-1;;;25062:58:0;;;25035:86;;25055:5;;25035:19;:86::i;1225:155::-;1283:9;1313:6;;;:30;;-1:-1:-1;;1328:5:0;;;1342:1;1337;1328:5;1337:1;1323:15;;;;;:20;1313:30;1305:67;;;;;-1:-1:-1;;;1305:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;1388:155;1446:7;1478:1;1474;:5;1466:46;;;;;-1:-1:-1;;;1466:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1534:1;1530;:5;;;;;;;1388:155;-1:-1:-1;;;1388:155:0:o;930:141::-;1023:5;;;1018:16;;;;1010:53;;;;;-1:-1:-1;;;1010:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;25137:205;25265:68;;;-1:-1:-1;;;;;25265:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25265:68:0;-1:-1:-1;;;25265:68:0;;;25238:96;;25258:5;;27257:761;27681:23;27707:69;27735:4;27707:69;;;;;;;;;;;;;;;;;27715:5;-1:-1:-1;;;;;27707:27:0;;;:69;;;;;:::i;:::-;27791:17;;27681:95;;-1:-1:-1;27791:21:0;27787:224;;27933:10;27922:30;;;;;;;;;;;;;;;-1:-1:-1;27922:30:0;27914:85;;;;-1:-1:-1;;;27914:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19951:195;20054:12;20086:52;20108:6;20116:4;20122:1;20125:12;20054;21255:18;21266:6;21255:10;:18::i;:::-;21247:60;;;;;-1:-1:-1;;;21247:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;21381:12;21395:23;21422:6;-1:-1:-1;;;;;21422:11:0;21442:5;21450:4;21422:33;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;21422:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21380:75;;;;21473:52;21491:7;21500:10;21512:12;21473:17;:52::i;:::-;21466:59;21003:530;-1:-1:-1;;;;;;;21003:530:0:o;17033:422::-;17400:20;17439:8;;;17033:422::o;23543:742::-;23658:12;23687:7;23683:595;;;-1:-1:-1;23718:10:0;23711:17;;23683:595;23832:17;;:21;23828:439;;24095:10;24089:17;24156:15;24143:10;24139:2;24135:19;24128:44;24043:148;24238:12;24231:20;;-1:-1:-1;;;24231:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Swarm Source
ipfs://c30d8927e61fd3aec6fa15fdae1d7cd11be71a7672ff55f7ce548ef179a01702
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.