Token
Overview
Total Supply:
73,867,685.954816 N/A
Holders:
0 addresses
Transfers:
-
Contract:
Decimals:
18
[ Download CSV Export ]
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x78d4BFb3b50E5895932073DC5Eb4713eb532941B
Contract Name:
StakingRewards
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-11-03 */ // Sources flattened with hardhat v2.6.3 https://hardhat.org // File openzeppelin-contracts-legacy/GSN/[email protected] // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File openzeppelin-contracts-legacy/access/[email protected] pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File openzeppelin-contracts-legacy/math/[email protected] pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // File openzeppelin-contracts-legacy/math/[email protected] 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, 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) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * 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); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File openzeppelin-contracts-legacy/token/ERC20/[email protected] 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 openzeppelin-contracts-legacy/utils/[email protected] 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); } 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-legacy/token/ERC20/[email protected] 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 openzeppelin-contracts-legacy/utils/[email protected] pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File @pangolindex/exchange-contracts/contracts/pangolin-core/interfaces/[email protected] pragma solidity >=0.5.0; interface IPangolinERC20 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; } // File contracts/StakingRewards.sol pragma solidity ^0.7.6; // https://docs.synthetix.io/contracts/source/contracts/stakingrewards contract StakingRewards is ReentrancyGuard, Ownable { using SafeMath for uint256; using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ IERC20 public rewardsToken; IERC20 public stakingToken; uint256 public periodFinish = 0; uint256 public rewardRate = 0; uint256 public rewardsDuration = 1 days; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; uint256 private _totalSupply; mapping(address => uint256) private _balances; /* ========== CONSTRUCTOR ========== */ constructor( address _rewardsToken, address _stakingToken ) public { rewardsToken = IERC20(_rewardsToken); stakingToken = IERC20(_stakingToken); } /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { return _totalSupply; } function balanceOf(address account) external view returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable() public view returns (uint256) { return Math.min(block.timestamp, periodFinish); } function rewardPerToken() public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply) ); } function earned(address account) public view returns (uint256) { return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]); } function getRewardForDuration() external view returns (uint256) { return rewardRate.mul(rewardsDuration); } /* ========== MUTATIVE FUNCTIONS ========== */ function stakeWithPermit(uint256 amount, uint deadline, uint8 v, bytes32 r, bytes32 s) external nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); // permit IPangolinERC20(address(stakingToken)).permit(msg.sender, address(this), amount, deadline, v, r, s); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function stake(uint256 amount) external nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); stakingToken.safeTransfer(msg.sender, amount); emit Withdrawn(msg.sender, amount); } function getReward() public nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; rewardsToken.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } function exit() external { withdraw(_balances[msg.sender]); getReward(); } /* ========== RESTRICTED FUNCTIONS ========== */ // Always needs to update the balance of the contract when calling this method function notifyRewardAmount(uint256 reward) external onlyOwner updateReward(address(0)) { if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); rewardRate = reward.add(leftover).div(rewardsDuration); } // Ensure the provided reward amount is not more than the balance in the contract. // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. uint balance = rewardsToken.balanceOf(address(this)); require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); lastUpdateTime = block.timestamp; periodFinish = block.timestamp.add(rewardsDuration); emit RewardAdded(reward); } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner nonReentrant { require(tokenAddress != address(stakingToken), "Cannot withdraw the staking token"); IERC20(tokenAddress).safeTransfer(owner(), tokenAmount); emit Recovered(tokenAddress, tokenAmount); } function setRewardsDuration(uint256 _rewardsDuration) external onlyOwner { require( block.timestamp > periodFinish, "Previous rewards period must be complete before changing the duration for the new period" ); require(_rewardsDuration > 0, "Reward duration can't be zero"); rewardsDuration = _rewardsDuration; emit RewardsDurationUpdated(rewardsDuration); } /* ========== MODIFIERS ========== */ modifier updateReward(address account) { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; } /* ========== EVENTS ========== */ event RewardAdded(uint256 reward); event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); event RewardsDurationUpdated(uint256 newDuration); event Recovered(address token, uint256 amount); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"stakeWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600060045560006005556201518060065534801561002157600080fd5b50604051611b8a380380611b8a8339818101604052604081101561004457600080fd5b5080516020909101516001600090815561005c6100db565b600180546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600280546001600160a01b039384166001600160a01b031991821617909155600380549290931691161790556100df565b3390565b611a9c806100ee6000396000f3fe608060405234801561001057600080fd5b50600436106101ad5760003560e01c80638980f11f116100ee578063cd3daf9d11610097578063e9fad8ee11610071578063e9fad8ee14610382578063ebe2b12b1461038a578063ecd9ba8214610392578063f2fde38b146103ca576101ad565b8063cd3daf9d1461036a578063d1af0c7d14610372578063df136d651461037a576101ad565b8063a694fc3a116100c8578063a694fc3a14610328578063c8f33c9114610345578063cc1a378f1461034d576101ad565b80638980f11f146102ce5780638b876347146102fa5780638da5cb5b14610320576101ad565b80633c6b16ab1161015b578063715018a611610135578063715018a61461029257806372f702f31461029a5780637b0a47ee146102be57806380faa57d146102c6576101ad565b80633c6b16ab146102475780633d18b9121461026457806370a082311461026c576101ad565b80631c1f78eb1161018c5780631c1f78eb146102185780632e1a7d4d14610220578063386a95251461023f576101ad565b80628cc262146101b25780630700037d146101ea57806318160ddd14610210575b600080fd5b6101d8600480360360208110156101c857600080fd5b50356001600160a01b03166103f0565b60408051918252519081900360200190f35b6101d86004803603602081101561020057600080fd5b50356001600160a01b031661046e565b6101d8610480565b6101d8610487565b61023d6004803603602081101561023657600080fd5b50356104a5565b005b6101d8610647565b61023d6004803603602081101561025d57600080fd5b503561064d565b61023d6108ba565b6101d86004803603602081101561028257600080fd5b50356001600160a01b03166109f1565b61023d610a0c565b6102a2610acd565b604080516001600160a01b039092168252519081900360200190f35b6101d8610adc565b6101d8610ae2565b61023d600480360360408110156102e457600080fd5b506001600160a01b038135169060200135610af0565b6101d86004803603602081101561031057600080fd5b50356001600160a01b0316610c6d565b6102a2610c7f565b61023d6004803603602081101561033e57600080fd5b5035610c8e565b6101d8610e31565b61023d6004803603602081101561036357600080fd5b5035610e37565b6101d8610f71565b6102a2610fbf565b6101d8610fce565b61023d610fd4565b6101d8610ff7565b61023d600480360360a08110156103a857600080fd5b5080359060208101359060ff6040820135169060608101359060800135610ffd565b61023d600480360360208110156103e057600080fd5b50356001600160a01b0316611248565b6001600160a01b0381166000908152600a60209081526040808320546009909252822054610468919061046290670de0b6b3a76400009061045c9061043d90610437610f71565b90611360565b6001600160a01b0388166000908152600c6020526040902054906113a9565b90611402565b90611444565b92915050565b600a6020526000908152604090205481565b600b545b90565b60006104a06006546005546113a990919063ffffffff16565b905090565b600260005414156104fd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000553361050b610f71565b600855610516610ae2565b6007556001600160a01b0381161561055d57610531816103f0565b6001600160a01b0382166000908152600a60209081526040808320939093556008546009909152919020555b600082116105b2576040805162461bcd60e51b815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015290519081900360640190fd5b600b546105bf9083611360565b600b55336000908152600c60205260409020546105dc9083611360565b336000818152600c6020526040902091909155600354610608916001600160a01b03909116908461149e565b60408051838152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a250506001600055565b60065481565b610655611523565b6001546001600160a01b039081169116146106b7576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60006106c1610f71565b6008556106cc610ae2565b6007556001600160a01b03811615610713576106e7816103f0565b6001600160a01b0382166000908152600a60209081526040808320939093556008546009909152919020555b60045442106107325760065461072a908390611402565b600555610775565b6004546000906107429042611360565b9050600061075b600554836113a990919063ffffffff16565b60065490915061076f9061045c8684611444565b60055550505b600254604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156107d957600080fd5b505afa1580156107ed573d6000803e3d6000fd5b505050506040513d602081101561080357600080fd5b5051600654909150610816908290611402565b600554111561086c576040805162461bcd60e51b815260206004820152601860248201527f50726f76696465642072657761726420746f6f20686967680000000000000000604482015290519081900360640190fd5b42600781905560065461087f9190611444565b6004556040805184815290517fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9181900360200190a1505050565b60026000541415610912576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005533610920610f71565b60085561092b610ae2565b6007556001600160a01b0381161561097257610946816103f0565b6001600160a01b0382166000908152600a60209081526040808320939093556008546009909152919020555b336000908152600a602052604090205480156109e857336000818152600a60205260408120556002546109b1916001600160a01b03909116908361149e565b60408051828152905133917fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486919081900360200190a25b50506001600055565b6001600160a01b03166000908152600c602052604090205490565b610a14611523565b6001546001600160a01b03908116911614610a76576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36001805473ffffffffffffffffffffffffffffffffffffffff19169055565b6003546001600160a01b031681565b60055481565b60006104a042600454611527565b610af8611523565b6001546001600160a01b03908116911614610b5a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60026000541415610bb2576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556003546001600160a01b0383811691161415610c045760405162461bcd60e51b8152600401808060200182810382526021815260200180611a466021913960400191505060405180910390fd5b610c20610c0f610c7f565b6001600160a01b038416908361149e565b604080516001600160a01b03841681526020810183905281517f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28929181900390910190a150506001600055565b60096020526000908152604090205481565b6001546001600160a01b031690565b60026000541415610ce6576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005533610cf4610f71565b600855610cff610ae2565b6007556001600160a01b03811615610d4657610d1a816103f0565b6001600160a01b0382166000908152600a60209081526040808320939093556008546009909152919020555b60008211610d9b576040805162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b600b54610da89083611444565b600b55336000908152600c6020526040902054610dc59083611444565b336000818152600c6020526040902091909155600354610df2916001600160a01b0390911690308561153d565b60408051838152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a250506001600055565b60075481565b610e3f611523565b6001546001600160a01b03908116911614610ea1576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6004544211610ee15760405162461bcd60e51b81526004018080602001828103825260588152602001806119576058913960600191505060405180910390fd5b60008111610f36576040805162461bcd60e51b815260206004820152601d60248201527f526577617264206475726174696f6e2063616e2774206265207a65726f000000604482015290519081900360640190fd5b60068190556040805182815290517ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d39181900360200190a150565b6000600b5460001415610f875750600854610484565b6104a0610fb6600b5461045c670de0b6b3a7640000610fb0600554610fb0600754610437610ae2565b906113a9565b60085490611444565b6002546001600160a01b031681565b60085481565b336000908152600c6020526040902054610fed906104a5565b610ff56108ba565b565b60045481565b60026000541415611055576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005533611063610f71565b60085561106e610ae2565b6007556001600160a01b038116156110b557611089816103f0565b6001600160a01b0382166000908152600a60209081526040808320939093556008546009909152919020555b6000861161110a576040805162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b600b546111179087611444565b600b55336000908152600c60205260409020546111349087611444565b336000818152600c60205260408082209390935560035483517fd505accf0000000000000000000000000000000000000000000000000000000081526004810193909352306024840152604483018a90526064830189905260ff8816608484015260a4830187905260c4830186905292516001600160a01b039093169263d505accf9260e480820193929182900301818387803b1580156111d457600080fd5b505af11580156111e8573d6000803e3d6000fd5b505060035461120592506001600160a01b0316905033308961153d565b60408051878152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a25050600160005550505050565b611250611523565b6001546001600160a01b039081169116146112b2576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166112f75760405162461bcd60e51b81526004018080602001828103825260268152602001806119af6026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60006113a283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506115cb565b9392505050565b6000826113b857506000610468565b828202828482816113c557fe5b04146113a25760405162461bcd60e51b81526004018080602001828103825260218152602001806119fb6021913960400191505060405180910390fd5b60006113a283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611662565b6000828201838110156113a2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261151e9084906116c7565b505050565b3390565b600081831061153657816113a2565b5090919050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526115c59085906116c7565b50505050565b6000818484111561165a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561161f578181015183820152602001611607565b50505050905090810190601f16801561164c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836116b15760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561161f578181015183820152602001611607565b5060008385816116bd57fe5b0495945050505050565b600061171c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117789092919063ffffffff16565b80519091501561151e5780806020019051602081101561173b57600080fd5b505161151e5760405162461bcd60e51b815260040180806020018281038252602a815260200180611a1c602a913960400191505060405180910390fd5b6060611787848460008561178f565b949350505050565b6060824710156117d05760405162461bcd60e51b81526004018080602001828103825260268152602001806119d56026913960400191505060405180910390fd5b6117d9856118ea565b61182a576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106118685780518252601f199092019160209182019101611849565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146118ca576040519150601f19603f3d011682016040523d82523d6000602084013e6118cf565b606091505b50915091506118df8282866118f0565b979650505050505050565b3b151590565b606083156118ff5750816113a2565b82511561190f5782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561161f57818101518382015260200161160756fe50726576696f7573207265776172647320706572696f64206d75737420626520636f6d706c657465206265666f7265206368616e67696e6720746865206475726174696f6e20666f7220746865206e657720706572696f644f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656443616e6e6f7420776974686472617720746865207374616b696e6720746f6b656ea26469706673582212206f44426a74f577b6d4f862ae02ec89c75f5c1bc3041e522f4a80381cfe10654964736f6c63430007060033000000000000000000000000340fe1d898eccaad394e2ba0fc1f93d27c7b717a00000000000000000000000060781c2586d68229fde47564546784ab3faca982
Deployed ByteCode Sourcemap
27455:6589:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29089:198;;;;;;;;;;;;;;;;-1:-1:-1;29089:198:0;-1:-1:-1;;;;;29089:198:0;;:::i;:::-;;;;;;;;;;;;;;;;27963:42;;;;;;;;;;;;;;;;-1:-1:-1;27963:42:0;-1:-1:-1;;;;;27963:42:0;;:::i;28391:93::-;;;:::i;29295:121::-;;;:::i;30420:357::-;;;;;;;;;;;;;;;;-1:-1:-1;30420:357:0;;:::i;:::-;;27773:39;;;:::i;31345:1069::-;;;;;;;;;;;;;;;;-1:-1:-1;31345:1069:0;;:::i;30785:307::-;;;:::i;28492:112::-;;;;;;;;;;;;;;;;-1:-1:-1;28492:112:0;-1:-1:-1;;;;;28492:112:0;;:::i;2860:148::-;;;:::i;27666:26::-;;;:::i;:::-;;;;-1:-1:-1;;;;;27666:26:0;;;;;;;;;;;;;;27737:29;;;:::i;28612:131::-;;;:::i;32529:317::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;32529:317:0;;;;;;;;:::i;27899:57::-;;;;;;;;;;;;;;;;-1:-1:-1;27899:57:0;-1:-1:-1;;;;;27899:57:0;;:::i;2218:79::-;;;:::i;30043:369::-;;;;;;;;;;;;;;;;-1:-1:-1;30043:369:0;;:::i;27819:29::-;;;:::i;32854:433::-;;;;;;;;;;;;;;;;-1:-1:-1;32854:433:0;;:::i;28751:330::-;;;:::i;27633:26::-;;;:::i;27855:35::-;;;:::i;31100:97::-;;;:::i;27699:31::-;;;:::i;29478:557::-;;;;;;;;;;;;;;;;-1:-1:-1;29478:557:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;3163:244::-;;;;;;;;;;;;;;;;-1:-1:-1;3163:244:0;-1:-1:-1;;;;;3163:244:0;;:::i;29089:198::-;-1:-1:-1;;;;;29262:16:0;;29143:7;29262:16;;;:7;:16;;;;;;;;;29214:22;:31;;;;;;29170:109;;29262:16;29170:87;;29252:4;;29170:77;;29193:53;;:16;:14;:16::i;:::-;:20;;:53::i;:::-;-1:-1:-1;;;;;29170:18:0;;;;;;:9;:18;;;;;;;:22;:77::i;:::-;:81;;:87::i;:::-;:91;;:109::i;:::-;29163:116;29089:198;-1:-1:-1;;29089:198:0:o;27963:42::-;;;;;;;;;;;;;:::o;28391:93::-;28464:12;;28391:93;;:::o;29295:121::-;29350:7;29377:31;29392:15;;29377:10;;:14;;:31;;;;:::i;:::-;29370:38;;29295:121;:::o;30420:357::-;25073:1;25679:7;;:19;;25671:63;;;;;-1:-1:-1;;;25671:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25073:1;25812:7;:18;30487:10:::1;33413:16;:14;:16::i;:::-;33390:20;:39:::0;33457:26:::1;:24;:26::i;:::-;33440:14;:43:::0;-1:-1:-1;;;;;33498:21:0;::::1;::::0;33494:157:::1;;33555:15;33562:7;33555:6;:15::i;:::-;-1:-1:-1::0;;;;;33536:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;33619:20:::1;::::0;33585:22:::1;:31:::0;;;;;;:54;33494:157:::1;30527:1:::2;30518:6;:10;30510:40;;;::::0;;-1:-1:-1;;;30510:40:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;30576:12;::::0;:24:::2;::::0;30593:6;30576:16:::2;:24::i;:::-;30561:12;:39:::0;30645:10:::2;30635:21;::::0;;;:9:::2;:21;::::0;;;;;:33:::2;::::0;30661:6;30635:25:::2;:33::i;:::-;30621:10;30611:21;::::0;;;:9:::2;:21;::::0;;;;:57;;;;30679:12:::2;::::0;:45:::2;::::0;-1:-1:-1;;;;;30679:12:0;;::::2;::::0;30717:6;30679:25:::2;:45::i;:::-;30740:29;::::0;;;;;;;30750:10:::2;::::0;30740:29:::2;::::0;;;;;::::2;::::0;;::::2;-1:-1:-1::0;;25029:1:0;25991:7;:22;30420:357::o;27773:39::-;;;;:::o;31345:1069::-;2440:12;:10;:12::i;:::-;2430:6;;-1:-1:-1;;;;;2430:6:0;;;:22;;;2422:67;;;;;-1:-1:-1;;;2422:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31429:1:::1;33413:16;:14;:16::i;:::-;33390:20;:39:::0;33457:26:::1;:24;:26::i;:::-;33440:14;:43:::0;-1:-1:-1;;;;;33498:21:0;::::1;::::0;33494:157:::1;;33555:15;33562:7;33555:6;:15::i;:::-;-1:-1:-1::0;;;;;33536:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;33619:20:::1;::::0;33585:22:::1;:31:::0;;;;;;:54;33494:157:::1;31467:12:::2;;31448:15;:31;31444:318;;31520:15;::::0;31509:27:::2;::::0;:6;;:10:::2;:27::i;:::-;31496:10;:40:::0;31444:318:::2;;;31589:12;::::0;31569:17:::2;::::0;31589:33:::2;::::0;31606:15:::2;31589:16;:33::i;:::-;31569:53;;31637:16;31656:25;31670:10;;31656:9;:13;;:25;;;;:::i;:::-;31734:15;::::0;31637:44;;-1:-1:-1;31709:41:0::2;::::0;:20:::2;:6:::0;31637:44;31709:10:::2;:20::i;:41::-;31696:10;:54:::0;-1:-1:-1;;31444:318:0::2;32137:12;::::0;:37:::2;::::0;;;;;32168:4:::2;32137:37;::::0;::::2;::::0;;;32122:12:::2;::::0;-1:-1:-1;;;;;32137:12:0::2;::::0;:22:::2;::::0;:37;;;;;::::2;::::0;;;;;;;;:12;:37;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;32137:37:0;32219:15:::2;::::0;32137:37;;-1:-1:-1;32207:28:0::2;::::0;32137:37;;32207:11:::2;:28::i;:::-;32193:10;;:42;;32185:79;;;::::0;;-1:-1:-1;;;32185:79:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;32294:15;32277:14;:32:::0;;;32355:15:::2;::::0;32335:36:::2;::::0;32294:15;32335:19:::2;:36::i;:::-;32320:12;:51:::0;32387:19:::2;::::0;;;;;;;::::2;::::0;;;;::::2;::::0;;::::2;33661:1;2500::::1;31345:1069:::0;:::o;30785:307::-;25073:1;25679:7;;:19;;25671:63;;;;;-1:-1:-1;;;25671:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25073:1;25812:7;:18;30839:10:::1;33413:16;:14;:16::i;:::-;33390:20;:39:::0;33457:26:::1;:24;:26::i;:::-;33440:14;:43:::0;-1:-1:-1;;;;;33498:21:0;::::1;::::0;33494:157:::1;;33555:15;33562:7;33555:6;:15::i;:::-;-1:-1:-1::0;;;;;33536:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;33619:20:::1;::::0;33585:22:::1;:31:::0;;;;;;:54;33494:157:::1;30887:10:::2;30862:14;30879:19:::0;;;:7:::2;:19;::::0;;;;;30913:10;;30909:176:::2;;30948:10;30962:1;30940:19:::0;;;:7:::2;:19;::::0;;;;:23;30978:12:::2;::::0;:45:::2;::::0;-1:-1:-1;;;;;30978:12:0;;::::2;::::0;31016:6;30978:25:::2;:45::i;:::-;31043:30;::::0;;;;;;;31054:10:::2;::::0;31043:30:::2;::::0;;;;;::::2;::::0;;::::2;30909:176;-1:-1:-1::0;;25029:1:0;25991:7;:22;30785:307::o;28492:112::-;-1:-1:-1;;;;;28578:18:0;28551:7;28578:18;;;:9;:18;;;;;;;28492:112::o;2860:148::-;2440:12;:10;:12::i;:::-;2430:6;;-1:-1:-1;;;;;2430:6:0;;;:22;;;2422:67;;;;;-1:-1:-1;;;2422:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2951:6:::1;::::0;2930:40:::1;::::0;2967:1:::1;::::0;-1:-1:-1;;;;;2951:6:0::1;::::0;2930:40:::1;::::0;2967:1;;2930:40:::1;2981:6;:19:::0;;-1:-1:-1;;2981:19:0::1;::::0;;2860:148::o;27666:26::-;;;-1:-1:-1;;;;;27666:26:0;;:::o;27737:29::-;;;;:::o;28612:131::-;28669:7;28696:39;28705:15;28722:12;;28696:8;:39::i;32529:317::-;2440:12;:10;:12::i;:::-;2430:6;;-1:-1:-1;;;;;2430:6:0;;;:22;;;2422:67;;;;;-1:-1:-1;;;2422:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25073:1:::1;25679:7;;:19;;25671:63;;;::::0;;-1:-1:-1;;;25671:63:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;25073:1;25812:7;:18:::0;32669:12:::2;::::0;-1:-1:-1;;;;;32645:37:0;;::::2;32669:12:::0;::::2;32645:37;;32637:83;;;;-1:-1:-1::0;;;32637:83:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32731:55;32765:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;32731:33:0;::::2;::::0;32774:11;32731:33:::2;:55::i;:::-;32802:36;::::0;;-1:-1:-1;;;;;32802:36:0;::::2;::::0;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;;;;;;;;::::2;-1:-1:-1::0;;25029:1:0::1;25991:7;:22:::0;32529:317::o;27899:57::-;;;;;;;;;;;;;:::o;2218:79::-;2283:6;;-1:-1:-1;;;;;2283:6:0;2218:79;:::o;30043:369::-;25073:1;25679:7;;:19;;25671:63;;;;;-1:-1:-1;;;25671:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25073:1;25812:7;:18;30109:10:::1;33413:16;:14;:16::i;:::-;33390:20;:39:::0;33457:26:::1;:24;:26::i;:::-;33440:14;:43:::0;-1:-1:-1;;;;;33498:21:0;::::1;::::0;33494:157:::1;;33555:15;33562:7;33555:6;:15::i;:::-;-1:-1:-1::0;;;;;33536:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;33619:20:::1;::::0;33585:22:::1;:31:::0;;;;;;:54;33494:157:::1;30149:1:::2;30140:6;:10;30132:37;;;::::0;;-1:-1:-1;;;30132:37:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;30195:12;::::0;:24:::2;::::0;30212:6;30195:16:::2;:24::i;:::-;30180:12;:39:::0;30264:10:::2;30254:21;::::0;;;:9:::2;:21;::::0;;;;;:33:::2;::::0;30280:6;30254:25:::2;:33::i;:::-;30240:10;30230:21;::::0;;;:9:::2;:21;::::0;;;;:57;;;;30298:12:::2;::::0;:64:::2;::::0;-1:-1:-1;;;;;30298:12:0;;::::2;::::0;30348:4:::2;30355:6:::0;30298:29:::2;:64::i;:::-;30378:26;::::0;;;;;;;30385:10:::2;::::0;30378:26:::2;::::0;;;;;::::2;::::0;;::::2;-1:-1:-1::0;;25029:1:0;25991:7;:22;30043:369::o;27819:29::-;;;;:::o;32854:433::-;2440:12;:10;:12::i;:::-;2430:6;;-1:-1:-1;;;;;2430:6:0;;;:22;;;2422:67;;;;;-1:-1:-1;;;2422:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32978:12:::1;;32960:15;:30;32938:168;;;;-1:-1:-1::0;;;32938:168:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33144:1;33125:16;:20;33117:62;;;::::0;;-1:-1:-1;;;33117:62:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;33190:15;:34:::0;;;33240:39:::1;::::0;;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;32854:433:::0;:::o;28751:330::-;28798:7;28822:12;;28838:1;28822:17;28818:77;;;-1:-1:-1;28863:20:0;;28856:27;;28818:77;28925:148;28968:90;29045:12;;28968:72;29035:4;28968:62;29019:10;;28968:46;28999:14;;28968:26;:24;:26::i;:46::-;:50;;:62::i;:90::-;28925:20;;;:24;:148::i;27633:26::-;;;-1:-1:-1;;;;;27633:26:0;;:::o;27855:35::-;;;;:::o;31100:97::-;31155:10;31145:21;;;;:9;:21;;;;;;31136:31;;:8;:31::i;:::-;31178:11;:9;:11::i;:::-;31100:97::o;27699:31::-;;;;:::o;29478:557::-;25073:1;25679:7;;:19;;25671:63;;;;;-1:-1:-1;;;25671:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25073:1;25812:7;:18;29600:10:::1;33413:16;:14;:16::i;:::-;33390:20;:39:::0;33457:26:::1;:24;:26::i;:::-;33440:14;:43:::0;-1:-1:-1;;;;;33498:21:0;::::1;::::0;33494:157:::1;;33555:15;33562:7;33555:6;:15::i;:::-;-1:-1:-1::0;;;;;33536:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;33619:20:::1;::::0;33585:22:::1;:31:::0;;;;;;:54;33494:157:::1;29640:1:::2;29631:6;:10;29623:37;;;::::0;;-1:-1:-1;;;29623:37:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;29686:12;::::0;:24:::2;::::0;29703:6;29686:16:::2;:24::i;:::-;29671:12;:39:::0;29755:10:::2;29745:21;::::0;;;:9:::2;:21;::::0;;;;;:33:::2;::::0;29771:6;29745:25:::2;:33::i;:::-;29731:10;29721:21;::::0;;;:9:::2;:21;::::0;;;;;:57;;;;29833:12:::2;::::0;29810:98;;;;;::::2;::::0;::::2;::::0;;;;29875:4:::2;29810:98:::0;;;;;;;;;;;;;;;;::::2;::::0;::::2;::::0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;29833:12:0;;::::2;::::0;29810:44:::2;::::0;:98;;;;;29721:21;29810:98;;;;;;29721:21;29833:12;29810:98;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;29921:12:0::2;::::0;:64:::2;::::0;-1:-1:-1;;;;;;29921:12:0::2;::::0;-1:-1:-1;29951:10:0::2;29971:4;29978:6:::0;29921:29:::2;:64::i;:::-;30001:26;::::0;;;;;;;30008:10:::2;::::0;30001:26:::2;::::0;;;;;::::2;::::0;;::::2;-1:-1:-1::0;;25029:1:0;25991:7;:22;-1:-1:-1;;;;29478:557:0:o;3163:244::-;2440:12;:10;:12::i;:::-;2430:6;;-1:-1:-1;;;;;2430:6:0;;;:22;;;2422:67;;;;;-1:-1:-1;;;2422:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3252:22:0;::::1;3244:73;;;;-1:-1:-1::0;;;3244:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3354:6;::::0;3333:38:::1;::::0;-1:-1:-1;;;;;3333:38:0;;::::1;::::0;3354:6:::1;::::0;3333:38:::1;::::0;3354:6:::1;::::0;3333:38:::1;3382:6;:17:::0;;-1:-1:-1;;3382:17:0::1;-1:-1:-1::0;;;;;3382:17:0;;;::::1;::::0;;;::::1;::::0;;3163:244::o;5692:136::-;5750:7;5777:43;5781:1;5784;5777:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;5770:50;5692:136;-1:-1:-1;;;5692:136:0:o;6582:471::-;6640:7;6885:6;6881:47;;-1:-1:-1;6915:1:0;6908:8;;6881:47;6952:5;;;6956:1;6952;:5;:1;6976:5;;;;;:10;6968:56;;;;-1:-1:-1;;;6968:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7529:132;7587:7;7614:39;7618:1;7621;7614:39;;;;;;;;;;;;;;;;;:3;:39::i;5228:181::-;5286:7;5318:5;;;5342:6;;;;5334:46;;;;;-1:-1:-1;;;5334:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;20234:177;20344:58;;;-1:-1:-1;;;;;20344:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20367:23;20344:58;;;20317:86;;20337:5;;20317:19;:86::i;:::-;20234:177;;;:::o;743:106::-;831:10;743:106;:::o;3860:::-;3918:7;3949:1;3945;:5;:13;;3957:1;3945:13;;;-1:-1:-1;3953:1:0;;3860:106;-1:-1:-1;3860:106:0:o;20419:205::-;20547:68;;;-1:-1:-1;;;;;20547:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20570:27;20547:68;;;20520:96;;20540:5;;20520:19;:96::i;:::-;20419:205;;;;:::o;6131:192::-;6217:7;6253:12;6245:6;;;;6237:29;;;;-1:-1:-1;;;6237:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;6289:5:0;;;6131:192::o;8157:278::-;8243:7;8278:12;8271:5;8263:28;;;;-1:-1:-1;;;8263:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8302:9;8318:1;8314;:5;;;;;;;8157:278;-1:-1:-1;;;;;8157:278:0:o;22539:761::-;22963:23;22989:69;23017:4;22989:69;;;;;;;;;;;;;;;;;22997:5;-1:-1:-1;;;;;22989:27:0;;;:69;;;;;:::i;:::-;23073:17;;22963:95;;-1:-1:-1;23073:21:0;23069:224;;23215:10;23204:30;;;;;;;;;;;;;;;-1:-1:-1;23204:30:0;23196:85;;;;-1:-1:-1;;;23196:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16219:195;16322:12;16354:52;16376:6;16384:4;16390:1;16393:12;16354:21;:52::i;:::-;16347:59;16219:195;-1:-1:-1;;;;16219:195:0:o;17271:530::-;17398:12;17456:5;17431:21;:30;;17423:81;;;;-1:-1:-1;;;17423:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17523:18;17534:6;17523:10;:18::i;:::-;17515:60;;;;;-1:-1:-1;;;17515:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;17649:12;17663:23;17690:6;-1:-1:-1;;;;;17690:11:0;17710:5;17718:4;17690:33;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17690:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17648:75;;;;17741:52;17759:7;17768:10;17780:12;17741:17;:52::i;:::-;17734:59;17271:530;-1:-1:-1;;;;;;;17271:530:0:o;13301:422::-;13668:20;13707:8;;;13301:422::o;18807:742::-;18922:12;18951:7;18947:595;;;-1:-1:-1;18982:10:0;18975:17;;18947:595;19096:17;;:21;19092:439;;19359:10;19353:17;19420:15;19407:10;19403:2;19399:19;19392:44;19307:148;19495:20;;-1:-1:-1;;;19495:20:0;;;;;;;;;;;;;;;;;19502:12;;19495:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Swarm Source
ipfs://6f44426a74f577b6d4f862ae02ec89c75f5c1bc3041e522f4a80381cfe106549