More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TokensFarm
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-09-28 */ // Sources flattened with hardhat v2.1.2 https://hardhat.org // File @openzeppelin/contracts/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/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, 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 @openzeppelin/contracts/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); } /** * @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/[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/utils/[email protected] 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/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 virtual 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/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 contracts/TokensFarm.sol pragma solidity 0.6.12; contract TokensFarm is Ownable, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; enum EarlyWithdrawPenalty { NO_PENALTY, BURN_REWARDS, REDISTRIBUTE_REWARDS } // Info of each user. struct StakeInfo { uint256 amount; // How many tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. uint256 depositTime; // Time when user deposited. } IERC20 public tokenStaked; // Address of ERC20 token contract. uint256 public lastRewardTime; // Last time number that ERC20s distribution occurs. uint256 public accERC20PerShare; // Accumulated ERC20s per share, times 1e18. uint256 public totalDeposits; // Total tokens deposited in the farm. // If contractor allows early withdraw on stakes bool public isEarlyWithdrawAllowed; // Minimal period of time to stake uint256 public minTimeToStake; // Address of the ERC20 Token contract. IERC20 public erc20; // The total amount of ERC20 that's paid out as reward. uint256 public paidOut; // ERC20 tokens rewarded per second. uint256 public rewardPerSecond; // Total rewards added to farm uint256 public totalRewards; // Info of each user that stakes ERC20 tokens. mapping(address => StakeInfo[]) public stakeInfo; // The time when farming starts. uint256 public startTime; // The time when farming ends. uint256 public endTime; // Early withdraw penalty EarlyWithdrawPenalty public penalty; // Counter for funding uint256 fundCounter; // Congress address address public congressAddress; // Stake fee percent uint256 public stakeFeePercent; // Reward fee percent uint256 public rewardFeePercent; // Fee collector address address payable public feeCollector; // Flat fee amount uint256 public flatFeeAmount; // Fee option bool public isFlatFeeAllowed; // Events event Deposit(address indexed user, uint256 stakeId, uint256 amount); event Withdraw(address indexed user, uint256 stakeId, uint256 amount); event EmergencyWithdraw( address indexed user, uint256 stakeId, uint256 amount ); event EarlyWithdrawPenaltyChange(EarlyWithdrawPenalty penalty); modifier validateStakeByStakeId(address _user, uint256 stakeId) { require(stakeId < stakeInfo[_user].length, "Stake does not exist"); _; } constructor( IERC20 _erc20, uint256 _rewardPerSecond, uint256 _startTime, uint256 _minTimeToStake, bool _isEarlyWithdrawAllowed, EarlyWithdrawPenalty _penalty, IERC20 _tokenStaked, address _congressAddress, uint256 _stakeFeePercent, uint256 _rewardFeePercent, uint256 _flatFeeAmount, address payable _feeCollector, bool _isFlatFeeAllowed ) public { require(address(_erc20) != address(0x0), "Wrong token address."); require(_rewardPerSecond > 0, "Rewards per second must be > 0."); require( _startTime >= block.timestamp, "Start timne can not be in the past." ); require(_stakeFeePercent < 100, "Stake fee must be < 100."); require(_rewardFeePercent < 100, "Reward fee must be < 100."); require(_feeCollector != address(0x0), "Wrong fee collector address."); require( _congressAddress != address(0x0), "Congress address can not be 0." ); erc20 = _erc20; rewardPerSecond = _rewardPerSecond; startTime = _startTime; endTime = _startTime; minTimeToStake = _minTimeToStake; isEarlyWithdrawAllowed = _isEarlyWithdrawAllowed; congressAddress = _congressAddress; stakeFeePercent = _stakeFeePercent; rewardFeePercent = _rewardFeePercent; flatFeeAmount = _flatFeeAmount; feeCollector = _feeCollector; isFlatFeeAllowed = _isFlatFeeAllowed; _setEarlyWithdrawPenalty(_penalty); _addPool(_tokenStaked); } // Set minimun time to stake function setMinTimeToStake(uint256 _minTimeToStake) external onlyOwner { minTimeToStake = _minTimeToStake; } // Set fee collector address function setFeeCollector(address payable _feeCollector) external onlyOwner { require(_feeCollector != address(0x0), "Wrong fee collector address."); feeCollector = _feeCollector; } // Set early withdrawal penalty, if applicable function _setEarlyWithdrawPenalty(EarlyWithdrawPenalty _penalty) internal { penalty = _penalty; emit EarlyWithdrawPenaltyChange(penalty); } // Fund the farm, increase the end time function fund(uint256 _amount) external { fundCounter = fundCounter.add(1); _fundInternal(_amount); erc20.safeTransferFrom(address(msg.sender), address(this), _amount); if (fundCounter == 2) { transferOwnership(congressAddress); } } // Internally fund the farm by adding farmed rewards by user to the end function _fundInternal(uint256 _amount) internal { require( block.timestamp < endTime, "fund: too late, the farm is closed" ); require(_amount > 0, "Amount must be greater than 0."); // Compute new end time endTime += _amount.div(rewardPerSecond); // Increase farm total rewards totalRewards = totalRewards.add(_amount); } // Add a new ERC20 token to the pool. Can only be called by the owner. function _addPool(IERC20 _tokenStaked) internal { require( address(_tokenStaked) != address(0x0), "Must input valid address." ); require( address(tokenStaked) == address(0x0), "Pool can be set only once." ); uint256 _lastRewardTime = block.timestamp > startTime ? block.timestamp : startTime; tokenStaked = _tokenStaked; lastRewardTime = _lastRewardTime; accERC20PerShare = 0; totalDeposits = 0; } // View function to see deposited ERC20 token for a user. function deposited(address _user, uint256 stakeId) public view validateStakeByStakeId(_user, stakeId) returns (uint256) { StakeInfo storage stake = stakeInfo[_user][stakeId]; return stake.amount; } // View function to see pending ERC20s for a user. function pending(address _user, uint256 stakeId) public view validateStakeByStakeId(_user, stakeId) returns (uint256) { StakeInfo storage stake = stakeInfo[_user][stakeId]; if (stake.amount == 0) { return 0; } uint256 _accERC20PerShare = accERC20PerShare; uint256 tokenSupply = totalDeposits; if (block.timestamp > lastRewardTime && tokenSupply != 0) { uint256 lastTime = block.timestamp < endTime ? block.timestamp : endTime; uint256 timeToCompare = lastRewardTime < endTime ? lastRewardTime : endTime; uint256 nrOfSeconds = lastTime.sub(timeToCompare); uint256 erc20Reward = nrOfSeconds.mul(rewardPerSecond); _accERC20PerShare = _accERC20PerShare.add( erc20Reward.mul(1e18).div(tokenSupply) ); } return stake.amount.mul(_accERC20PerShare).div(1e18).sub(stake.rewardDebt); } // View function to see deposit timestamp for a user. function depositTimestamp(address _user, uint256 stakeId) public view validateStakeByStakeId(_user, stakeId) returns (uint256) { StakeInfo storage stake = stakeInfo[_user][stakeId]; return stake.depositTime; } // View function for total reward the farm has yet to pay out. function totalPending() external view returns (uint256) { if (block.timestamp <= startTime) { return 0; } uint256 lastTime = block.timestamp < endTime ? block.timestamp : endTime; return rewardPerSecond.mul(lastTime - startTime).sub(paidOut); } // Update reward variables of the given pool to be up-to-date. function updatePool() public { uint256 lastTime = block.timestamp < endTime ? block.timestamp : endTime; if (lastTime <= lastRewardTime) { return; } uint256 tokenSupply = totalDeposits; if (tokenSupply == 0) { lastRewardTime = lastTime; return; } uint256 nrOfSeconds = lastTime.sub(lastRewardTime); uint256 erc20Reward = nrOfSeconds.mul(rewardPerSecond); accERC20PerShare = accERC20PerShare.add( erc20Reward.mul(1e18).div(tokenSupply) ); lastRewardTime = block.timestamp; } // Deposit ERC20 tokens to Farm for ERC20 allocation. function deposit(uint256 _amount) external payable { StakeInfo memory stake; // Update pool updatePool(); // Take token and transfer to contract tokenStaked.safeTransferFrom( address(msg.sender), address(this), _amount ); uint256 stakedAmount = _amount; if (isFlatFeeAllowed) { // Collect flat fee require( msg.value >= flatFeeAmount, "Payable amount is less than fee amount." ); (bool sent, ) = payable(feeCollector).call{value: msg.value}(""); require(sent, "Failed to send flat fee"); } else if (stakeFeePercent > 0) { // Handle this case only if flat fee is not allowed, and stakeFeePercent > 0 // Compute the fee uint256 feeAmount = _amount.mul(stakeFeePercent).div(100); // Compute stake amount stakedAmount = _amount.sub(feeAmount); // Transfer fee to Fee Collector tokenStaked.safeTransfer(feeCollector, feeAmount); } // Increase total deposits totalDeposits = totalDeposits.add(stakedAmount); // Update user accounting stake.amount = stakedAmount; stake.rewardDebt = stake.amount.mul(accERC20PerShare).div(1e18); stake.depositTime = block.timestamp; // Compute stake id uint256 stakeId = stakeInfo[msg.sender].length; // Push new stake to array of stakes for user stakeInfo[msg.sender].push(stake); // Emit deposit event emit Deposit(msg.sender, stakeId, stakedAmount); } // Withdraw ERC20 tokens from Farm. function withdraw(uint256 _amount, uint256 stakeId) external payable nonReentrant validateStakeByStakeId(msg.sender, stakeId) { bool minimalTimeStakeRespected; StakeInfo storage stake = stakeInfo[msg.sender][stakeId]; require( stake.amount >= _amount, "withdraw: can't withdraw more than deposit" ); updatePool(); minimalTimeStakeRespected = stake.depositTime.add(minTimeToStake) <= block.timestamp; // if early withdraw is not allowed, user can't withdraw funds before if (!isEarlyWithdrawAllowed) { // Check if user has respected minimal time to stake, require it. require( minimalTimeStakeRespected, "User can not withdraw funds yet." ); } // Compute pending rewards amount of user rewards uint256 pendingAmount = stake .amount .mul(accERC20PerShare) .div(1e18) .sub(stake.rewardDebt); // Penalties in case user didn't stake enough time if (pendingAmount > 0) { if ( penalty == EarlyWithdrawPenalty.BURN_REWARDS && !minimalTimeStakeRespected ) { // Burn to address (1) _erc20Transfer(address(1), pendingAmount); } else if ( penalty == EarlyWithdrawPenalty.REDISTRIBUTE_REWARDS && !minimalTimeStakeRespected ) { if (block.timestamp >= endTime) { // Burn rewards because farm can not be funded anymore since it ended _erc20Transfer(address(1), pendingAmount); } else { // Re-fund the farm _fundInternal(pendingAmount); } } else { // In case either there's no penalty _erc20Transfer(msg.sender, pendingAmount); } } stake.amount = stake.amount.sub(_amount); stake.rewardDebt = stake.amount.mul(accERC20PerShare).div(1e18); tokenStaked.safeTransfer(address(msg.sender), _amount); totalDeposits = totalDeposits.sub(_amount); // Emit Withdraw event emit Withdraw(msg.sender, stakeId, _amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 stakeId) external nonReentrant validateStakeByStakeId(msg.sender, stakeId) { StakeInfo storage stake = stakeInfo[msg.sender][stakeId]; // if early withdraw is not allowed, user can't withdraw funds before if (!isEarlyWithdrawAllowed) { bool minimalTimeStakeRespected = stake.depositTime.add( minTimeToStake ) <= block.timestamp; // Check if user has respected minimal time to stake, require it. require( minimalTimeStakeRespected, "User can not withdraw funds yet." ); } tokenStaked.safeTransfer(address(msg.sender), stake.amount); totalDeposits = totalDeposits.sub(stake.amount); emit EmergencyWithdraw(msg.sender, stakeId, stake.amount); stake.amount = 0; stake.rewardDebt = 0; } // Get number of stakes user has function getNumberOfUserStakes(address user) external view returns (uint256) { return stakeInfo[user].length; } // Get user pending amounts, stakes and deposit time function getUserStakesAndPendingAmounts(address user) external view returns ( uint256[] memory, uint256[] memory, uint256[] memory ) { uint256 numberOfStakes = stakeInfo[user].length; uint256[] memory deposits = new uint256[](numberOfStakes); uint256[] memory pendingAmounts = new uint256[](numberOfStakes); uint256[] memory depositTime = new uint256[](numberOfStakes); for (uint256 i = 0; i < numberOfStakes; i++) { deposits[i] = deposited(user, i); pendingAmounts[i] = pending(user, i); depositTime[i] = depositTimestamp(user, i); } return (deposits, pendingAmounts, depositTime); } // Get total rewards locked/unlocked function getTotalRewardsLockedUnlocked() external view returns (uint256, uint256) { uint256 totalRewardsLocked; uint256 totalRewardsUnlocked; if (block.timestamp <= startTime) { totalRewardsUnlocked = 0; totalRewardsLocked = totalRewards; } else { uint256 lastTime = block.timestamp < endTime ? block.timestamp : endTime; totalRewardsUnlocked = rewardPerSecond.mul(lastTime - startTime); totalRewardsLocked = totalRewards - totalRewardsUnlocked; } return (totalRewardsUnlocked, totalRewardsLocked); } // Transfer ERC20 and update the required ERC20 to payout all rewards function _erc20Transfer(address _to, uint256 _amount) internal { if (isFlatFeeAllowed) { // Collect flat fee require( msg.value >= flatFeeAmount, "Payable amount is less than fee amount." ); (bool sent, ) = payable(feeCollector).call{value: msg.value}(""); require(sent, "Failed to end flat fee"); // send reward erc20.transfer(_to, _amount); paidOut += _amount; } else if (stakeFeePercent > 0) { // Collect reward fee uint256 feeAmount = _amount.mul(rewardFeePercent).div(100); uint256 rewardAmount = _amount.sub(feeAmount); erc20.transfer(feeCollector, feeAmount); // send reward erc20.transfer(_to, rewardAmount); paidOut += _amount; } else { erc20.transfer(_to, _amount); paidOut += _amount; } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"_erc20","type":"address"},{"internalType":"uint256","name":"_rewardPerSecond","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_minTimeToStake","type":"uint256"},{"internalType":"bool","name":"_isEarlyWithdrawAllowed","type":"bool"},{"internalType":"enum TokensFarm.EarlyWithdrawPenalty","name":"_penalty","type":"uint8"},{"internalType":"contract IERC20","name":"_tokenStaked","type":"address"},{"internalType":"address","name":"_congressAddress","type":"address"},{"internalType":"uint256","name":"_stakeFeePercent","type":"uint256"},{"internalType":"uint256","name":"_rewardFeePercent","type":"uint256"},{"internalType":"uint256","name":"_flatFeeAmount","type":"uint256"},{"internalType":"address payable","name":"_feeCollector","type":"address"},{"internalType":"bool","name":"_isFlatFeeAllowed","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum TokensFarm.EarlyWithdrawPenalty","name":"penalty","type":"uint8"}],"name":"EarlyWithdrawPenaltyChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"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":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"accERC20PerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"congressAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"depositTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"deposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flatFeeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"fund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNumberOfUserStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRewardsLockedUnlocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserStakesAndPendingAmounts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isEarlyWithdrawAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFlatFeeAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRewardTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTimeToStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paidOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"penalty","outputs":[{"internalType":"enum TokensFarm.EarlyWithdrawPenalty","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"pending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_feeCollector","type":"address"}],"name":"setFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minTimeToStake","type":"uint256"}],"name":"setMinTimeToStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakeInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"},{"internalType":"uint256","name":"depositTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenStaked","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewards","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":[],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003fdd38038062003fdd83398181016040526101a08110156200003857600080fd5b81019080805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050506000620000d36200068160201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35060018081905550600073ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff1614156200021c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f57726f6e6720746f6b656e20616464726573732e00000000000000000000000081525060200191505060405180910390fd5b60008c1162000293576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265776172647320706572207365636f6e64206d757374206265203e20302e0081525060200191505060405180910390fd5b428b1015620002ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018062003fba6023913960400191505060405180910390fd5b6064851062000365576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f5374616b6520666565206d757374206265203c203130302e000000000000000081525060200191505060405180910390fd5b60648410620003dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f52657761726420666565206d757374206265203c203130302e0000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f57726f6e672066656520636f6c6c6563746f7220616464726573732e0000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16141562000524576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f436f6e677265737320616464726573732063616e206e6f7420626520302e000081525060200191505060405180910390fd5b8c600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600a819055508a600d819055508a600e819055508960078190555088600660006101000a81548160ff02191690831515021790555085601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084601281905550836013819055508260158190555081601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080601660006101000a81548160ff0219169083151502179055506200065d886200068960201b60201c565b6200066e876200070260201b60201c565b50505050505050505050505050620008e0565b600033905090565b80600f60006101000a81548160ff02191690836002811115620006a857fe5b02179055507fa592e2c7247cb0aeb63e74859fdb4185ba9bf65f3a6a9e577fe909f8b146a3c3600f60009054906101000a900460ff1660405180826002811115620006ef57fe5b815260200191505060405180910390a150565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620007a6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4d75737420696e7075742076616c696420616464726573732e0000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146200086b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f506f6f6c2063616e20626520736574206f6e6c79206f6e63652e00000000000081525060200191505060405180910390fd5b6000600d5442116200088057600d5462000882565b425b905081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600381905550600060048190555060006005819055505050565b6136ca80620008f06000396000f3fe60806040526004361061021a5760003560e01c8063715018a611610123578063a42dce80116100ab578063ca1d209d1161006f578063ca1d209d14610a64578063e3161ddd14610a9f578063e86e8c6d14610ab6578063f2fde38b14610b25578063ff0c44da14610b765761021a565b8063a42dce801461094c578063b6b55f251461099d578063ba78b2e4146109cb578063bfa98f75146109f8578063c415b95c14610a235761021a565b8063899b8e13116100f2578063899b8e131461071a5780638da5cb5b146108505780638f10369a146108915780639231cf74146108bc578063a3705585146108e75761021a565b8063715018a61461066c578063785e9e861461068357806378e97925146106c45780637d882097146106ef5761021a565b806341b99342116101a65780635312ea8e116101755780635312ea8e146105415780635a4616981461057c5780635c76ca2d146105a7578063638f95f6146105d2578063688e89c1146105fd5761021a565b806341b9934214610460578063441a3e701461048d578063518f49d8146104c5578063524c4f1f146105065761021a565b80631c43bd7d116101ed5780631c43bd7d14610321578063264e2d1f1461039e5780633197cbb6146103df57806339d43ce01461040a5780633f90916a146104355761021a565b806304601cb91461021f5780630e15561a146102515780630edd2ffc1461027c57806315167c03146102b2575b600080fd5b34801561022b57600080fd5b50610234610ba1565b604051808381526020018281526020019250505060405180910390f35b34801561025d57600080fd5b50610266610c05565b6040518082815260200191505060405180910390f35b34801561028857600080fd5b50610291610c0b565b604051808260028111156102a157fe5b815260200191505060405180910390f35b3480156102be57600080fd5b5061030b600480360360408110156102d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1e565b6040518082815260200191505060405180910390f35b34801561032d57600080fd5b5061037a6004803603604081101561034457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e6e565b60405180848152602001838152602001828152602001935050505060405180910390f35b3480156103aa57600080fd5b506103b3610eb2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103eb57600080fd5b506103f4610ed8565b6040518082815260200191505060405180910390f35b34801561041657600080fd5b5061041f610ede565b6040518082815260200191505060405180910390f35b34801561044157600080fd5b5061044a610ee4565b6040518082815260200191505060405180910390f35b34801561046c57600080fd5b50610475610f43565b60405180821515815260200191505060405180910390f35b6104c3600480360360408110156104a357600080fd5b810190808035906020019092919080359060200190929190505050610f56565b005b3480156104d157600080fd5b506104da61142a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561051257600080fd5b5061053f6004803603602081101561052957600080fd5b8101908080359060200190929190505050611450565b005b34801561054d57600080fd5b5061057a6004803603602081101561056457600080fd5b8101908080359060200190929190505050611509565b005b34801561058857600080fd5b50610591611833565b6040518082815260200191505060405180910390f35b3480156105b357600080fd5b506105bc611839565b6040518082815260200191505060405180910390f35b3480156105de57600080fd5b506105e761183f565b6040518082815260200191505060405180910390f35b34801561060957600080fd5b506106566004803603604081101561062057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611845565b6040518082815260200191505060405180910390f35b34801561067857600080fd5b5061068161196c565b005b34801561068f57600080fd5b50610698611ad9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156106d057600080fd5b506106d9611aff565b6040518082815260200191505060405180910390f35b3480156106fb57600080fd5b50610704611b05565b6040518082815260200191505060405180910390f35b34801561072657600080fd5b506107696004803603602081101561073d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b0b565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156107b4578082015181840152602081019050610799565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156107f65780820151818401526020810190506107db565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561083857808201518184015260208101905061081d565b50505050905001965050505050505060405180910390f35b34801561085c57600080fd5b50610865611ccb565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561089d57600080fd5b506108a6611cf4565b6040518082815260200191505060405180910390f35b3480156108c857600080fd5b506108d1611cfa565b6040518082815260200191505060405180910390f35b3480156108f357600080fd5b506109366004803603602081101561090a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d00565b6040518082815260200191505060405180910390f35b34801561095857600080fd5b5061099b6004803603602081101561096f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d4c565b005b6109c9600480360360208110156109b357600080fd5b8101908080359060200190929190505050611ee2565b005b3480156109d757600080fd5b506109e061230f565b60405180821515815260200191505060405180910390f35b348015610a0457600080fd5b50610a0d612322565b6040518082815260200191505060405180910390f35b348015610a2f57600080fd5b50610a38612328565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a7057600080fd5b50610a9d60048036036020811015610a8757600080fd5b810190808035906020019092919050505061234e565b005b348015610aab57600080fd5b50610ab46123fc565b005b348015610ac257600080fd5b50610b0f60048036036040811015610ad957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506124c7565b6040518082815260200191505060405180910390f35b348015610b3157600080fd5b50610b7460048036036020811015610b4857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125ee565b005b348015610b8257600080fd5b50610b8b6127e0565b6040518082815260200191505060405180910390f35b600080600080600d544211610bbe5760009050600b549150610bf9565b6000600e544210610bd157600e54610bd3565b425b9050610bee600d548203600a546127e690919063ffffffff16565b915081600b54039250505b80829350935050509091565b600b5481565b600f60009054906101000a900460ff1681565b60008282600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110610cd9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208581548110610d2557fe5b90600052602060002090600302019050600081600001541415610d4c576000935050610e66565b600060045490506000600554905060035442118015610d6c575060008114155b15610e19576000600e544210610d8457600e54610d86565b425b90506000600e5460035410610d9d57600e54610da1565b6003545b90506000610db8828461286c90919063ffffffff16565b90506000610dd1600a54836127e690919063ffffffff16565b9050610e12610e0386610df5670de0b6b3a7640000856127e690919063ffffffff16565b6128ef90919063ffffffff16565b8761297890919063ffffffff16565b9550505050505b610e608360010154610e52670de0b6b3a7640000610e448688600001546127e690919063ffffffff16565b6128ef90919063ffffffff16565b61286c90919063ffffffff16565b95505050505b505092915050565b600c6020528160005260406000208181548110610e8757fe5b9060005260206000209060030201600091509150508060000154908060010154908060020154905083565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e5481565b60045481565b6000600d544211610ef85760009050610f40565b6000600e544210610f0b57600e54610f0d565b425b9050610f3c600954610f2e600d548403600a546127e690919063ffffffff16565b61286c90919063ffffffff16565b9150505b90565b601660009054906101000a900460ff1681565b60026001541415610fcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026001819055503381600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110611090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b600080600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002085815481106110dd57fe5b90600052602060002090600302019050858160000154101561114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613641602a913960400191505060405180910390fd5b6111526123fc565b4261116c600754836002015461297890919063ffffffff16565b11159150600660009054906101000a900460ff166111f857816111f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f557365722063616e206e6f742077697468647261772066756e6473207965742e81525060200191505060405180910390fd5b5b60006112438260010154611235670de0b6b3a764000061122760045487600001546127e690919063ffffffff16565b6128ef90919063ffffffff16565b61286c90919063ffffffff16565b90506000811115611302576001600281111561125b57fe5b600f60009054906101000a900460ff16600281111561127657fe5b148015611281575082155b1561129657611291600182612a00565b611301565b6002808111156112a257fe5b600f60009054906101000a900460ff1660028111156112bd57fe5b1480156112c8575082155b156112f557600e5442106112e6576112e1600182612a00565b6112f0565b6112ef81612f5d565b5b611300565b6112ff3382612a00565b5b5b5b61131987836000015461286c90919063ffffffff16565b8260000181905550611354670de0b6b3a764000061134660045485600001546127e690919063ffffffff16565b6128ef90919063ffffffff16565b82600101819055506113a93388600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661306f9092919063ffffffff16565b6113be8760055461286c90919063ffffffff16565b6005819055503373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5688789604051808381526020018281526020019250505060405180910390a25050505050600180819055505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611458613111565b73ffffffffffffffffffffffffffffffffffffffff16611476611ccb565b73ffffffffffffffffffffffffffffffffffffffff16146114ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060078190555050565b60026001541415611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026001819055503381600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110611643576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020848154811061168f57fe5b90600052602060002090600302019050600660009054906101000a900460ff16611748576000426116cf600754846002015461297890919063ffffffff16565b1115905080611746576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f557365722063616e206e6f742077697468647261772066756e6473207965742e81525060200191505060405180910390fd5b505b611799338260000154600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661306f9092919063ffffffff16565b6117b2816000015460055461286c90919063ffffffff16565b6005819055503373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595858360000154604051808381526020018281526020019250505060405180910390a260008160000181905550600081600101819055505050506001808190555050565b60135481565b60095481565b60125481565b60008282600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110611900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020858154811061194c57fe5b906000526020600020906003020190508060000154935050505092915050565b611974613111565b73ffffffffffffffffffffffffffffffffffffffff16611992611ccb565b73ffffffffffffffffffffffffffffffffffffffff1614611a1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d5481565b60055481565b60608060606000600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060608167ffffffffffffffff81118015611b7057600080fd5b50604051908082528060200260200182016040528015611b9f5781602001602082028036833780820191505090505b50905060608267ffffffffffffffff81118015611bbb57600080fd5b50604051908082528060200260200182016040528015611bea5781602001602082028036833780820191505090505b50905060608367ffffffffffffffff81118015611c0657600080fd5b50604051908082528060200260200182016040528015611c355781602001602082028036833780820191505090505b50905060005b84811015611cb657611c4d8982611845565b848281518110611c5957fe5b602002602001018181525050611c6f8982610c1e565b838281518110611c7b57fe5b602002602001018181525050611c9189826124c7565b828281518110611c9d57fe5b6020026020010181815250508080600101915050611c3b565b50828282965096509650505050509193909250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a5481565b60035481565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b611d54613111565b73ffffffffffffffffffffffffffffffffffffffff16611d72611ccb565b73ffffffffffffffffffffffffffffffffffffffff1614611dfb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611e9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f57726f6e672066656520636f6c6c6563746f7220616464726573732e0000000081525060200191505060405180910390fd5b80601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611eea613569565b611ef26123fc565b611f41333084600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613119909392919063ffffffff16565b6000829050601660009054906101000a900460ff16156120ba57601554341015611fb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806135d76027913960400191505060405180910390fd5b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163460405180600001905060006040518083038185875af1925050503d8060008114612038576040519150601f19603f3d011682016040523d82523d6000602084013e61203d565b606091505b50509050806120b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f4661696c656420746f2073656e6420666c61742066656500000000000000000081525060200191505060405180910390fd5b50612178565b600060125411156121775760006120ef60646120e1601254876127e690919063ffffffff16565b6128ef90919063ffffffff16565b9050612104818561286c90919063ffffffff16565b9150612175601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661306f9092919063ffffffff16565b505b5b61218d8160055461297890919063ffffffff16565b600581905550808260000181815250506121d0670de0b6b3a76400006121c260045485600001516127e690919063ffffffff16565b6128ef90919063ffffffff16565b826020018181525050428260400181815250506000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002015550503373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a158284604051808381526020018281526020019250505060405180910390a250505050565b600660009054906101000a900460ff1681565b60075481565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b612364600160105461297890919063ffffffff16565b60108190555061237381612f5d565b6123c2333083600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613119909392919063ffffffff16565b600260105414156123f9576123f8601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166125ee565b5b50565b6000600e54421061240f57600e54612411565b425b9050600354811161242257506124c5565b600060055490506000811415612440578160038190555050506124c5565b60006124576003548461286c90919063ffffffff16565b90506000612470600a54836127e690919063ffffffff16565b90506124b36124a284612494670de0b6b3a7640000856127e690919063ffffffff16565b6128ef90919063ffffffff16565b60045461297890919063ffffffff16565b60048190555042600381905550505050505b565b60008282600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110612582576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002085815481106125ce57fe5b906000526020600020906003020190508060020154935050505092915050565b6125f6613111565b73ffffffffffffffffffffffffffffffffffffffff16612614611ccb565b73ffffffffffffffffffffffffffffffffffffffff161461269d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061358b6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60155481565b6000808314156127f95760009050612866565b600082840290508284828161280a57fe5b0414612861576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806135fe6021913960400191505060405180910390fd5b809150505b92915050565b6000828211156128e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6000808211612966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b81838161296f57fe5b04905092915050565b6000808284019050838110156129f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b601660009054906101000a900460ff1615612c5357601554341015612a70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806135d76027913960400191505060405180910390fd5b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163460405180600001905060006040518083038185875af1925050503d8060008114612af2576040519150601f19603f3d011682016040523d82523d6000602084013e612af7565b606091505b5050905080612b6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4661696c656420746f20656e6420666c6174206665650000000000000000000081525060200191505060405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612c0157600080fd5b505af1158015612c15573d6000803e3d6000fd5b505050506040513d6020811015612c2b57600080fd5b8101908080519060200190929190505050508160096000828254019250508190555050612f59565b60006012541115612e78576000612c886064612c7a601354856127e690919063ffffffff16565b6128ef90919063ffffffff16565b90506000612c9f828461286c90919063ffffffff16565b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612d5657600080fd5b505af1158015612d6a573d6000803e3d6000fd5b505050506040513d6020811015612d8057600080fd5b810190808051906020019092919050505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612e2557600080fd5b505af1158015612e39573d6000803e3d6000fd5b505050506040513d6020811015612e4f57600080fd5b810190808051906020019092919050505050826009600082825401925050819055505050612f58565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612f0b57600080fd5b505af1158015612f1f573d6000803e3d6000fd5b505050506040513d6020811015612f3557600080fd5b810190808051906020019092919050505050806009600082825401925050819055505b5b5050565b600e544210612fb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061361f6022913960400191505060405180910390fd5b6000811161302d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f416d6f756e74206d7573742062652067726561746572207468616e20302e000081525060200191505060405180910390fd5b613042600a54826128ef90919063ffffffff16565b600e6000828254019250508190555061306681600b5461297890919063ffffffff16565b600b8190555050565b61310c8363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506131da565b505050565b600033905090565b6131d4846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506131da565b50505050565b606061323c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132c99092919063ffffffff16565b90506000815111156132c45780806020019051602081101561325d57600080fd5b81019080805190602001909291905050506132c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061366b602a913960400191505060405180910390fd5b5b505050565b60606132d884846000856132e1565b90509392505050565b60608247101561333c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806135b16026913960400191505060405180910390fd5b6133458561348a565b6133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061340757805182526020820191506020810190506020830392506133e4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613469576040519150601f19603f3d011682016040523d82523d6000602084013e61346e565b606091505b509150915061347e82828661349d565b92505050949350505050565b600080823b905060008111915050919050565b606083156134ad57829050613562565b6000835111156134c05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561352757808201518184015260208101905061350c565b50505050905090810190601f1680156135545780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b6040518060600160405280600081526020016000815260200160008152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c50617961626c6520616d6f756e74206973206c657373207468616e2066656520616d6f756e742e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7766756e643a20746f6f206c6174652c20746865206661726d20697320636c6f73656477697468647261773a2063616e2774207769746864726177206d6f7265207468616e206465706f7369745361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122030e6ff7dd276afdc9adeeec2906273dcc8bedf59824a8ac48c74a72d1500ccbe64736f6c634300060c003353746172742074696d6e652063616e206e6f7420626520696e2074686520706173742e00000000000000000000000080d55c03180349fff4a229102f62328220a964440000000000000000000000000000000000000000000000000403fbf9e8bb284b000000000000000000000000000000000000000000000000000000006152fcb800000000000000000000000000000000000000000000000000000000000d2f0000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000b6b4c7ac240b1f176c5589d064733066a83884a10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002ad0606097905292f92daa48bcaf5b9e1c555bc40000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361061021a5760003560e01c8063715018a611610123578063a42dce80116100ab578063ca1d209d1161006f578063ca1d209d14610a64578063e3161ddd14610a9f578063e86e8c6d14610ab6578063f2fde38b14610b25578063ff0c44da14610b765761021a565b8063a42dce801461094c578063b6b55f251461099d578063ba78b2e4146109cb578063bfa98f75146109f8578063c415b95c14610a235761021a565b8063899b8e13116100f2578063899b8e131461071a5780638da5cb5b146108505780638f10369a146108915780639231cf74146108bc578063a3705585146108e75761021a565b8063715018a61461066c578063785e9e861461068357806378e97925146106c45780637d882097146106ef5761021a565b806341b99342116101a65780635312ea8e116101755780635312ea8e146105415780635a4616981461057c5780635c76ca2d146105a7578063638f95f6146105d2578063688e89c1146105fd5761021a565b806341b9934214610460578063441a3e701461048d578063518f49d8146104c5578063524c4f1f146105065761021a565b80631c43bd7d116101ed5780631c43bd7d14610321578063264e2d1f1461039e5780633197cbb6146103df57806339d43ce01461040a5780633f90916a146104355761021a565b806304601cb91461021f5780630e15561a146102515780630edd2ffc1461027c57806315167c03146102b2575b600080fd5b34801561022b57600080fd5b50610234610ba1565b604051808381526020018281526020019250505060405180910390f35b34801561025d57600080fd5b50610266610c05565b6040518082815260200191505060405180910390f35b34801561028857600080fd5b50610291610c0b565b604051808260028111156102a157fe5b815260200191505060405180910390f35b3480156102be57600080fd5b5061030b600480360360408110156102d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1e565b6040518082815260200191505060405180910390f35b34801561032d57600080fd5b5061037a6004803603604081101561034457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e6e565b60405180848152602001838152602001828152602001935050505060405180910390f35b3480156103aa57600080fd5b506103b3610eb2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103eb57600080fd5b506103f4610ed8565b6040518082815260200191505060405180910390f35b34801561041657600080fd5b5061041f610ede565b6040518082815260200191505060405180910390f35b34801561044157600080fd5b5061044a610ee4565b6040518082815260200191505060405180910390f35b34801561046c57600080fd5b50610475610f43565b60405180821515815260200191505060405180910390f35b6104c3600480360360408110156104a357600080fd5b810190808035906020019092919080359060200190929190505050610f56565b005b3480156104d157600080fd5b506104da61142a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561051257600080fd5b5061053f6004803603602081101561052957600080fd5b8101908080359060200190929190505050611450565b005b34801561054d57600080fd5b5061057a6004803603602081101561056457600080fd5b8101908080359060200190929190505050611509565b005b34801561058857600080fd5b50610591611833565b6040518082815260200191505060405180910390f35b3480156105b357600080fd5b506105bc611839565b6040518082815260200191505060405180910390f35b3480156105de57600080fd5b506105e761183f565b6040518082815260200191505060405180910390f35b34801561060957600080fd5b506106566004803603604081101561062057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611845565b6040518082815260200191505060405180910390f35b34801561067857600080fd5b5061068161196c565b005b34801561068f57600080fd5b50610698611ad9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156106d057600080fd5b506106d9611aff565b6040518082815260200191505060405180910390f35b3480156106fb57600080fd5b50610704611b05565b6040518082815260200191505060405180910390f35b34801561072657600080fd5b506107696004803603602081101561073d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b0b565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156107b4578082015181840152602081019050610799565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156107f65780820151818401526020810190506107db565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561083857808201518184015260208101905061081d565b50505050905001965050505050505060405180910390f35b34801561085c57600080fd5b50610865611ccb565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561089d57600080fd5b506108a6611cf4565b6040518082815260200191505060405180910390f35b3480156108c857600080fd5b506108d1611cfa565b6040518082815260200191505060405180910390f35b3480156108f357600080fd5b506109366004803603602081101561090a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d00565b6040518082815260200191505060405180910390f35b34801561095857600080fd5b5061099b6004803603602081101561096f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d4c565b005b6109c9600480360360208110156109b357600080fd5b8101908080359060200190929190505050611ee2565b005b3480156109d757600080fd5b506109e061230f565b60405180821515815260200191505060405180910390f35b348015610a0457600080fd5b50610a0d612322565b6040518082815260200191505060405180910390f35b348015610a2f57600080fd5b50610a38612328565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a7057600080fd5b50610a9d60048036036020811015610a8757600080fd5b810190808035906020019092919050505061234e565b005b348015610aab57600080fd5b50610ab46123fc565b005b348015610ac257600080fd5b50610b0f60048036036040811015610ad957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506124c7565b6040518082815260200191505060405180910390f35b348015610b3157600080fd5b50610b7460048036036020811015610b4857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125ee565b005b348015610b8257600080fd5b50610b8b6127e0565b6040518082815260200191505060405180910390f35b600080600080600d544211610bbe5760009050600b549150610bf9565b6000600e544210610bd157600e54610bd3565b425b9050610bee600d548203600a546127e690919063ffffffff16565b915081600b54039250505b80829350935050509091565b600b5481565b600f60009054906101000a900460ff1681565b60008282600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110610cd9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208581548110610d2557fe5b90600052602060002090600302019050600081600001541415610d4c576000935050610e66565b600060045490506000600554905060035442118015610d6c575060008114155b15610e19576000600e544210610d8457600e54610d86565b425b90506000600e5460035410610d9d57600e54610da1565b6003545b90506000610db8828461286c90919063ffffffff16565b90506000610dd1600a54836127e690919063ffffffff16565b9050610e12610e0386610df5670de0b6b3a7640000856127e690919063ffffffff16565b6128ef90919063ffffffff16565b8761297890919063ffffffff16565b9550505050505b610e608360010154610e52670de0b6b3a7640000610e448688600001546127e690919063ffffffff16565b6128ef90919063ffffffff16565b61286c90919063ffffffff16565b95505050505b505092915050565b600c6020528160005260406000208181548110610e8757fe5b9060005260206000209060030201600091509150508060000154908060010154908060020154905083565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600e5481565b60045481565b6000600d544211610ef85760009050610f40565b6000600e544210610f0b57600e54610f0d565b425b9050610f3c600954610f2e600d548403600a546127e690919063ffffffff16565b61286c90919063ffffffff16565b9150505b90565b601660009054906101000a900460ff1681565b60026001541415610fcf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026001819055503381600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110611090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b600080600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002085815481106110dd57fe5b90600052602060002090600302019050858160000154101561114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613641602a913960400191505060405180910390fd5b6111526123fc565b4261116c600754836002015461297890919063ffffffff16565b11159150600660009054906101000a900460ff166111f857816111f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f557365722063616e206e6f742077697468647261772066756e6473207965742e81525060200191505060405180910390fd5b5b60006112438260010154611235670de0b6b3a764000061122760045487600001546127e690919063ffffffff16565b6128ef90919063ffffffff16565b61286c90919063ffffffff16565b90506000811115611302576001600281111561125b57fe5b600f60009054906101000a900460ff16600281111561127657fe5b148015611281575082155b1561129657611291600182612a00565b611301565b6002808111156112a257fe5b600f60009054906101000a900460ff1660028111156112bd57fe5b1480156112c8575082155b156112f557600e5442106112e6576112e1600182612a00565b6112f0565b6112ef81612f5d565b5b611300565b6112ff3382612a00565b5b5b5b61131987836000015461286c90919063ffffffff16565b8260000181905550611354670de0b6b3a764000061134660045485600001546127e690919063ffffffff16565b6128ef90919063ffffffff16565b82600101819055506113a93388600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661306f9092919063ffffffff16565b6113be8760055461286c90919063ffffffff16565b6005819055503373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5688789604051808381526020018281526020019250505060405180910390a25050505050600180819055505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611458613111565b73ffffffffffffffffffffffffffffffffffffffff16611476611ccb565b73ffffffffffffffffffffffffffffffffffffffff16146114ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060078190555050565b60026001541415611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026001819055503381600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110611643576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020848154811061168f57fe5b90600052602060002090600302019050600660009054906101000a900460ff16611748576000426116cf600754846002015461297890919063ffffffff16565b1115905080611746576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f557365722063616e206e6f742077697468647261772066756e6473207965742e81525060200191505060405180910390fd5b505b611799338260000154600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661306f9092919063ffffffff16565b6117b2816000015460055461286c90919063ffffffff16565b6005819055503373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae0595858360000154604051808381526020018281526020019250505060405180910390a260008160000181905550600081600101819055505050506001808190555050565b60135481565b60095481565b60125481565b60008282600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110611900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020858154811061194c57fe5b906000526020600020906003020190508060000154935050505092915050565b611974613111565b73ffffffffffffffffffffffffffffffffffffffff16611992611ccb565b73ffffffffffffffffffffffffffffffffffffffff1614611a1b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d5481565b60055481565b60608060606000600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060608167ffffffffffffffff81118015611b7057600080fd5b50604051908082528060200260200182016040528015611b9f5781602001602082028036833780820191505090505b50905060608267ffffffffffffffff81118015611bbb57600080fd5b50604051908082528060200260200182016040528015611bea5781602001602082028036833780820191505090505b50905060608367ffffffffffffffff81118015611c0657600080fd5b50604051908082528060200260200182016040528015611c355781602001602082028036833780820191505090505b50905060005b84811015611cb657611c4d8982611845565b848281518110611c5957fe5b602002602001018181525050611c6f8982610c1e565b838281518110611c7b57fe5b602002602001018181525050611c9189826124c7565b828281518110611c9d57fe5b6020026020010181815250508080600101915050611c3b565b50828282965096509650505050509193909250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600a5481565b60035481565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b611d54613111565b73ffffffffffffffffffffffffffffffffffffffff16611d72611ccb565b73ffffffffffffffffffffffffffffffffffffffff1614611dfb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611e9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f57726f6e672066656520636f6c6c6563746f7220616464726573732e0000000081525060200191505060405180910390fd5b80601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611eea613569565b611ef26123fc565b611f41333084600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613119909392919063ffffffff16565b6000829050601660009054906101000a900460ff16156120ba57601554341015611fb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806135d76027913960400191505060405180910390fd5b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163460405180600001905060006040518083038185875af1925050503d8060008114612038576040519150601f19603f3d011682016040523d82523d6000602084013e61203d565b606091505b50509050806120b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f4661696c656420746f2073656e6420666c61742066656500000000000000000081525060200191505060405180910390fd5b50612178565b600060125411156121775760006120ef60646120e1601254876127e690919063ffffffff16565b6128ef90919063ffffffff16565b9050612104818561286c90919063ffffffff16565b9150612175601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661306f9092919063ffffffff16565b505b5b61218d8160055461297890919063ffffffff16565b600581905550808260000181815250506121d0670de0b6b3a76400006121c260045485600001516127e690919063ffffffff16565b6128ef90919063ffffffff16565b826020018181525050428260400181815250506000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002015550503373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a158284604051808381526020018281526020019250505060405180910390a250505050565b600660009054906101000a900460ff1681565b60075481565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b612364600160105461297890919063ffffffff16565b60108190555061237381612f5d565b6123c2333083600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613119909392919063ffffffff16565b600260105414156123f9576123f8601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166125ee565b5b50565b6000600e54421061240f57600e54612411565b425b9050600354811161242257506124c5565b600060055490506000811415612440578160038190555050506124c5565b60006124576003548461286c90919063ffffffff16565b90506000612470600a54836127e690919063ffffffff16565b90506124b36124a284612494670de0b6b3a7640000856127e690919063ffffffff16565b6128ef90919063ffffffff16565b60045461297890919063ffffffff16565b60048190555042600381905550505050505b565b60008282600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110612582576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5374616b6520646f6573206e6f7420657869737400000000000000000000000081525060200191505060405180910390fd5b6000600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002085815481106125ce57fe5b906000526020600020906003020190508060020154935050505092915050565b6125f6613111565b73ffffffffffffffffffffffffffffffffffffffff16612614611ccb565b73ffffffffffffffffffffffffffffffffffffffff161461269d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061358b6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60155481565b6000808314156127f95760009050612866565b600082840290508284828161280a57fe5b0414612861576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806135fe6021913960400191505060405180910390fd5b809150505b92915050565b6000828211156128e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b6000808211612966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b81838161296f57fe5b04905092915050565b6000808284019050838110156129f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b601660009054906101000a900460ff1615612c5357601554341015612a70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806135d76027913960400191505060405180910390fd5b6000601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163460405180600001905060006040518083038185875af1925050503d8060008114612af2576040519150601f19603f3d011682016040523d82523d6000602084013e612af7565b606091505b5050905080612b6e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4661696c656420746f20656e6420666c6174206665650000000000000000000081525060200191505060405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612c0157600080fd5b505af1158015612c15573d6000803e3d6000fd5b505050506040513d6020811015612c2b57600080fd5b8101908080519060200190929190505050508160096000828254019250508190555050612f59565b60006012541115612e78576000612c886064612c7a601354856127e690919063ffffffff16565b6128ef90919063ffffffff16565b90506000612c9f828461286c90919063ffffffff16565b9050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612d5657600080fd5b505af1158015612d6a573d6000803e3d6000fd5b505050506040513d6020811015612d8057600080fd5b810190808051906020019092919050505050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612e2557600080fd5b505af1158015612e39573d6000803e3d6000fd5b505050506040513d6020811015612e4f57600080fd5b810190808051906020019092919050505050826009600082825401925050819055505050612f58565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015612f0b57600080fd5b505af1158015612f1f573d6000803e3d6000fd5b505050506040513d6020811015612f3557600080fd5b810190808051906020019092919050505050806009600082825401925050819055505b5b5050565b600e544210612fb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061361f6022913960400191505060405180910390fd5b6000811161302d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f416d6f756e74206d7573742062652067726561746572207468616e20302e000081525060200191505060405180910390fd5b613042600a54826128ef90919063ffffffff16565b600e6000828254019250508190555061306681600b5461297890919063ffffffff16565b600b8190555050565b61310c8363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506131da565b505050565b600033905090565b6131d4846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506131da565b50505050565b606061323c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132c99092919063ffffffff16565b90506000815111156132c45780806020019051602081101561325d57600080fd5b81019080805190602001909291905050506132c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061366b602a913960400191505060405180910390fd5b5b505050565b60606132d884846000856132e1565b90509392505050565b60608247101561333c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806135b16026913960400191505060405180910390fd5b6133458561348a565b6133b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061340757805182526020820191506020810190506020830392506133e4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613469576040519150601f19603f3d011682016040523d82523d6000602084013e61346e565b606091505b509150915061347e82828661349d565b92505050949350505050565b600080823b905060008111915050919050565b606083156134ad57829050613562565b6000835111156134c05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561352757808201518184015260208101905061350c565b50505050905090810190601f1680156135545780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b6040518060600160405280600081526020016000815260200160008152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c50617961626c6520616d6f756e74206973206c657373207468616e2066656520616d6f756e742e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7766756e643a20746f6f206c6174652c20746865206661726d20697320636c6f73656477697468647261773a2063616e2774207769746864726177206d6f7265207468616e206465706f7369745361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122030e6ff7dd276afdc9adeeec2906273dcc8bedf59824a8ac48c74a72d1500ccbe64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000080d55c03180349fff4a229102f62328220a964440000000000000000000000000000000000000000000000000403fbf9e8bb284b000000000000000000000000000000000000000000000000000000006152fcb800000000000000000000000000000000000000000000000000000000000d2f0000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000b6b4c7ac240b1f176c5589d064733066a83884a10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002ad0606097905292f92daa48bcaf5b9e1c555bc40000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _erc20 (address): 0x80D55c03180349Fff4a229102F62328220A96444
Arg [1] : _rewardPerSecond (uint256): 289351851851851851
Arg [2] : _startTime (uint256): 1632828600
Arg [3] : _minTimeToStake (uint256): 864000
Arg [4] : _isEarlyWithdrawAllowed (bool): True
Arg [5] : _penalty (uint8): 2
Arg [6] : _tokenStaked (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [7] : _congressAddress (address): 0xB6b4C7aC240b1f176c5589d064733066a83884a1
Arg [8] : _stakeFeePercent (uint256): 0
Arg [9] : _rewardFeePercent (uint256): 0
Arg [10] : _flatFeeAmount (uint256): 0
Arg [11] : _feeCollector (address): 0x2AD0606097905292F92dAA48bcaF5b9e1C555BC4
Arg [12] : _isFlatFeeAllowed (bool): False
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 00000000000000000000000080d55c03180349fff4a229102f62328220a96444
Arg [1] : 0000000000000000000000000000000000000000000000000403fbf9e8bb284b
Arg [2] : 000000000000000000000000000000000000000000000000000000006152fcb8
Arg [3] : 00000000000000000000000000000000000000000000000000000000000d2f00
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [6] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [7] : 000000000000000000000000b6b4c7ac240b1f176c5589d064733066a83884a1
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000002ad0606097905292f92daa48bcaf5b9e1c555bc4
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
28235:17502:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43962:694;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;29491:27;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;29797:35;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;35004:1090;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;29577:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29918:30;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;29737:22;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;28885:31;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;36510:326;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;30233:28;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;39402:2435;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28728:25;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;32517:122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;41908:958;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;30045:31;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;29347:22;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;29981:30;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;34679:261;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;24895:148;;;;;;;;;;;;;:::i;:::-;;29260:19;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;29670:24;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;28968:28;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;43135:777;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24244:87;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;29418:30;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;28796:29;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;42912:157;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;32681:203;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;37644:1709;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;29098:34;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;29179:29;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;30113:35;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;33159:299;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;36912:665;;;;;;;;;;;;;:::i;:::-;;36161:273;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;25198:244;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;30179:28;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;43962:694;44053:7;44062;44087:26;44124:28;44188:9;;44169:15;:28;44165:422;;44237:1;44214:24;;44274:12;;44253:33;;44165:422;;;44319:16;44356:7;;44338:15;:25;:87;;44418:7;;44338:87;;;44383:15;44338:87;44319:106;;44463:41;44494:9;;44483:8;:20;44463:15;;:19;;:41;;;;:::i;:::-;44440:64;;44555:20;44540:12;;:35;44519:56;;44165:422;;44607:20;44629:18;44599:49;;;;;;43962:694;;:::o;29491:27::-;;;;:::o;29797:35::-;;;;;;;;;;;;;:::o;35004:1090::-;35149:7;35115:5;35122:7;30719:9;:16;30729:5;30719:16;;;;;;;;;;;;;;;:23;;;;30709:7;:33;30701:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35174:23:::1;35200:9;:16;35210:5;35200:16;;;;;;;;;;;;;;;35217:7;35200:25;;;;;;;;;;;;;;;;;;35174:51;;35258:1;35242:5;:12;;;:17;35238:58;;;35283:1;35276:8;;;;;35238:58;35308:25;35336:16;;35308:44;;35363:19;35385:13;;35363:35;;35433:14;;35415:15;:32;:52;;;;;35466:1;35451:11;:16;;35415:52;35411:576;;;35484:16;35521:7;;35503:15;:25;:87;;35583:7;;35503:87;;;35548:15;35503:87;35484:106;;35605:21;35646:7;;35629:14;;:24;:85;;35707:7;;35629:85;;;35673:14;;35629:85;35605:109;;35729:19;35751:27;35764:13;35751:8;:12;;:27;;;;:::i;:::-;35729:49;;35793:19;35815:32;35831:15;;35815:11;:15;;:32;;;;:::i;:::-;35793:54;;35882:93;35922:38;35948:11;35922:21;35938:4;35922:11;:15;;:21;;;;:::i;:::-;:25;;:38;;;;:::i;:::-;35882:17;:21;;:93;;;;:::i;:::-;35862:113;;35411:576;;;;;36019:67;36069:5;:16;;;36019:45;36059:4;36019:35;36036:17;36019:5;:12;;;:16;;:35;;;;:::i;:::-;:39;;:45;;;;:::i;:::-;:49;;:67;;;;:::i;:::-;35999:87;;;;;30778:1;35004:1090:::0;;;;;;:::o;29577:48::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;29918:30::-;;;;;;;;;;;;;:::o;29737:22::-;;;;:::o;28885:31::-;;;;:::o;36510:326::-;36557:7;36600:9;;36581:15;:28;36577:69;;36633:1;36626:8;;;;36577:69;36658:16;36695:7;;36677:15;:25;:79;;36749:7;;36677:79;;;36718:15;36677:79;36658:98;;36774:54;36820:7;;36774:41;36805:9;;36794:8;:20;36774:15;;:19;;:41;;;;:::i;:::-;:45;;:54;;;;:::i;:::-;36767:61;;;36510:326;;:::o;30233:28::-;;;;;;;;;;;;;:::o;39402:2435::-;27207:1;27813:7;;:19;;27805:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27207:1;27946:7;:18;;;;39543:10:::1;39555:7;30719:9;:16;30729:5;30719:16;;;;;;;;;;;;;;;:23;;;;30709:7;:33;30701:66;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;39580:30:::2;39623:23:::0;39649:9:::2;:21;39659:10;39649:21;;;;;;;;;;;;;;;39671:7;39649:30;;;;;;;;;;;;;;;;;;39623:56;;39730:7;39714:5;:12;;;:23;;39692:115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39820:12;:10;:12::i;:::-;39912:15;39871:37;39893:14;;39871:5;:17;;;:21;;:37;;;;:::i;:::-;:56;;39843:84;;40022:22;;;;;;;;;;;40017:254;;40166:25;40140:119;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;40017:254;40342:21;40366:122;40471:5;:16;;;40366:86;40447:4;40366:62;40411:16;;40366:5;:26;;;:44;;:62;;;;:::i;:::-;:80;;:86;;;;:::i;:::-;:104;;:122;;;;:::i;:::-;40342:146;;40583:1;40567:13;:17;40563:932;;;40634:33;40623:44;;;;;;;;:7;;;;;;;;;;;:44;;;;;;;;;:91;;;;;40689:25;40688:26;40623:91;40601:883;;;40789:41;40812:1;40816:13;40789:14;:41::i;:::-;40601:883;;;40885:41;40874:52:::0;::::2;;;;;;;:7;;;;;;;;;;;:52;;;;;;;;;:99;;;;;40948:25;40947:26;40874:99;40852:632;;;41031:7;;41012:15;:26;41008:325;;41154:41;41177:1;41181:13;41154:14;:41::i;:::-;41008:325;;;41285:28;41299:13;41285;:28::i;:::-;41008:325;40852:632;;;41427:41;41442:10;41454:13;41427:14;:41::i;:::-;40852:632;40601:883;40563:932;41522:25;41539:7;41522:5;:12;;;:16;;:25;;;;:::i;:::-;41507:5;:12;;:40;;;;41577:44;41616:4;41577:34;41594:16;;41577:5;:12;;;:16;;:34;;;;:::i;:::-;:38;;:44;;;;:::i;:::-;41558:5;:16;;:63;;;;41634:54;41667:10;41680:7;41634:11;;;;;;;;;;;:24;;;;:54;;;;;:::i;:::-;41715:26;41733:7;41715:13;;:17;;:26;;;;:::i;:::-;41699:13;:42;;;;41800:10;41791:38;;;41812:7;41821;41791:38;;;;;;;;;;;;;;;;;;;;;;;;30778:1;;;27977::::1;;27163::::0;28125:7;:22;;;;39402:2435;;:::o;28728:25::-;;;;;;;;;;;;;:::o;32517:122::-;24475:12;:10;:12::i;:::-;24464:23;;:7;:5;:7::i;:::-;:23;;;24456:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32616:15:::1;32599:14;:32;;;;32517:122:::0;:::o;41908:958::-;27207:1;27813:7;;:19;;27805:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27207:1;27946:7;:18;;;;42024:10:::1;42036:7;30719:9;:16;30729:5;30719:16;;;;;;;;;;;;;;;:23;;;;30709:7;:33;30701:66;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;42061:23:::2;42087:9;:21;42097:10;42087:21;;;;;;;;;;;;;;;42109:7;42087:30;;;;;;;;;;;;;;;;;;42061:56;;42214:22;;;;;;;;;;;42209:390;;42253:30;42359:15;42286:69;42326:14;;42286:5;:17;;;:21;;:69;;;;:::i;:::-;:88;;42253:121;;42494:25;42468:119;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;42209:390;;42611:59;42644:10;42657:5;:12;;;42611:11;;;;;;;;;;;:24;;;;:59;;;;;:::i;:::-;42697:31;42715:5;:12;;;42697:13;;:17;;:31;;;;:::i;:::-;42681:13;:47;;;;42764:10;42746:52;;;42776:7;42785:5;:12;;;42746:52;;;;;;;;;;;;;;;;;;;;;;;;42826:1;42811:5;:12;;:16;;;;42857:1;42838:5;:16;;:20;;;;30778:1;27977::::1;;27163::::0;28125:7;:22;;;;41908:958;:::o;30045:31::-;;;;:::o;29347:22::-;;;;:::o;29981:30::-;;;;:::o;34679:261::-;34826:7;34792:5;34799:7;30719:9;:16;30729:5;30719:16;;;;;;;;;;;;;;;:23;;;;30709:7;:33;30701:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34851:23:::1;34877:9;:16;34887:5;34877:16;;;;;;;;;;;;;;;34894:7;34877:25;;;;;;;;;;;;;;;;;;34851:51;;34920:5;:12;;;34913:19;;;34679:261:::0;;;;;;:::o;24895:148::-;24475:12;:10;:12::i;:::-;24464:23;;:7;:5;:7::i;:::-;:23;;;24456:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25002:1:::1;24965:40;;24986:6;::::0;::::1;;;;;;;;24965:40;;;;;;;;;;;;25033:1;25016:6:::0;::::1;:19;;;;;;;;;;;;;;;;;;24895:148::o:0;29260:19::-;;;;;;;;;;;;;:::o;29670:24::-;;;;:::o;28968:28::-;;;;:::o;43135:777::-;43253:16;43284;43315;43359:22;43384:9;:15;43394:4;43384:15;;;;;;;;;;;;;;;:22;;;;43359:47;;43419:25;43461:14;43447:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43419:57;;43487:31;43535:14;43521:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43487:63;;43561:28;43606:14;43592:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43561:60;;43639:9;43634:212;43658:14;43654:1;:18;43634:212;;;43708:18;43718:4;43724:1;43708:9;:18::i;:::-;43694:8;43703:1;43694:11;;;;;;;;;;;;;:32;;;;;43761:16;43769:4;43775:1;43761:7;:16::i;:::-;43741:14;43756:1;43741:17;;;;;;;;;;;;;:36;;;;;43809:25;43826:4;43832:1;43809:16;:25::i;:::-;43792:11;43804:1;43792:14;;;;;;;;;;;;;:42;;;;;43674:3;;;;;;;43634:212;;;;43866:8;43876:14;43892:11;43858:46;;;;;;;;;;43135:777;;;;;:::o;24244:87::-;24290:7;24317:6;;;;;;;;;;;24310:13;;24244:87;:::o;29418:30::-;;;;:::o;28796:29::-;;;;:::o;42912:157::-;43007:7;43039:9;:15;43049:4;43039:15;;;;;;;;;;;;;;;:22;;;;43032:29;;42912:157;;;:::o;32681:203::-;24475:12;:10;:12::i;:::-;24464:23;;:7;:5;:7::i;:::-;:23;;;24456:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32800:3:::1;32775:29;;:13;:29;;;;32767:70;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;32863:13;32848:12;;:28;;;;;;;;;;;;;;;;;;32681:203:::0;:::o;37644:1709::-;37706:22;;:::i;:::-;37765:12;:10;:12::i;:::-;37838:123;37889:10;37923:4;37943:7;37838:11;;;;;;;;;;;:28;;;;:123;;;;;;:::i;:::-;37974:20;37997:7;37974:30;;38021:16;;;;;;;;;;;38017:766;;;38126:13;;38113:9;:26;;38087:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38230:9;38253:12;;;;;;;;;;;38245:26;;38279:9;38245:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38229:64;;;38316:4;38308:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38017:766;;;;38388:1;38370:15;;:19;38366:417;;;38515:17;38535:37;38568:3;38535:28;38547:15;;38535:7;:11;;:28;;;;:::i;:::-;:32;;:37;;;;:::i;:::-;38515:57;;38639:22;38651:9;38639:7;:11;;:22;;;;:::i;:::-;38624:37;;38722:49;38747:12;;;;;;;;;;;38761:9;38722:11;;;;;;;;;;;:24;;;;:49;;;;;:::i;:::-;38366:417;;38017:766;38847:31;38865:12;38847:13;;:17;;:31;;;;:::i;:::-;38831:13;:47;;;;38939:12;38924:5;:12;;:27;;;;;38981:44;39020:4;38981:34;38998:16;;38981:5;:12;;;:16;;:34;;;;:::i;:::-;:38;;:44;;;;:::i;:::-;38962:5;:16;;:63;;;;;39056:15;39036:5;:17;;:35;;;;;39111:15;39129:9;:21;39139:10;39129:21;;;;;;;;;;;;;;;:28;;;;39111:46;;39223:9;:21;39233:10;39223:21;;;;;;;;;;;;;;;39250:5;39223:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39311:10;39303:42;;;39323:7;39332:12;39303:42;;;;;;;;;;;;;;;;;;;;;;;;37644:1709;;;;:::o;29098:34::-;;;;;;;;;;;;;:::o;29179:29::-;;;;:::o;30113:35::-;;;;;;;;;;;;;:::o;33159:299::-;33224:18;33240:1;33224:11;;:15;;:18;;;;:::i;:::-;33210:11;:32;;;;33255:22;33269:7;33255:13;:22::i;:::-;33288:67;33319:10;33340:4;33347:7;33288:5;;;;;;;;;;;:22;;;;:67;;;;;;:::i;:::-;33387:1;33372:11;;:16;33368:83;;;33405:34;33423:15;;;;;;;;;;;33405:17;:34::i;:::-;33368:83;33159:299;:::o;36912:665::-;36952:16;36989:7;;36971:15;:25;:79;;37043:7;;36971:79;;;37012:15;36971:79;36952:98;;37079:14;;37067:8;:26;37063:65;;37110:7;;;37063:65;37140:19;37162:13;;37140:35;;37207:1;37192:11;:16;37188:95;;;37242:8;37225:14;:25;;;;37265:7;;;;37188:95;37295:19;37317:28;37330:14;;37317:8;:12;;:28;;;;:::i;:::-;37295:50;;37356:19;37378:32;37394:15;;37378:11;:15;;:32;;;;:::i;:::-;37356:54;;37442:84;37477:38;37503:11;37477:21;37493:4;37477:11;:15;;:21;;;;:::i;:::-;:25;;:38;;;;:::i;:::-;37442:16;;:20;;:84;;;;:::i;:::-;37423:16;:103;;;;37554:15;37537:14;:32;;;;36912:665;;;;;:::o;36161:273::-;36315:7;36281:5;36288:7;30719:9;:16;30729:5;30719:16;;;;;;;;;;;;;;;:23;;;;30709:7;:33;30701:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36340:23:::1;36366:9;:16;36376:5;36366:16;;;;;;;;;;;;;;;36383:7;36366:25;;;;;;;;;;;;;;;;;;36340:51;;36409:5;:17;;;36402:24;;;36161:273:::0;;;;;;:::o;25198:244::-;24475:12;:10;:12::i;:::-;24464:23;;:7;:5;:7::i;:::-;:23;;;24456:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25307:1:::1;25287:22;;:8;:22;;;;25279:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25397:8;25368:38;;25389:6;::::0;::::1;;;;;;;;25368:38;;;;;;;;;;;;25426:8;25417:6;::::0;:17:::1;;;;;;;;;;;;;;;;;;25198:244:::0;:::o;30179:28::-;;;;:::o;6561:220::-;6619:7;6648:1;6643;:6;6639:20;;;6658:1;6651:8;;;;6639:20;6670:9;6686:1;6682;:5;6670:17;;6715:1;6710;6706;:5;;;;;;:10;6698:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6772:1;6765:8;;;6561:220;;;;;:::o;6144:158::-;6202:7;6235:1;6230;:6;;6222:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6293:1;6289;:5;6282:12;;6144:158;;;;:::o;7259:153::-;7317:7;7349:1;7345;:5;7337:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7403:1;7399;:5;;;;;;7392:12;;7259:153;;;;:::o;5682:179::-;5740:7;5760:9;5776:1;5772;:5;5760:17;;5801:1;5796;:6;;5788:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5852:1;5845:8;;;5682:179;;;;:::o;44739:995::-;44817:16;;;;;;;;;;;44813:914;;;44922:13;;44909:9;:26;;44883:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45026:9;45049:12;;;;;;;;;;;45041:26;;45075:9;45041:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45025:64;;;45112:4;45104:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45186:5;;;;;;;;;;;:14;;;45201:3;45206:7;45186:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45240:7;45229;;:18;;;;;;;;;;;44813:914;;;;45287:1;45269:15;;:19;45265:462;;;45340:17;45360:38;45394:3;45360:29;45372:16;;45360:7;:11;;:29;;;;:::i;:::-;:33;;:38;;;;:::i;:::-;45340:58;;45413:20;45436:22;45448:9;45436:7;:11;;:22;;;;:::i;:::-;45413:45;;45473:5;;;;;;;;;;;:14;;;45488:12;;;;;;;;;;;45502:9;45473:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45555:5;;;;;;;;;;;:14;;;45570:3;45575:12;45555:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45614:7;45603;;:18;;;;;;;;;;;45265:462;;;;;45654:5;;;;;;;;;;;:14;;;45669:3;45674:7;45654:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45708:7;45697;;:18;;;;;;;;;;;45265:462;44813:914;44739:995;;:::o;33543:416::-;33643:7;;33625:15;:25;33603:109;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33741:1;33731:7;:11;33723:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33832:28;33844:15;;33832:7;:11;;:28;;;;:::i;:::-;33821:7;;:39;;;;;;;;;;;33926:25;33943:7;33926:12;;:16;;:25;;;;:::i;:::-;33911:12;:40;;;;33543:416;:::o;19058:177::-;19141:86;19161:5;19191:23;;;19216:2;19220:5;19168:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19141:19;:86::i;:::-;19058:177;;;:::o;22773:106::-;22826:15;22861:10;22854:17;;22773:106;:::o;19243:205::-;19344:96;19364:5;19394:27;;;19423:4;19429:2;19433:5;19371:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19344:19;:96::i;:::-;19243:205;;;;:::o;21363:761::-;21787:23;21813:69;21841:4;21813:69;;;;;;;;;;;;;;;;;21821:5;21813:27;;;;:69;;;;;:::i;:::-;21787:95;;21917:1;21897:10;:17;:21;21893:224;;;22039:10;22028:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22020:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21893:224;21363:761;;;:::o;14047:195::-;14150:12;14182:52;14204:6;14212:4;14218:1;14221:12;14182:21;:52::i;:::-;14175:59;;14047:195;;;;;:::o;15099:530::-;15226:12;15284:5;15259:21;:30;;15251:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15351:18;15362:6;15351:10;:18::i;:::-;15343:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15477:12;15491:23;15518:6;:11;;15538:5;15546:4;15518:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15476:75;;;;15569:52;15587:7;15596:10;15608:12;15569:17;:52::i;:::-;15562:59;;;;15099:530;;;;;;:::o;11129:422::-;11189:4;11397:12;11508:7;11496:20;11488:28;;11542:1;11535:4;:8;11528:15;;;11129:422;;;:::o;17639:742::-;17754:12;17783:7;17779:595;;;17814:10;17807:17;;;;17779:595;17948:1;17928:10;:17;:21;17924:439;;;18191:10;18185:17;18252:15;18239:10;18235:2;18231:19;18224:44;18139:148;18334:12;18327:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17639:742;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://30e6ff7dd276afdc9adeeec2906273dcc8bedf59824a8ac48c74a72d1500ccbe
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.