Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 13862857 | 940 days ago | IN | Create: UnipoolTokenDistributor | 0 ETH | 0.25327116 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
UnipoolTokenDistributor
Compiler Version
v0.8.6+commit.11564f7e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-12-24 */ // File: contracts/Interfaces/IDistro.sol pragma solidity =0.8.6; interface IDistro { /** * @dev Emitted when someone makes a claim of tokens */ event Claim(address indexed grantee, uint256 amount); /** * @dev Emitted when the DISTRIBUTOR allocate an amount to a grantee */ event Allocate( address indexed distributor, address indexed grantee, uint256 amount ); /** * @dev Emitted when the DEFAULT_ADMIN assign an amount to a DISTRIBUTOR */ event Assign( address indexed admin, address indexed distributor, uint256 amount ); /** * @dev Emitted when someone change their reception address */ event ChangeAddress(address indexed oldAddress, address indexed newAddress); /** * @dev Emitted when a new startTime is set */ event StartTimeChanged(uint256 newStartTime, uint256 newCliffTime); /** * @dev Returns the total amount of tokens will be streamed */ function totalTokens() external view returns (uint256); /** * Function that allows the DEFAULT_ADMIN_ROLE to assign set a new startTime if it hasn't started yet * @param newStartTime new startTime * * Emits a {StartTimeChanged} event. * */ function setStartTime(uint256 newStartTime) external; /** * Function that allows the DEFAULT_ADMIN_ROLE to assign tokens to an address who later can distribute them. * @dev It is required that the DISTRIBUTOR_ROLE is already held by the address to which an amount will be assigned * @param distributor the address, generally a smart contract, that will determine who gets how many tokens * @param amount Total amount of tokens to assign to that address for distributing */ function assign(address distributor, uint256 amount) external; /** * Function to claim tokens for a specific address. It uses the current timestamp */ function claim() external; /** * Function that allows to the distributor address to allocate some amount of tokens to a specific recipient * @dev Needs to be initialized: Nobody has the DEFAULT_ADMIN_ROLE and all available tokens have been assigned * @param recipient of token allocation * @param amount allocated amount * @param claim whether claim after allocate */ function allocate( address recipient, uint256 amount, bool claim ) external; /** * Function that allows to the distributor address to allocate some amounts of tokens to specific recipients * @dev Needs to be initialized: Nobody has the DEFAULT_ADMIN_ROLE and all available tokens have been assigned * @param recipients of token allocation * @param amounts allocated amount */ function allocateMany(address[] memory recipients, uint256[] memory amounts) external; function sendGIVbacks(address[] memory recipients, uint256[] memory amounts) external; /** * Function that allows a recipient to change its address * @dev The change can only be made to an address that has not previously received an allocation & * the distributor cannot change its address */ function changeAddress(address newAddress) external; /** * Function to get the current timestamp from the block */ function getTimestamp() external view returns (uint256); /** * Function to get the total unlocked tokes at some moment */ function globallyClaimableAt(uint256 timestamp) external view returns (uint256); /** * Function to get the unlocked tokes at some moment for a specific address */ function claimableAt(address recipient, uint256 timestamp) external view returns (uint256); /** * Function to get the unlocked tokens for a specific address. It uses the current timestamp */ function claimableNow(address recipient) external view returns (uint256); function cancelAllocation(address prevRecipient, address newRecipient) external; } // File: openzeppelin-contracts-upgradable-v4/utils/AddressUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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; 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"); (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"); (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"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: openzeppelin-contracts-upgradable-v4/token/ERC20/IERC20Upgradeable.sol pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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-upgradable-v4/token/ERC20/utils/SafeERC20Upgradeable.sol pragma solidity ^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 SafeERC20Upgradeable { using AddressUpgradeable for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20Upgradeable 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( IERC20Upgradeable 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' 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( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _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(IERC20Upgradeable 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 require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: openzeppelin-contracts-upgradable-v4/utils/math/SafeMathUpgradeable.sol pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMathUpgradeable { /** * @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) { unchecked { 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) { unchecked { 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) { unchecked { // 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) { unchecked { 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) { unchecked { 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) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return 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) { return a * b; } /** * @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. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { 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) { 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) { unchecked { 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. * * 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) { unchecked { 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) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File: openzeppelin-contracts-upgradable-v4/utils/math/MathUpgradeable.sol pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } } // File: openzeppelin-contracts-upgradable-v4/proxy/utils/Initializable.sol pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } } // File: openzeppelin-contracts-upgradable-v4/utils/ContextUpgradeable.sol pragma solidity ^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 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 ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; } // File: openzeppelin-contracts-upgradable-v4/access/OwnableUpgradeable.sol pragma solidity ^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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; } // File: contracts/Distributors/UnipoolTokenDistributor.sol pragma solidity ^0.8.6; // Based on: https://github.com/Synthetixio/Unipool/tree/master/contracts /* * changelog: * * Added SPDX-License-Identifier * * Update to solidity ^0.8.0 * * Update openzeppelin imports * * IRewardDistributionRecipient integrated in Unipool and removed * * Added virtual and override to stake and withdraw methods * * Added constructors to LPTokenWrapper and Unipool * * Change transfer to allocate (TokenVesting) * * Added `stakeWithPermit` function for NODE and the BridgeToken */ contract LPTokenWrapper is Initializable { using SafeMathUpgradeable for uint256; using SafeERC20Upgradeable for IERC20Upgradeable; IERC20Upgradeable public uni; uint256 private _totalSupply; mapping(address => uint256) private _balances; function __LPTokenWrapper_initialize(IERC20Upgradeable _uni) public initializer { uni = _uni; } function totalSupply() public view returns (uint256) { return _totalSupply; } function balanceOf(address account) public view returns (uint256) { return _balances[account]; } function stake(uint256 amount) public virtual { _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); uni.safeTransferFrom(msg.sender, address(this), amount); } function withdraw(uint256 amount) public virtual { _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); uni.safeTransfer(msg.sender, amount); } } contract UnipoolTokenDistributor is LPTokenWrapper, OwnableUpgradeable { using SafeMathUpgradeable for uint256; using SafeERC20Upgradeable for IERC20Upgradeable; IDistro public tokenDistro; uint256 public duration; address public rewardDistribution; uint256 public periodFinish; uint256 public rewardRate; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; event RewardAdded(uint256 reward); event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); // bytes4 private constant _PERMIT_SIGNATURE = // bytes4(keccak256(bytes("permit(address,address,uint256,uint256,uint8,bytes32,bytes32)"))); bytes4 private constant _PERMIT_SIGNATURE = 0xd505accf; // bytes4 private constant _PERMIT_SIGNATURE_BRIDGE = // bytes4(keccak256(bytes("permit(address,address,uint256,uint256,bool,uint8,bytes32,bytes32)"))); bytes4 private constant _PERMIT_SIGNATURE_BRIDGE = 0x8fcbaf0c; modifier onlyRewardDistribution() { require( _msgSender() == rewardDistribution, "Caller is not reward distribution" ); _; } modifier updateReward(address account) { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; } function initialize( IDistro _tokenDistribution, IERC20Upgradeable _uni, uint256 _duration ) public initializer { __Ownable_init(); __LPTokenWrapper_initialize(_uni); tokenDistro = _tokenDistribution; duration = _duration; periodFinish = 0; rewardRate = 0; } function lastTimeRewardApplicable() public view returns (uint256) { return MathUpgradeable.min(_getBlockTimestamp(), periodFinish); } function rewardPerToken() public view returns (uint256) { if (totalSupply() == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( lastTimeRewardApplicable() .sub(lastUpdateTime) .mul(rewardRate) .mul(1e18) .div(totalSupply()) ); } function earned(address account) public view returns (uint256) { return balanceOf(account) .mul(rewardPerToken().sub(userRewardPerTokenPaid[account])) .div(1e18) .add(rewards[account]); } // stake visibility is public as overriding LPTokenWrapper's stake() function function stake(uint256 amount) public override updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); super.stake(amount); emit Staked(msg.sender, amount); } function withdraw(uint256 amount) public override updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); super.withdraw(amount); emit Withdrawn(msg.sender, amount); } function exit() external { withdraw(balanceOf(msg.sender)); getReward(); } function getReward() public updateReward(msg.sender) { uint256 reward = earned(msg.sender); if (reward > 0) { rewards[msg.sender] = 0; //token.safeTransfer(msg.sender, reward); tokenDistro.allocate(msg.sender, reward, true); emit RewardPaid(msg.sender, reward); } } function notifyRewardAmount(uint256 reward) external onlyRewardDistribution updateReward(address(0)) { uint256 _timestamp = _getBlockTimestamp(); if (_timestamp >= periodFinish) { rewardRate = reward.div(duration); } else { uint256 remaining = periodFinish.sub(_timestamp); uint256 leftover = remaining.mul(rewardRate); rewardRate = reward.add(leftover).div(duration); } lastUpdateTime = _timestamp; periodFinish = _timestamp.add(duration); emit RewardAdded(reward); } function setRewardDistribution(address _rewardDistribution) external onlyOwner { rewardDistribution = _rewardDistribution; } /** * @notice method that allows you to stake by using the permit method * @param amount the amount to be staked, it has to match the amount that appears in the signature * @param permit the bytes of the signed permit function call */ function stakeWithPermit(uint256 amount, bytes calldata permit) public updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); // we call without checking the result, in case it fails and he doesn't have enough balance // the following transferFrom should be fail. This prevents DoS attacks from using a signature // before the smartcontract call _permit(amount, permit); super.stake(amount); emit Staked(msg.sender, amount); } /** * @notice function to extract the selector of a bytes calldata * @param _data the calldata bytes */ function getSelector(bytes memory _data) private pure returns (bytes4 sig) { assembly { sig := mload(add(_data, 32)) } } /** * @notice function to call token permit function, since the token on xDAI has a different implementation * we need to distinguish between them * @param _amount the quantity that is expected to be allowed * @param _permitData the raw data of the call `permit` of the token */ function _permit(uint256 _amount, bytes calldata _permitData) internal returns (bool success, bytes memory returndata) { bytes4 sig = getSelector(_permitData); if (sig == _PERMIT_SIGNATURE) { ( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) = abi.decode( _permitData[4:], ( address, address, uint256, uint256, uint8, bytes32, bytes32 ) ); require( owner == msg.sender, "UnipoolTokenDistributor: OWNER_NOT_EQUAL_SENDER" ); require( spender == address(this), "UnipoolTokenDistributor: SPENDER_NOT_EQUAL_THIS" ); require(value == _amount, "UnipoolTokenDistributor: WRONG_AMOUNT"); /* solhint-disable avoid-low-level-calls avoid-call-value */ return address(uni).call( abi.encodeWithSelector( _PERMIT_SIGNATURE, owner, spender, value, deadline, v, r, s ) ); } else if (sig == _PERMIT_SIGNATURE_BRIDGE) { ( address _holder, address _spender, uint256 _nonce, uint256 _expiry, bool _allowed, uint8 v, bytes32 r, bytes32 s ) = abi.decode( _permitData[4:], ( address, address, uint256, uint256, bool, uint8, bytes32, bytes32 ) ); require( _holder == msg.sender, "UnipoolTokenDistributor: OWNER_NOT_EQUAL_SENDER" ); require( _spender == address(this), "UnipoolTokenDistributor: SPENDER_NOT_EQUAL_THIS" ); return address(uni).call( abi.encodeWithSelector( _PERMIT_SIGNATURE_BRIDGE, _holder, _spender, _nonce, _expiry, _allowed, v, r, s ) ); } else { revert("UnipoolTokenDistributor: NOT_VALID_CALL_SIGNATURE"); } } /// @dev Internal method that returns the current block timestamp /// We expect this function call to be optimized away /// Mock implementations can override this to set a fixed block timestamp value /// @return The current block timestamp function _getBlockTimestamp() internal view virtual returns (uint256) { return block.timestamp; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"_uni","type":"address"}],"name":"__LPTokenWrapper_initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IDistro","name":"_tokenDistribution","type":"address"},{"internalType":"contract IERC20Upgradeable","name":"_uni","type":"address"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardDistribution","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardDistribution","type":"address"}],"name":"setRewardDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"permit","type":"bytes"}],"name":"stakeWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenDistro","outputs":[{"internalType":"contract IDistro","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uni","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612584806100206000396000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c806371cc29e5116100f9578063ca8af4d411610097578063e9fad8ee11610071578063e9fad8ee146103af578063ebe2b12b146103b7578063edc9af95146103c0578063f2fde38b146103e657600080fd5b8063ca8af4d41461037e578063cd3daf9d1461039e578063df136d65146103a657600080fd5b80638b876347116100d35780638b876347146103245780638da5cb5b14610344578063a694fc3a14610362578063c8f33c911461037557600080fd5b806371cc29e5146103005780637b0a47ee1461031357806380faa57d1461031c57600080fd5b806318160ddd116101665780633d18b912116101405780633d18b912146102a7578063478f4d02146102af57806370a08231146102c2578063715018a6146102f857600080fd5b806318160ddd146102795780632e1a7d4d146102815780633c6b16ab1461029457600080fd5b80630fb5a6b4116101975780630fb5a6b414610218578063101114cf146102215780631794bb3c1461026657600080fd5b80628cc262146101bd5780630700037d146101e35780630d68b76114610203575b600080fd5b6101d06101cb366004612186565b6103f9565b6040519081526020015b60405180910390f35b6101d06101f1366004612186565b606f6020526000908152604090205481565b610216610211366004612186565b610492565b005b6101d060685481565b6069546102419073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6102166102743660046122af565b61055f565b6001546101d0565b61021661028f3660046122f0565b6106d8565b6102166102a23660046122f0565b6107fa565b6102166109df565b6102166102bd366004612186565b610b41565b6101d06102d0366004612186565b73ffffffffffffffffffffffffffffffffffffffff1660009081526002602052604090205490565b610216610c9c565b61021661030e366004612309565b610d29565b6101d0606b5481565b6101d0610e59565b6101d0610332366004612186565b606e6020526000908152604090205481565b60355473ffffffffffffffffffffffffffffffffffffffff16610241565b6102166103703660046122f0565b610e6c565b6101d0606c5481565b6067546102419073ffffffffffffffffffffffffffffffffffffffff1681565b6101d0610f86565b6101d0606d5481565b610216610fd4565b6101d0606a5481565b6000546102419062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6102166103f4366004612186565b610ff5565b73ffffffffffffffffffffffffffffffffffffffff81166000908152606f6020908152604080832054606e90925282205461048c919061048690670de0b6b3a764000090610480906104539061044d610f86565b90611125565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600260205260409020545b90611138565b90611144565b90611150565b92915050565b60355473ffffffffffffffffffffffffffffffffffffffff163314610518576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b606980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600054610100900460ff1680610578575060005460ff16155b610604576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff1615801561064357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61064b61115c565b61065483610b41565b606780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861617905560688290556000606a819055606b5580156106d257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b336106e1610f86565b606d556106ec610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff81161561074d57610714816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b600082116107b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015260640161050f565b6107c082611281565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020015b60405180910390a25050565b60695473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616c6c6572206973206e6f742072657761726420646973747269627574696f60448201527f6e00000000000000000000000000000000000000000000000000000000000000606482015260840161050f565b60006108c1610f86565b606d556108cc610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff81161561092d576108f4816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b606a544290811061094e57606854610946908490611144565b606b55610991565b606a5460009061095e9083611125565b90506000610977606b548361113890919063ffffffff16565b60685490915061098b906104808784611150565b606b5550505b606c8190556068546109a4908290611150565b606a556040518381527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1505050565b336109e8610f86565b606d556109f3610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff811615610a5457610a1b816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b6000610a5f336103f9565b90508015610b3d57336000818152606f60205260408082209190915560675490517f6ca163de0000000000000000000000000000000000000000000000000000000081526004810192909252602482018390526001604483015273ffffffffffffffffffffffffffffffffffffffff1690636ca163de90606401600060405180830381600087803b158015610af357600080fd5b505af1158015610b07573d6000803e3d6000fd5b50506040518381523392507fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048691506020016107ee565b5050565b600054610100900460ff1680610b5a575060005460ff16155b610be6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff16158015610c2557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166201000073ffffffffffffffffffffffffffffffffffffffff8516021790558015610b3d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b60355473ffffffffffffffffffffffffffffffffffffffff163314610d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050f565b610d2760006112e8565b565b33610d32610f86565b606d55610d3d610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff811615610d9e57610d65816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b60008411610e08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015260640161050f565b610e1384848461135f565b5050610e1e84611abd565b60405184815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d9060200160405180910390a250505050565b6000610e6742606a54611b25565b905090565b33610e75610f86565b606d55610e80610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff811615610ee157610ea8816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b60008211610f4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015260640161050f565b610f5482611abd565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016107ee565b6000610f9160015490565b610f9c5750606d5490565b610e67610fcb610fab60015490565b610480670de0b6b3a764000061047a606b5461047a606c5461044d610e59565b606d5490611150565b33600090815260026020526040902054610fed906106d8565b610d276109df565b60355473ffffffffffffffffffffffffffffffffffffffff163314611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050f565b73ffffffffffffffffffffffffffffffffffffffff8116611119576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050f565b611122816112e8565b50565b600061113182846124ac565b9392505050565b6000611131828461246f565b60006111318284612434565b6000611131828461241c565b600054610100900460ff1680611175575060005460ff16155b611201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff1615801561124057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611248611b3b565b611250611c4f565b801561112257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b60015461128e9082611125565b600155336000908152600260205260409020546112ab9082611125565b336000818152600260205260408120929092559054611122916201000090910473ffffffffffffffffffffffffffffffffffffffff169083611d3c565b6035805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000606060006113a485858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e1592505050565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167fd505accf0000000000000000000000000000000000000000000000000000000014156117265760008080808080806114058b6004818f6123f2565b8101906114129190612224565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16146114db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a204f574e45525f4e60448201527f4f545f455155414c5f53454e4445520000000000000000000000000000000000606482015260840161050f565b73ffffffffffffffffffffffffffffffffffffffff86163014611580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a205350454e44455260448201527f5f4e4f545f455155414c5f544849530000000000000000000000000000000000606482015260840161050f565b8c851461160f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f556e69706f6f6c546f6b656e4469737472696275746f723a2057524f4e475f4160448201527f4d4f554e54000000000000000000000000000000000000000000000000000000606482015260840161050f565b6000546040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905260ff871660a483015260c4820186905260e48083018690528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf00000000000000000000000000000000000000000000000000000000179052915162010000909304909116916116d29190612385565b6000604051808303816000865af19150503d806000811461170f576040519150601f19603f3d011682016040523d82523d6000602084013e611714565b606091505b50995099505050505050505050611ab5565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c000000000000000000000000000000000000000000000000000000001415611a2d576000806000806000806000808c8c600490809261178f939291906123f2565b81019061179c91906121a3565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a204f574e45525f4e60448201527f4f545f455155414c5f53454e4445520000000000000000000000000000000000606482015260840161050f565b73ffffffffffffffffffffffffffffffffffffffff8716301461190c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a205350454e44455260448201527f5f4e4f545f455155414c5f544849530000000000000000000000000000000000606482015260840161050f565b6000546040805173ffffffffffffffffffffffffffffffffffffffff8b811660248301528a81166044830152606482018a90526084820189905287151560a483015260ff871660c483015260e482018690526101048083018690528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c00000000000000000000000000000000000000000000000000000000179052915162010000909304909116916119d89190612385565b6000604051808303816000865af19150503d8060008114611a15576040519150601f19603f3d011682016040523d82523d6000602084013e611a1a565b606091505b509a509a50505050505050505050611ab5565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f556e69706f6f6c546f6b656e4469737472696275746f723a204e4f545f56414c60448201527f49445f43414c4c5f5349474e4154555245000000000000000000000000000000606482015260840161050f565b935093915050565b600154611aca9082611150565b60015533600090815260026020526040902054611ae79082611150565b336000818152600260205260408120929092559054611122916201000090910473ffffffffffffffffffffffffffffffffffffffff16903084611e1c565b6000818310611b345781611131565b5090919050565b600054610100900460ff1680611b54575060005460ff16155b611be0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff1615801561125057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016610101179055801561112257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680611c68575060005460ff16155b611cf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff16158015611d3357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611250336112e8565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052611e109084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e7a565b505050565b6020015190565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526106d29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611d8e565b6000611edc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611f869092919063ffffffff16565b805190915015611e105780806020019051810190611efa9190612292565b611e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161050f565b6060611f958484600085611f9d565b949350505050565b60608247101561202f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161050f565b843b612097576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161050f565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516120c09190612385565b60006040518083038185875af1925050503d80600081146120fd576040519150601f19603f3d011682016040523d82523d6000602084013e612102565b606091505b509150915061211282828661211d565b979650505050505050565b6060831561212c575081611131565b82511561213c5782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050f91906123a1565b803560ff8116811461218157600080fd5b919050565b60006020828403121561219857600080fd5b81356111318161251e565b600080600080600080600080610100898b0312156121c057600080fd5b88356121cb8161251e565b975060208901356121db8161251e565b9650604089013595506060890135945060808901356121f981612540565b935061220760a08a01612170565b925060c0890135915060e089013590509295985092959890939650565b600080600080600080600060e0888a03121561223f57600080fd5b873561224a8161251e565b9650602088013561225a8161251e565b9550604088013594506060880135935061227660808901612170565b925060a0880135915060c0880135905092959891949750929550565b6000602082840312156122a457600080fd5b815161113181612540565b6000806000606084860312156122c457600080fd5b83356122cf8161251e565b925060208401356122df8161251e565b929592945050506040919091013590565b60006020828403121561230257600080fd5b5035919050565b60008060006040848603121561231e57600080fd5b83359250602084013567ffffffffffffffff8082111561233d57600080fd5b818601915086601f83011261235157600080fd5b81358181111561236057600080fd5b87602082850101111561237257600080fd5b6020830194508093505050509250925092565b600082516123978184602087016124c3565b9190910192915050565b60208152600082518060208401526123c08160408501602087016124c3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000808585111561240257600080fd5b8386111561240f57600080fd5b5050820193919092039150565b6000821982111561242f5761242f6124ef565b500190565b60008261246a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156124a7576124a76124ef565b500290565b6000828210156124be576124be6124ef565b500390565b60005b838110156124de5781810151838201526020016124c6565b838111156106d25750506000910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461112257600080fd5b801515811461112257600080fdfea2646970667358221220f0a05122555cd84465c95771b2e8bc7d34005c6c22e54efa3cd9c7fa6d97c9ec64736f6c63430008060033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101b85760003560e01c806371cc29e5116100f9578063ca8af4d411610097578063e9fad8ee11610071578063e9fad8ee146103af578063ebe2b12b146103b7578063edc9af95146103c0578063f2fde38b146103e657600080fd5b8063ca8af4d41461037e578063cd3daf9d1461039e578063df136d65146103a657600080fd5b80638b876347116100d35780638b876347146103245780638da5cb5b14610344578063a694fc3a14610362578063c8f33c911461037557600080fd5b806371cc29e5146103005780637b0a47ee1461031357806380faa57d1461031c57600080fd5b806318160ddd116101665780633d18b912116101405780633d18b912146102a7578063478f4d02146102af57806370a08231146102c2578063715018a6146102f857600080fd5b806318160ddd146102795780632e1a7d4d146102815780633c6b16ab1461029457600080fd5b80630fb5a6b4116101975780630fb5a6b414610218578063101114cf146102215780631794bb3c1461026657600080fd5b80628cc262146101bd5780630700037d146101e35780630d68b76114610203575b600080fd5b6101d06101cb366004612186565b6103f9565b6040519081526020015b60405180910390f35b6101d06101f1366004612186565b606f6020526000908152604090205481565b610216610211366004612186565b610492565b005b6101d060685481565b6069546102419073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101da565b6102166102743660046122af565b61055f565b6001546101d0565b61021661028f3660046122f0565b6106d8565b6102166102a23660046122f0565b6107fa565b6102166109df565b6102166102bd366004612186565b610b41565b6101d06102d0366004612186565b73ffffffffffffffffffffffffffffffffffffffff1660009081526002602052604090205490565b610216610c9c565b61021661030e366004612309565b610d29565b6101d0606b5481565b6101d0610e59565b6101d0610332366004612186565b606e6020526000908152604090205481565b60355473ffffffffffffffffffffffffffffffffffffffff16610241565b6102166103703660046122f0565b610e6c565b6101d0606c5481565b6067546102419073ffffffffffffffffffffffffffffffffffffffff1681565b6101d0610f86565b6101d0606d5481565b610216610fd4565b6101d0606a5481565b6000546102419062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6102166103f4366004612186565b610ff5565b73ffffffffffffffffffffffffffffffffffffffff81166000908152606f6020908152604080832054606e90925282205461048c919061048690670de0b6b3a764000090610480906104539061044d610f86565b90611125565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600260205260409020545b90611138565b90611144565b90611150565b92915050565b60355473ffffffffffffffffffffffffffffffffffffffff163314610518576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b606980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600054610100900460ff1680610578575060005460ff16155b610604576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff1615801561064357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61064b61115c565b61065483610b41565b606780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861617905560688290556000606a819055606b5580156106d257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b336106e1610f86565b606d556106ec610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff81161561074d57610714816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b600082116107b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015260640161050f565b6107c082611281565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020015b60405180910390a25050565b60695473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616c6c6572206973206e6f742072657761726420646973747269627574696f60448201527f6e00000000000000000000000000000000000000000000000000000000000000606482015260840161050f565b60006108c1610f86565b606d556108cc610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff81161561092d576108f4816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b606a544290811061094e57606854610946908490611144565b606b55610991565b606a5460009061095e9083611125565b90506000610977606b548361113890919063ffffffff16565b60685490915061098b906104808784611150565b606b5550505b606c8190556068546109a4908290611150565b606a556040518381527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1505050565b336109e8610f86565b606d556109f3610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff811615610a5457610a1b816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b6000610a5f336103f9565b90508015610b3d57336000818152606f60205260408082209190915560675490517f6ca163de0000000000000000000000000000000000000000000000000000000081526004810192909252602482018390526001604483015273ffffffffffffffffffffffffffffffffffffffff1690636ca163de90606401600060405180830381600087803b158015610af357600080fd5b505af1158015610b07573d6000803e3d6000fd5b50506040518381523392507fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048691506020016107ee565b5050565b600054610100900460ff1680610b5a575060005460ff16155b610be6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff16158015610c2557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166201000073ffffffffffffffffffffffffffffffffffffffff8516021790558015610b3d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b60355473ffffffffffffffffffffffffffffffffffffffff163314610d1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050f565b610d2760006112e8565b565b33610d32610f86565b606d55610d3d610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff811615610d9e57610d65816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b60008411610e08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015260640161050f565b610e1384848461135f565b5050610e1e84611abd565b60405184815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d9060200160405180910390a250505050565b6000610e6742606a54611b25565b905090565b33610e75610f86565b606d55610e80610e59565b606c5573ffffffffffffffffffffffffffffffffffffffff811615610ee157610ea8816103f9565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606f6020908152604080832093909355606d54606e909152919020555b60008211610f4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015260640161050f565b610f5482611abd565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016107ee565b6000610f9160015490565b610f9c5750606d5490565b610e67610fcb610fab60015490565b610480670de0b6b3a764000061047a606b5461047a606c5461044d610e59565b606d5490611150565b33600090815260026020526040902054610fed906106d8565b610d276109df565b60355473ffffffffffffffffffffffffffffffffffffffff163314611076576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050f565b73ffffffffffffffffffffffffffffffffffffffff8116611119576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050f565b611122816112e8565b50565b600061113182846124ac565b9392505050565b6000611131828461246f565b60006111318284612434565b6000611131828461241c565b600054610100900460ff1680611175575060005460ff16155b611201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff1615801561124057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611248611b3b565b611250611c4f565b801561112257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b60015461128e9082611125565b600155336000908152600260205260409020546112ab9082611125565b336000818152600260205260408120929092559054611122916201000090910473ffffffffffffffffffffffffffffffffffffffff169083611d3c565b6035805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000606060006113a485858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e1592505050565b90507fffffffff0000000000000000000000000000000000000000000000000000000081167fd505accf0000000000000000000000000000000000000000000000000000000014156117265760008080808080806114058b6004818f6123f2565b8101906114129190612224565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16146114db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a204f574e45525f4e60448201527f4f545f455155414c5f53454e4445520000000000000000000000000000000000606482015260840161050f565b73ffffffffffffffffffffffffffffffffffffffff86163014611580576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a205350454e44455260448201527f5f4e4f545f455155414c5f544849530000000000000000000000000000000000606482015260840161050f565b8c851461160f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f556e69706f6f6c546f6b656e4469737472696275746f723a2057524f4e475f4160448201527f4d4f554e54000000000000000000000000000000000000000000000000000000606482015260840161050f565b6000546040805173ffffffffffffffffffffffffffffffffffffffff8a811660248301528981166044830152606482018990526084820188905260ff871660a483015260c4820186905260e48083018690528351808403909101815261010490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fd505accf00000000000000000000000000000000000000000000000000000000179052915162010000909304909116916116d29190612385565b6000604051808303816000865af19150503d806000811461170f576040519150601f19603f3d011682016040523d82523d6000602084013e611714565b606091505b50995099505050505050505050611ab5565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f8fcbaf0c000000000000000000000000000000000000000000000000000000001415611a2d576000806000806000806000808c8c600490809261178f939291906123f2565b81019061179c91906121a3565b975097509750975097509750975097503373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614611867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a204f574e45525f4e60448201527f4f545f455155414c5f53454e4445520000000000000000000000000000000000606482015260840161050f565b73ffffffffffffffffffffffffffffffffffffffff8716301461190c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f556e69706f6f6c546f6b656e4469737472696275746f723a205350454e44455260448201527f5f4e4f545f455155414c5f544849530000000000000000000000000000000000606482015260840161050f565b6000546040805173ffffffffffffffffffffffffffffffffffffffff8b811660248301528a81166044830152606482018a90526084820189905287151560a483015260ff871660c483015260e482018690526101048083018690528351808403909101815261012490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8fcbaf0c00000000000000000000000000000000000000000000000000000000179052915162010000909304909116916119d89190612385565b6000604051808303816000865af19150503d8060008114611a15576040519150601f19603f3d011682016040523d82523d6000602084013e611a1a565b606091505b509a509a50505050505050505050611ab5565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f556e69706f6f6c546f6b656e4469737472696275746f723a204e4f545f56414c60448201527f49445f43414c4c5f5349474e4154555245000000000000000000000000000000606482015260840161050f565b935093915050565b600154611aca9082611150565b60015533600090815260026020526040902054611ae79082611150565b336000818152600260205260408120929092559054611122916201000090910473ffffffffffffffffffffffffffffffffffffffff16903084611e1c565b6000818310611b345781611131565b5090919050565b600054610100900460ff1680611b54575060005460ff16155b611be0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff1615801561125057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016610101179055801561112257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680611c68575060005460ff16155b611cf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050f565b600054610100900460ff16158015611d3357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611250336112e8565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052611e109084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e7a565b505050565b6020015190565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526106d29085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611d8e565b6000611edc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611f869092919063ffffffff16565b805190915015611e105780806020019051810190611efa9190612292565b611e10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161050f565b6060611f958484600085611f9d565b949350505050565b60608247101561202f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161050f565b843b612097576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161050f565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516120c09190612385565b60006040518083038185875af1925050503d80600081146120fd576040519150601f19603f3d011682016040523d82523d6000602084013e612102565b606091505b509150915061211282828661211d565b979650505050505050565b6060831561212c575081611131565b82511561213c5782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050f91906123a1565b803560ff8116811461218157600080fd5b919050565b60006020828403121561219857600080fd5b81356111318161251e565b600080600080600080600080610100898b0312156121c057600080fd5b88356121cb8161251e565b975060208901356121db8161251e565b9650604089013595506060890135945060808901356121f981612540565b935061220760a08a01612170565b925060c0890135915060e089013590509295985092959890939650565b600080600080600080600060e0888a03121561223f57600080fd5b873561224a8161251e565b9650602088013561225a8161251e565b9550604088013594506060880135935061227660808901612170565b925060a0880135915060c0880135905092959891949750929550565b6000602082840312156122a457600080fd5b815161113181612540565b6000806000606084860312156122c457600080fd5b83356122cf8161251e565b925060208401356122df8161251e565b929592945050506040919091013590565b60006020828403121561230257600080fd5b5035919050565b60008060006040848603121561231e57600080fd5b83359250602084013567ffffffffffffffff8082111561233d57600080fd5b818601915086601f83011261235157600080fd5b81358181111561236057600080fd5b87602082850101111561237257600080fd5b6020830194508093505050509250925092565b600082516123978184602087016124c3565b9190910192915050565b60208152600082518060208401526123c08160408501602087016124c3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000808585111561240257600080fd5b8386111561240f57600080fd5b5050820193919092039150565b6000821982111561242f5761242f6124ef565b500190565b60008261246a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156124a7576124a76124ef565b500290565b6000828210156124be576124be6124ef565b500390565b60005b838110156124de5781810151838201526020016124c6565b838111156106d25750506000910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461112257600080fd5b801515811461112257600080fdfea2646970667358221220f0a05122555cd84465c95771b2e8bc7d34005c6c22e54efa3cd9c7fa6d97c9ec64736f6c63430008060033
Deployed Bytecode Sourcemap
33823:9766:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36505:265;;;;;;:::i;:::-;;:::i;:::-;;;13227:25:1;;;13215:2;13200:18;36505:265:0;;;;;;;;34315:42;;;;;;:::i;:::-;;;;;;;;;;;;;;38379:161;;;;;;:::i;:::-;;:::i;:::-;;34035:23;;;;;;34067:33;;;;;;;;;;;;4405:42:1;4393:55;;;4375:74;;4363:2;4348:18;34067:33:0;4330:125:1;35565:349:0;;;;;;:::i;:::-;;:::i;33131:91::-;33202:12;;33131:91;;37069:212;;;;;;:::i;:::-;;:::i;37751:620::-;;;;;;:::i;:::-;;:::i;37394:349::-;;;:::i;32991:132::-;;;;;;:::i;:::-;;:::i;33230:110::-;;;;;;:::i;:::-;33314:18;;33287:7;33314:18;;;:9;:18;;;;;;;33230:110;31408:94;;;:::i;38812:528::-;;;;;;:::i;:::-;;:::i;34141:25::-;;;;;;35922:147;;;:::i;34251:57::-;;;;;;:::i;:::-;;;;;;;;;;;;;;30757:87;30830:6;;;;30757:87;;36861:200;;;;;;:::i;:::-;;:::i;34173:29::-;;;;;;34002:26;;;;;;;;;36077:420;;;:::i;34209:35::-;;;;;;37289:97;;;:::i;34107:27::-;;;;;;32865:28;;;;;;;;;;;;31657:192;;;;;;:::i;:::-;;:::i;36505:265::-;36745:16;;;36559:7;36745:16;;;:7;:16;;;;;;;;;36661:22;:31;;;;;;36599:163;;36745:16;36599:123;;36717:4;;36599:95;;36640:53;;:16;:14;:16::i;:::-;:20;;:53::i;:::-;33314:18;;;33287:7;33314:18;;;:9;:18;;;;;;36599;:40;;:95::i;:::-;:117;;:123::i;:::-;:145;;:163::i;:::-;36579:183;36505:265;-1:-1:-1;;36505:265:0:o;38379:161::-;30830:6;;30977:23;30830:6;29350:10;30977:23;30969:68;;;;;;;10919:2:1;30969:68:0;;;10901:21:1;;;10938:18;;;10931:30;10997:34;10977:18;;;10970:62;11049:18;;30969:68:0;;;;;;;;;38492:18:::1;:40:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;38379:161::o;35565:349::-;28070:13;;;;;;;;:30;;-1:-1:-1;28088:12:0;;;;28087:13;28070:30;28062:89;;;;;;;9740:2:1;28062:89:0;;;9722:21:1;9779:2;9759:18;;;9752:30;9818:34;9798:18;;;9791:62;9889:16;9869:18;;;9862:44;9923:19;;28062:89:0;9712:236:1;28062:89:0;28164:19;28187:13;;;;;;28186:14;28211:101;;;;28246:13;:20;;28281:19;;;;;;28211:101;35720:16:::1;:14;:16::i;:::-;35747:33;35775:4;35747:27;:33::i;:::-;35791:11;:32:::0;;;::::1;;::::0;::::1;;::::0;;35834:8:::1;:20:::0;;;-1:-1:-1;35865:12:0::1;:16:::0;;;35892:10:::1;:14:::0;28338:68;;;;28389:5;28373:21;;;;;;28338:68;28051:362;35565:349;;;:::o;37069:212::-;37132:10;35300:16;:14;:16::i;:::-;35277:20;:39;35344:26;:24;:26::i;:::-;35327:14;:43;35385:21;;;;35381:157;;35442:15;35449:7;35442:6;:15::i;:::-;35423:16;;;;;;;:7;:16;;;;;;;;:34;;;;35506:20;;35472:22;:31;;;;;;:54;35381:157;37172:1:::1;37163:6;:10;37155:40;;;::::0;::::1;::::0;;10573:2:1;37155:40:0::1;::::0;::::1;10555:21:1::0;10612:2;10592:18;;;10585:30;10651:19;10631:18;;;10624:47;10688:18;;37155:40:0::1;10545:167:1::0;37155:40:0::1;37206:22;37221:6;37206:14;:22::i;:::-;37244:29;::::0;13227:25:1;;;37254:10:0::1;::::0;37244:29:::1;::::0;13215:2:1;13200:18;37244:29:0::1;;;;;;;;37069:212:::0;;:::o;37751:620::-;35120:18;;;;29350:10;35104:34;;;35082:117;;;;;;;11696:2:1;35082:117:0;;;11678:21:1;11735:2;11715:18;;;11708:30;11774:34;11754:18;;;11747:62;11845:3;11825:18;;;11818:31;11866:19;;35082:117:0;11668:223:1;35082:117:0;37875:1:::1;35300:16;:14;:16::i;:::-;35277:20;:39:::0;35344:26:::1;:24;:26::i;:::-;35327:14;:43:::0;35385:21:::1;::::0;::::1;::::0;35381:157:::1;;35442:15;35449:7;35442:6;:15::i;:::-;35423:16;::::0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;35506:20:::1;::::0;35472:22:::1;:31:::0;;;;;;:54;35381:157:::1;37965:12:::2;::::0;43563:15;;37951:26;::::2;37947:294;;38018:8;::::0;38007:20:::2;::::0;:6;;:10:::2;:20::i;:::-;37994:10;:33:::0;37947:294:::2;;;38080:12;::::0;38060:17:::2;::::0;38080:28:::2;::::0;38097:10;38080:16:::2;:28::i;:::-;38060:48;;38123:16;38142:25;38156:10;;38142:9;:13;;:25;;;;:::i;:::-;38220:8;::::0;38123:44;;-1:-1:-1;38195:34:0::2;::::0;:20:::2;:6:::0;38123:44;38195:10:::2;:20::i;:34::-;38182:10;:47:::0;-1:-1:-1;;37947:294:0::2;38251:14;:27:::0;;;38319:8:::2;::::0;38304:24:::2;::::0;38268:10;;38304:14:::2;:24::i;:::-;38289:12;:39:::0;38344:19:::2;::::0;13227:25:1;;;38344:19:0::2;::::0;13215:2:1;13200:18;38344:19:0::2;;;;;;;37884:487;35210:1:::1;37751:620:::0;:::o;37394:349::-;37435:10;35300:16;:14;:16::i;:::-;35277:20;:39;35344:26;:24;:26::i;:::-;35327:14;:43;35385:21;;;;35381:157;;35442:15;35449:7;35442:6;:15::i;:::-;35423:16;;;;;;;:7;:16;;;;;;;;:34;;;;35506:20;;35472:22;:31;;;;;;:54;35381:157;37458:14:::1;37475:18;37482:10;37475:6;:18::i;:::-;37458:35:::0;-1:-1:-1;37508:10:0;;37504:232:::1;;37543:10;37557:1;37535:19:::0;;;:7:::1;:19;::::0;;;;;:23;;;;37628:11:::1;::::0;:46;;;;;::::1;::::0;::::1;6839:74:1::0;;;;6929:18;;;6922:34;;;37628:11:0;6972:18:1;;;6965:50;37535:19:0::1;37628:11;::::0;:20:::1;::::0;6812:18:1;;37628:46:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;37694:30:0::1;::::0;13227:25:1;;;37705:10:0::1;::::0;-1:-1:-1;37694:30:0::1;::::0;-1:-1:-1;13215:2:1;13200:18;37694:30:0::1;13182:76:1::0;37504:232:0::1;37447:296;37394:349:::0;:::o;32991:132::-;28070:13;;;;;;;;:30;;-1:-1:-1;28088:12:0;;;;28087:13;28070:30;28062:89;;;;;;;9740:2:1;28062:89:0;;;9722:21:1;9779:2;9759:18;;;9752:30;9818:34;9798:18;;;9791:62;9889:16;9869:18;;;9862:44;9923:19;;28062:89:0;9712:236:1;28062:89:0;28164:19;28187:13;;;;;;28186:14;28211:101;;;;28246:13;:20;;28281:19;;;;;;28211:101;33105:3:::1;:10:::0;;;::::1;::::0;::::1;::::0;::::1;;;::::0;;28338:68;;;;28389:5;28373:21;;;;;;28051:362;32991:132;:::o;31408:94::-;30830:6;;30977:23;30830:6;29350:10;30977:23;30969:68;;;;;;;10919:2:1;30969:68:0;;;10901:21:1;;;10938:18;;;10931:30;10997:34;10977:18;;;10970:62;11049:18;;30969:68:0;10891:182:1;30969:68:0;31473:21:::1;31491:1;31473:9;:21::i;:::-;31408:94::o:0;38812:528::-;38914:10;35300:16;:14;:16::i;:::-;35277:20;:39;35344:26;:24;:26::i;:::-;35327:14;:43;35385:21;;;;35381:157;;35442:15;35449:7;35442:6;:15::i;:::-;35423:16;;;;;;;:7;:16;;;;;;;;:34;;;;35506:20;;35472:22;:31;;;;;;:54;35381:157;38959:1:::1;38950:6;:10;38942:37;;;::::0;::::1;::::0;;8990:2:1;38942:37:0::1;::::0;::::1;8972:21:1::0;9029:2;9009:18;;;9002:30;9068:16;9048:18;;;9041:44;9102:18;;38942:37:0::1;8962:164:1::0;38942:37:0::1;39237:23;39245:6;39253;;39237:7;:23::i;:::-;;;39271:19;39283:6;39271:11;:19::i;:::-;39306:26;::::0;13227:25:1;;;39313:10:0::1;::::0;39306:26:::1;::::0;13215:2:1;13200:18;39306:26:0::1;;;;;;;38812:528:::0;;;;:::o;35922:147::-;35979:7;36006:55;43563:15;36048:12;;36006:19;:55::i;:::-;35999:62;;35922:147;:::o;36861:200::-;36921:10;35300:16;:14;:16::i;:::-;35277:20;:39;35344:26;:24;:26::i;:::-;35327:14;:43;35385:21;;;;35381:157;;35442:15;35449:7;35442:6;:15::i;:::-;35423:16;;;;;;;:7;:16;;;;;;;;:34;;;;35506:20;;35472:22;:31;;;;;;:54;35381:157;36961:1:::1;36952:6;:10;36944:37;;;::::0;::::1;::::0;;8990:2:1;36944:37:0::1;::::0;::::1;8972:21:1::0;9029:2;9009:18;;;9002:30;9068:16;9048:18;;;9041:44;9102:18;;36944:37:0::1;8962:164:1::0;36944:37:0::1;36992:19;37004:6;36992:11;:19::i;:::-;37027:26;::::0;13227:25:1;;;37034:10:0::1;::::0;37027:26:::1;::::0;13215:2:1;13200:18;37027:26:0::1;13182:76:1::0;36077:420:0;36124:7;36148:13;33202:12;;;33131:91;36148:13;36144:78;;-1:-1:-1;36190:20:0;;;36077:420::o;36144:78::-;36252:237;36295:179;36460:13;33202:12;;;33131:91;36460:13;36295:138;36428:4;36295:106;36390:10;;36295:68;36348:14;;36295:26;:24;:26::i;:179::-;36252:20;;;:24;:237::i;37289:97::-;37344:10;33287:7;33314:18;;;:9;:18;;;;;;37325:31;;37069:212;:::i;37325:31::-;37367:11;:9;:11::i;31657:192::-;30830:6;;30977:23;30830:6;29350:10;30977:23;30969:68;;;;;;;10919:2:1;30969:68:0;;;10901:21:1;;;10938:18;;;10931:30;10997:34;10977:18;;;10970:62;11049:18;;30969:68:0;10891:182:1;30969:68:0;31746:22:::1;::::0;::::1;31738:73;;;::::0;::::1;::::0;;8583:2:1;31738:73:0::1;::::0;::::1;8565:21:1::0;8622:2;8602:18;;;8595:30;8661:34;8641:18;;;8634:62;8732:8;8712:18;;;8705:36;8758:19;;31738:73:0::1;8555:228:1::0;31738:73:0::1;31822:19;31832:8;31822:9;:19::i;:::-;31657:192:::0;:::o;21537:98::-;21595:7;21622:5;21626:1;21622;:5;:::i;:::-;21615:12;21537:98;-1:-1:-1;;;21537:98:0:o;21894:::-;21952:7;21979:5;21983:1;21979;:5;:::i;22293:98::-;22351:7;22378:5;22382:1;22378;:5;:::i;21156:98::-;21214:7;21241:5;21245:1;21241;:5;:::i;30440:129::-;28070:13;;;;;;;;:30;;-1:-1:-1;28088:12:0;;;;28087:13;28070:30;28062:89;;;;;;;9740:2:1;28062:89:0;;;9722:21:1;9779:2;9759:18;;;9752:30;9818:34;9798:18;;;9791:62;9889:16;9869:18;;;9862:44;9923:19;;28062:89:0;9712:236:1;28062:89:0;28164:19;28187:13;;;;;;28186:14;28211:101;;;;28246:13;:20;;28281:19;;;;;;28211:101;30498:26:::1;:24;:26::i;:::-;30535;:24;:26::i;:::-;28342:14:::0;28338:68;;;28389:5;28373:21;;;;;;28051:362;30440:129::o;33594:222::-;33669:12;;:24;;33686:6;33669:16;:24::i;:::-;33654:12;:39;33738:10;33728:21;;;;:9;:21;;;;;;:33;;33754:6;33728:25;:33::i;:::-;33714:10;33704:21;;;;:9;:21;;;;;:57;;;;33772:3;;:36;;:3;;;;33704:21;33772:3;;33801:6;33772:16;:36::i;31857:173::-;31932:6;;;;31949:17;;;;;;;;;;;31982:40;;31932:6;;;31949:17;31932:6;;31982:40;;31913:16;;31982:40;31902:128;31857:173;:::o;39953:3254::-;40051:12;40065:23;40106:10;40119:24;40131:11;;40119:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40119:11:0;;-1:-1:-1;;;40119:24:0:i;:::-;40106:37;-1:-1:-1;40160:24:0;;;40167:17;40160:24;40156:3044;;;40220:13;;;;;;;40467:15;:11;40479:1;40467:11;;:15;:::i;:::-;40434:349;;;;;;;:::i;:::-;40201:582;;;;;;;;;;;;;;40833:10;40824:19;;:5;:19;;;40798:128;;;;;;;11280:2:1;40798:128:0;;;11262:21:1;11319:2;11299:18;;;11292:30;11358:34;11338:18;;;11331:62;11429:17;11409:18;;;11402:45;11464:19;;40798:128:0;11252:237:1;40798:128:0;40967:24;;;40986:4;40967:24;40941:133;;;;;;;12867:2:1;40941:133:0;;;12849:21:1;12906:2;12886:18;;;12879:30;12945:34;12925:18;;;12918:62;13016:17;12996:18;;;12989:45;13051:19;;40941:133:0;12839:237:1;40941:133:0;41106:7;41097:5;:16;41089:66;;;;;;;8177:2:1;41089:66:0;;;8159:21:1;8216:2;8196:18;;;8189:30;8255:34;8235:18;;;8228:62;8326:7;8306:18;;;8299:35;8351:19;;41089:66:0;8149:227:1;41089:66:0;41278:3;;41310:306;;;41278:3;6033:15:1;;;41310:306:0;;;6015:34:1;6085:15;;;6065:18;;;6058:43;6117:18;;;6110:34;;;6160:18;;;6153:34;;;6236:4;6224:17;;6203:19;;;6196:46;6258:19;;;6251:35;;;6302:19;;;;6295:35;;;41310:306:0;;;;;;;;;;5926:19:1;;;;41310:306:0;;;;;;;;;41359:17;41310:306;;;41270:365;;41278:3;;;;;;;;41270:365;;41310:306;41270:365;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41246:389;;;;;;;;;;;;;;40156:3044;41657:31;;;41664:24;41657:31;41653:1547;;;41724:15;41758:16;41793:14;41826:15;41860:13;41892:7;41918:9;41946;42006:11;;42018:1;42006:15;;;;;;;;;:::i;:::-;41973:380;;;;;;;:::i;:::-;41705:648;;;;;;;;;;;;;;;;42405:10;42394:21;;:7;:21;;;42368:130;;;;;;;11280:2:1;42368:130:0;;;11262:21:1;11319:2;11299:18;;;11292:30;11358:34;11338:18;;;11331:62;11429:17;11409:18;;;11402:45;11464:19;;42368:130:0;11252:237:1;42368:130:0;42539:25;;;42559:4;42539:25;42513:134;;;;;;;12867:2:1;42513:134:0;;;12849:21:1;12906:2;12886:18;;;12879:30;12945:34;12925:18;;;12918:62;13016:17;12996:18;;;12989:45;13051:19;;42513:134:0;12839:237:1;42513:134:0;42694:3;;42726:351;;;42694:3;5275:15:1;;;42726:351:0;;;5257:34:1;5327:15;;;5307:18;;;5300:43;5359:18;;;5352:34;;;5402:18;;;5395:34;;;5473:14;;5466:22;5445:19;;;5438:51;5538:4;5526:17;;5505:19;;;5498:46;5560:19;;;5553:35;;;5604:19;;;;5597:35;;;42726:351:0;;;;;;;;;;5168:19:1;;;;42726:351:0;;;;;;;;;42775:24;42726:351;;;42686:410;;42694:3;;;;;;;;42686:410;;42726:351;42686:410;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42662:434;;;;;;;;;;;;;;;41653:1547;43129:59;;;;;10155:2:1;43129:59:0;;;10137:21:1;10194:2;10174:18;;;10167:30;10233:34;10213:18;;;10206:62;10304:19;10284:18;;;10277:47;10341:19;;43129:59:0;10127:239:1;39953:3254:0;;;;;;;:::o;33348:238::-;33420:12;;:24;;33437:6;33420:16;:24::i;:::-;33405:12;:39;33489:10;33479:21;;;;:9;:21;;;;;;:33;;33505:6;33479:25;:33::i;:::-;33465:10;33455:21;;;;:9;:21;;;;;:57;;;;33523:3;;:55;;:3;;;;33455:21;33523:3;;33564:4;33571:6;33523:20;:55::i;25790:106::-;25848:7;25879:1;25875;:5;:13;;25887:1;25875:13;;;-1:-1:-1;25883:1:0;;25790:106;-1:-1:-1;25790:106:0:o;29199:65::-;28070:13;;;;;;;;:30;;-1:-1:-1;28088:12:0;;;;28087:13;28070:30;28062:89;;;;;;;9740:2:1;28062:89:0;;;9722:21:1;9779:2;9759:18;;;9752:30;9818:34;9798:18;;;9791:62;9889:16;9869:18;;;9862:44;9923:19;;28062:89:0;9712:236:1;28062:89:0;28164:19;28187:13;;;;;;28186:14;28211:101;;;;28246:13;:20;;28281:19;;;;;;28338:68;;;;28389:5;28373:21;;;;;;28051:362;29199:65::o;30577:99::-;28070:13;;;;;;;;:30;;-1:-1:-1;28088:12:0;;;;28087:13;28070:30;28062:89;;;;;;;9740:2:1;28062:89:0;;;9722:21:1;9779:2;9759:18;;;9752:30;9818:34;9798:18;;;9791:62;9889:16;9869:18;;;9862:44;9923:19;;28062:89:0;9712:236:1;28062:89:0;28164:19;28187:13;;;;;;28186:14;28211:101;;;;28246:13;:20;;28281:19;;;;;;28211:101;30645:23:::1;29350:10:::0;30645:9:::1;:23::i;14967:222::-:0;15122:58;;6545:42:1;6533:55;;15122:58:0;;;6515:74:1;6605:18;;;6598:34;;;15095:86:0;;15115:5;;15145:23;;6488:18:1;;15122:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15095:19;:86::i;:::-;14967:222;;;:::o;39475:156::-;39609:2;39598:14;39592:21;;39475:156::o;15197:259::-;15379:68;;4672:42:1;4741:15;;;15379:68:0;;;4723:34:1;4793:15;;4773:18;;;4766:43;4825:18;;;4818:34;;;15352:96:0;;15372:5;;15402:27;;4635:18:1;;15379:68:0;4617:241:1;17595:727:0;18030:23;18056:69;18084:4;18056:69;;;;;;;;;;;;;;;;;18064:5;18056:27;;;;:69;;;;;:::i;:::-;18140:17;;18030:95;;-1:-1:-1;18140:21:0;18136:179;;18237:10;18226:30;;;;;;;;;;;;:::i;:::-;18218:85;;;;;;;12456:2:1;18218:85:0;;;12438:21:1;12495:2;12475:18;;;12468:30;12534:34;12514:18;;;12507:62;12605:12;12585:18;;;12578:40;12635:19;;18218:85:0;12428:232:1;7872:229:0;8009:12;8041:52;8063:6;8071:4;8077:1;8080:12;8041:21;:52::i;:::-;8034:59;7872:229;-1:-1:-1;;;;7872:229:0:o;8992:510::-;9162:12;9220:5;9195:21;:30;;9187:81;;;;;;;9333:2:1;9187:81:0;;;9315:21:1;9372:2;9352:18;;;9345:30;9411:34;9391:18;;;9384:62;9482:8;9462:18;;;9455:36;9508:19;;9187:81:0;9305:228:1;9187:81:0;5389:20;;9279:60;;;;;;;12098:2:1;9279:60:0;;;12080:21:1;12137:2;12117:18;;;12110:30;12176:31;12156:18;;;12149:59;12225:18;;9279:60:0;12070:179:1;9279:60:0;9353:12;9367:23;9394:6;:11;;9413:5;9420:4;9394:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9352:73;;;;9443:51;9460:7;9469:10;9481:12;9443:16;:51::i;:::-;9436:58;8992:510;-1:-1:-1;;;;;;;8992:510:0:o;10701:712::-;10851:12;10880:7;10876:530;;;-1:-1:-1;10911:10:0;10904:17;;10876:530;11025:17;;:21;11021:374;;11223:10;11217:17;11284:15;11271:10;11267:2;11263:19;11256:44;11021:374;11366:12;11359:20;;;;;;;;;;;:::i;14:156:1:-;80:20;;140:4;129:16;;119:27;;109:2;;160:1;157;150:12;109:2;61:109;;;:::o;175:247::-;234:6;287:2;275:9;266:7;262:23;258:32;255:2;;;303:1;300;293:12;255:2;342:9;329:23;361:31;386:5;361:31;:::i;427:886::-;560:6;568;576;584;592;600;608;616;669:3;657:9;648:7;644:23;640:33;637:2;;;686:1;683;676:12;637:2;725:9;712:23;744:31;769:5;744:31;:::i;:::-;794:5;-1:-1:-1;851:2:1;836:18;;823:32;864:33;823:32;864:33;:::i;:::-;916:7;-1:-1:-1;970:2:1;955:18;;942:32;;-1:-1:-1;1021:2:1;1006:18;;993:32;;-1:-1:-1;1077:3:1;1062:19;;1049:33;1091:30;1049:33;1091:30;:::i;:::-;1140:7;-1:-1:-1;1166:37:1;1198:3;1183:19;;1166:37;:::i;:::-;1156:47;;1250:3;1239:9;1235:19;1222:33;1212:43;;1302:3;1291:9;1287:19;1274:33;1264:43;;627:686;;;;;;;;;;;:::o;1318:750::-;1445:6;1453;1461;1469;1477;1485;1493;1546:3;1534:9;1525:7;1521:23;1517:33;1514:2;;;1563:1;1560;1553:12;1514:2;1602:9;1589:23;1621:31;1646:5;1621:31;:::i;:::-;1671:5;-1:-1:-1;1728:2:1;1713:18;;1700:32;1741:33;1700:32;1741:33;:::i;:::-;1793:7;-1:-1:-1;1847:2:1;1832:18;;1819:32;;-1:-1:-1;1898:2:1;1883:18;;1870:32;;-1:-1:-1;1921:37:1;1953:3;1938:19;;1921:37;:::i;:::-;1911:47;;2005:3;1994:9;1990:19;1977:33;1967:43;;2057:3;2046:9;2042:19;2029:33;2019:43;;1504:564;;;;;;;;;;:::o;2073:245::-;2140:6;2193:2;2181:9;2172:7;2168:23;2164:32;2161:2;;;2209:1;2206;2199:12;2161:2;2241:9;2235:16;2260:28;2282:5;2260:28;:::i;2323:496::-;2440:6;2448;2456;2509:2;2497:9;2488:7;2484:23;2480:32;2477:2;;;2525:1;2522;2515:12;2477:2;2564:9;2551:23;2583:31;2608:5;2583:31;:::i;:::-;2633:5;-1:-1:-1;2690:2:1;2675:18;;2662:32;2703:33;2662:32;2703:33;:::i;:::-;2467:352;;2755:7;;-1:-1:-1;;;2809:2:1;2794:18;;;;2781:32;;2467:352::o;3101:180::-;3160:6;3213:2;3201:9;3192:7;3188:23;3184:32;3181:2;;;3229:1;3226;3219:12;3181:2;-1:-1:-1;3252:23:1;;3171:110;-1:-1:-1;3171:110:1:o;3286:659::-;3365:6;3373;3381;3434:2;3422:9;3413:7;3409:23;3405:32;3402:2;;;3450:1;3447;3440:12;3402:2;3486:9;3473:23;3463:33;;3547:2;3536:9;3532:18;3519:32;3570:18;3611:2;3603:6;3600:14;3597:2;;;3627:1;3624;3617:12;3597:2;3665:6;3654:9;3650:22;3640:32;;3710:7;3703:4;3699:2;3695:13;3691:27;3681:2;;3732:1;3729;3722:12;3681:2;3772;3759:16;3798:2;3790:6;3787:14;3784:2;;;3814:1;3811;3804:12;3784:2;3859:7;3854:2;3845:6;3841:2;3837:15;3833:24;3830:37;3827:2;;;3880:1;3877;3870:12;3827:2;3911;3907;3903:11;3893:21;;3933:6;3923:16;;;;;3392:553;;;;;:::o;3950:274::-;4079:3;4117:6;4111:13;4133:53;4179:6;4174:3;4167:4;4159:6;4155:17;4133:53;:::i;:::-;4202:16;;;;;4087:137;-1:-1:-1;;4087:137:1:o;7528:442::-;7677:2;7666:9;7659:21;7640:4;7709:6;7703:13;7752:6;7747:2;7736:9;7732:18;7725:34;7768:66;7827:6;7822:2;7811:9;7807:18;7802:2;7794:6;7790:15;7768:66;:::i;:::-;7886:2;7874:15;7891:66;7870:88;7855:104;;;;7961:2;7851:113;;7649:321;-1:-1:-1;;7649:321:1:o;13263:331::-;13368:9;13379;13421:8;13409:10;13406:24;13403:2;;;13443:1;13440;13433:12;13403:2;13472:6;13462:8;13459:20;13456:2;;;13492:1;13489;13482:12;13456:2;-1:-1:-1;;13518:23:1;;;13563:25;;;;;-1:-1:-1;13393:201:1:o;13599:128::-;13639:3;13670:1;13666:6;13663:1;13660:13;13657:2;;;13676:18;;:::i;:::-;-1:-1:-1;13712:9:1;;13647:80::o;13732:274::-;13772:1;13798;13788:2;;13833:77;13830:1;13823:88;13934:4;13931:1;13924:15;13962:4;13959:1;13952:15;13788:2;-1:-1:-1;13991:9:1;;13778:228::o;14011:::-;14051:7;14177:1;14109:66;14105:74;14102:1;14099:81;14094:1;14087:9;14080:17;14076:105;14073:2;;;14184:18;;:::i;:::-;-1:-1:-1;14224:9:1;;14063:176::o;14244:125::-;14284:4;14312:1;14309;14306:8;14303:2;;;14317:18;;:::i;:::-;-1:-1:-1;14354:9:1;;14293:76::o;14374:258::-;14446:1;14456:113;14470:6;14467:1;14464:13;14456:113;;;14546:11;;;14540:18;14527:11;;;14520:39;14492:2;14485:10;14456:113;;;14587:6;14584:1;14581:13;14578:2;;;-1:-1:-1;;14622:1:1;14604:16;;14597:27;14427:205::o;14637:184::-;14689:77;14686:1;14679:88;14786:4;14783:1;14776:15;14810:4;14807:1;14800:15;14826:154;14912:42;14905:5;14901:54;14894:5;14891:65;14881:2;;14970:1;14967;14960:12;14985:118;15071:5;15064:13;15057:21;15050:5;15047:32;15037:2;;15093:1;15090;15083:12
Swarm Source
ipfs://f0a05122555cd84465c95771b2e8bc7d34005c6c22e54efa3cd9c7fa6d97c9ec
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.