Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
StakingRewards
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-12-04 */ // SPDX-License-Identifier: MIT // Sources flattened with hardhat v2.0.4 https://hardhat.org pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; // File deps/@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File deps/@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol /** * @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 deps/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol /** * @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 in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File deps/@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using SafeMathUpgradeable for uint256; 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' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(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 // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File deps/@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256` * (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File deps/@openzeppelin/contracts-upgradeable/proxy/Initializable.sol /** * @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 {UpgradeableProxy-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 || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; // solhint-disable-next-line no-inline-assembly assembly { cs := extcodesize(self) } return cs == 0; } } // File deps/@openzeppelin/contracts-upgradeable/GSN/ContextUpgradeable.sol /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; } // File deps/@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable { function __AccessControl_init() internal initializer { __Context_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer { } using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; using AddressUpgradeable for address; struct RoleData { EnumerableSetUpgradeable.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; } // File deps/@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } uint256[49] private __gap; } // File deps/@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal initializer { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal initializer { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!_paused, "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(_paused, "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; } // File deps/@openzeppelin/contracts-upgradeable/math/MathUpgradeable.sol /** * @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, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // File contracts/badger-geyser/StakingRewards.sol /** * @title Badger Staking Rewards * @dev Gated rewards mechanics for Badger Setts, based on Synthetix * StakingRewards */ contract StakingRewards is Initializable, AccessControlUpgradeable, PausableUpgradeable, ReentrancyGuardUpgradeable { using SafeMathUpgradeable for uint256; using SafeERC20Upgradeable for IERC20Upgradeable; /* ========== STATE VARIABLES ========== */ IERC20Upgradeable public rewardsToken; IERC20Upgradeable public stakingToken; uint256 public periodFinish; uint256 public rewardRate; uint256 public rewardsDuration; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; uint256 private _totalSupply; mapping(address => uint256) private _balances; bytes32 public constant APPROVED_STAKER_ROLE = keccak256("APPROVED_STAKER_ROLE"); function initialize( address _admin, address _rewardsToken, address _stakingToken ) public initializer { __AccessControl_init(); __Pausable_init_unchained(); __ReentrancyGuard_init_unchained(); _setupRole(DEFAULT_ADMIN_ROLE, _admin); rewardsToken = IERC20Upgradeable(_rewardsToken); stakingToken = IERC20Upgradeable(_stakingToken); rewardsDuration = 7 days; } /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { return _totalSupply; } function balanceOf(address account) external view returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable() public view returns (uint256) { return MathUpgradeable.min(block.timestamp, periodFinish); } function rewardPerToken() public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add(lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply)); } function earned(address account) public view returns (uint256) { return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]); } function getRewardForDuration() external view returns (uint256) { return rewardRate.mul(rewardsDuration); } /* ========== MUTATIVE FUNCTIONS ========== */ function stake(uint256 amount) external nonReentrant whenNotPaused updateReward(msg.sender) { _onlyApprovedStaker(); require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); stakingToken.safeTransfer(msg.sender, amount); emit Withdrawn(msg.sender, amount); } function getReward() public nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; rewardsToken.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } function exit() external { withdraw(_balances[msg.sender]); getReward(); } /* ========== RESTRICTED FUNCTIONS ========== */ function notifyRewardAmount(uint256 reward) external updateReward(address(0)) { _onlyAdmin(); if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); rewardRate = reward.add(leftover).div(rewardsDuration); } // Ensure the provided reward amount is not more than the balance in the contract. // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. uint256 balance = rewardsToken.balanceOf(address(this)); emit Test(rewardRate, balance, reward, rewardsDuration); require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); lastUpdateTime = block.timestamp; periodFinish = block.timestamp.add(rewardsDuration); emit RewardAdded(reward); } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address tokenAddress, uint256 tokenAmount) external { _onlyAdmin(); // Cannot recover the staking token or the rewards token require(tokenAddress != address(stakingToken) && tokenAddress != address(rewardsToken), "Cannot withdraw the staking or rewards tokens"); IERC20Upgradeable(tokenAddress).safeTransfer(getRoleMember(DEFAULT_ADMIN_ROLE, 0), tokenAmount); emit Recovered(tokenAddress, tokenAmount); } function setRewardsDuration(uint256 _rewardsDuration) external { _onlyAdmin(); require(block.timestamp > periodFinish, "Previous rewards period must be complete before changing the duration for the new period"); rewardsDuration = _rewardsDuration; emit RewardsDurationUpdated(rewardsDuration); } function pause() external { _onlyAdmin(); _pause(); } function unpause() external { _onlyAdmin(); _unpause(); } /* ========== MODIFIERS ========== */ modifier updateReward(address account) { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; } function _onlyAdmin() internal { require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "onlyAdmin"); } function _onlyApprovedStaker() internal { require(hasRole(APPROVED_STAKER_ROLE, msg.sender), "onlyApprovedStaker"); } /* ========== EVENTS ========== */ event Test(uint256 rate, uint256 balance, uint256 reward, uint256 duration); event RewardAdded(uint256 reward); event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); event RewardsDurationUpdated(uint256 newDuration); event Recovered(address token, uint256 amount); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":false,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Test","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","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":[],"name":"APPROVED_STAKER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"}],"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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50611f4f806100206000396000f3fe608060405234801561001057600080fd5b50600436106102105760003560e01c80638456cb5911610125578063c8f33c91116100ad578063d1af0c7d1161007c578063d1af0c7d146103e7578063d547741f146103ef578063df136d6514610402578063e9fad8ee1461040a578063ebe2b12b1461041257610210565b8063c8f33c91146103b1578063ca15c873146103b9578063cc1a378f146103cc578063cd3daf9d146103df57610210565b80639010d07c116100f45780639010d07c1461035d57806391d1485414610370578063a217fddf14610383578063a694fc3a1461038b578063c0c53b8b1461039e57610210565b80638456cb5914610327578063867e75e01461032f5780638980f11f146103375780638b8763471461034a57610210565b8063386a9525116101a85780635c975abb116101775780635c975abb146102da57806370a08231146102ef57806372f702f3146103025780637b0a47ee1461031757806380faa57d1461031f57610210565b8063386a9525146102af5780633c6b16ab146102b75780633d18b912146102ca5780633f4ba83a146102d257610210565b8063248a9ca3116101e4578063248a9ca3146102615780632e1a7d4d146102745780632f2ff15d1461028957806336568abe1461029c57610210565b80628cc262146102155780630700037d1461023e57806318160ddd146102515780631c1f78eb14610259575b600080fd5b61022861022336600461183a565b61041a565b60405161023591906119e7565b60405180910390f35b61022861024c36600461183a565b610498565b6102286104aa565b6102286104b1565b61022861026f3660046118e4565b6104cf565b6102876102823660046118e4565b6104e4565b005b6102876102973660046118fc565b610630565b6102876102aa3660046118fc565b610678565b6102286106ba565b6102876102c53660046118e4565b6106c0565b6102876108cc565b6102876109d0565b6102e26109e2565b60405161023591906119dc565b6102286102fd36600461183a565b6109eb565b61030a610a06565b604051610235919061198b565b610228610a15565b610228610a1b565b610287610a29565b610228610a39565b61028761034536600461189a565b610a5d565b61022861035836600461183a565b610b09565b61030a61036b366004611936565b610b1b565b6102e261037e3660046118fc565b610b3a565b610228610b52565b6102876103993660046118e4565b610b57565b6102876103ac366004611855565b610cb5565b610228610d95565b6102286103c73660046118e4565b610d9b565b6102876103da3660046118e4565b610db2565b610228610e1b565b61030a610e69565b6102876103fd3660046118fc565b610e78565b610228610eb2565b610287610eb8565b610228610ed9565b6001600160a01b038116600090815260d1602090815260408083205460d0909252822054610492919061048c90670de0b6b3a7640000906104869061046790610461610e1b565b90610edf565b6001600160a01b038816600090815260d3602052604090205490610f21565b90610f5b565b90610f9d565b92915050565b60d16020526000908152604090205481565b60d2545b90565b60006104ca60cd5460cc54610f2190919063ffffffff16565b905090565b60009081526033602052604090206002015490565b600260975414156105105760405162461bcd60e51b815260040161050790611e4c565b60405180910390fd5b60026097553361051e610e1b565b60cf55610529610a1b565b60ce556001600160a01b03811615610570576105448161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b600082116105905760405162461bcd60e51b815260040161050790611cdb565b60d25461059d9083610edf565b60d25533600090815260d360205260409020546105ba9083610edf565b33600081815260d3602052604090209190915560ca546105e6916001600160a01b039091169084610fc2565b336001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d58360405161061f91906119e7565b60405180910390a250506001609755565b60008281526033602052604090206002015461064e9061037e61101d565b61066a5760405162461bcd60e51b815260040161050790611b0b565b6106748282611021565b5050565b61068061101d565b6001600160a01b0316816001600160a01b0316146106b05760405162461bcd60e51b815260040161050790611e83565b610674828261108a565b60cd5481565b60006106ca610e1b565b60cf556106d5610a1b565b60ce556001600160a01b0381161561071c576106f08161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b6107246110f3565b60cb5442106107435760cd5461073b908390610f5b565b60cc55610786565b60cb546000906107539042610edf565b9050600061076c60cc5483610f2190919063ffffffff16565b60cd54909150610780906104868684610f9d565b60cc5550505b60c9546040516370a0823160e01b81526000916001600160a01b0316906370a08231906107b790309060040161198b565b60206040518083038186803b1580156107cf57600080fd5b505afa1580156107e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108079190611957565b90507f194b98d7327f7e5a21b302ad3be9f3402fad62465a1e4b5fe0d14a3e4696be3060cc54828560cd546040516108429493929190611ed2565b60405180910390a160cd54610858908290610f5b565b60cc5411156108795760405162461bcd60e51b815260040161050790611d47565b4260ce81905560cd5461088c9190610f9d565b60cb556040517fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d906108bf9085906119e7565b60405180910390a1505050565b600260975414156108ef5760405162461bcd60e51b815260040161050790611e4c565b6002609755336108fd610e1b565b60cf55610908610a1b565b60ce556001600160a01b0381161561094f576109238161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b33600090815260d1602052604090205480156109c75733600081815260d1602052604081205560c95461098e916001600160a01b039091169083610fc2565b336001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868260405161061f91906119e7565b50506001609755565b6109d86110f3565b6109e061111a565b565b60655460ff1690565b6001600160a01b0316600090815260d3602052604090205490565b60ca546001600160a01b031681565b60cc5481565b60006104ca4260cb54611186565b610a316110f3565b6109e061119c565b7fcaf8f629423b88c901c4a0224e3af9b8b6789801a2ab637bc6e101d939d0b1f381565b610a656110f3565b60ca546001600160a01b03838116911614801590610a91575060c9546001600160a01b03838116911614155b610aad5760405162461bcd60e51b815260040161050790611db5565b610acc610abb600080610b1b565b6001600160a01b0384169083610fc2565b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288282604051610afd9291906119c3565b60405180910390a15050565b60d06020526000908152604090205481565b6000828152603360205260408120610b3390836111f5565b9392505050565b6000828152603360205260408120610b339083611201565b600081565b60026097541415610b7a5760405162461bcd60e51b815260040161050790611e4c565b600260975560655460ff1615610ba25760405162461bcd60e51b815260040161050790611c37565b33610bab610e1b565b60cf55610bb6610a1b565b60ce556001600160a01b03811615610bfd57610bd18161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b610c05611216565b60008211610c255760405162461bcd60e51b815260040161050790611b88565b60d254610c329083610f9d565b60d25533600090815260d36020526040902054610c4f9083610f9d565b33600081815260d3602052604090209190915560ca54610c7c916001600160a01b0390911690308561125c565b336001600160a01b03167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d8360405161061f91906119e7565b600054610100900460ff1680610cce5750610cce61127d565b80610cdc575060005460ff16155b610cf85760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015610d23576000805460ff1961ff0019909116610100171660011790555b610d2b611283565b610d33611316565b610d3b6113a2565b610d4660008561066a565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca80549285169290911691909117905562093a8060cd558015610d8f576000805461ff00191690555b50505050565b60ce5481565b600081815260336020526040812061049290611429565b610dba6110f3565b60cb544211610ddb5760405162461bcd60e51b815260040161050790611a88565b60cd8190556040517ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d390610e109083906119e7565b60405180910390a150565b600060d25460001415610e31575060cf546104ae565b6104ca610e6060d254610486670de0b6b3a7640000610e5a60cc54610e5a60ce54610461610a1b565b90610f21565b60cf5490610f9d565b60c9546001600160a01b031681565b600082815260336020526040902060020154610e969061037e61101d565b6106b05760405162461bcd60e51b815260040161050790611be7565b60cf5481565b33600090815260d36020526040902054610ed1906104e4565b6109e06108cc565b60cb5481565b6000610b3383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611434565b600082610f3057506000610492565b82820282848281610f3d57fe5b0414610b335760405162461bcd60e51b815260040161050790611d06565b6000610b3383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611460565b600082820183811015610b335760405162461bcd60e51b815260040161050790611bb0565b6110188363a9059cbb60e01b8484604051602401610fe19291906119c3565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611497565b505050565b3390565b60008281526033602052604090206110399082611526565b156106745761104661101d565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206110a2908261153b565b15610674576110af61101d565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6110fe600033610b3a565b6109e05760405162461bcd60e51b815260040161050790611a23565b60655460ff1661113c5760405162461bcd60e51b815260040161050790611b5a565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61116f61101d565b60405161117c919061198b565b60405180910390a1565b60008183106111955781610b33565b5090919050565b60655460ff16156111bf5760405162461bcd60e51b815260040161050790611c37565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861116f61101d565b6000610b338383611550565b6000610b33836001600160a01b038416611595565b6112407fcaf8f629423b88c901c4a0224e3af9b8b6789801a2ab637bc6e101d939d0b1f333610b3a565b6109e05760405162461bcd60e51b815260040161050790611caf565b610d8f846323b872dd60e01b858585604051602401610fe19392919061199f565b303b1590565b600054610100900460ff168061129c575061129c61127d565b806112aa575060005460ff16155b6112c65760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff161580156112f1576000805460ff1961ff0019909116610100171660011790555b6112f96115ad565b6113016115ad565b8015611313576000805461ff00191690555b50565b600054610100900460ff168061132f575061132f61127d565b8061133d575060005460ff16155b6113595760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015611384576000805460ff1961ff0019909116610100171660011790555b6065805460ff191690558015611313576000805461ff001916905550565b600054610100900460ff16806113bb57506113bb61127d565b806113c9575060005460ff16155b6113e55760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015611410576000805460ff1961ff0019909116610100171660011790555b60016097558015611313576000805461ff001916905550565b60006104928261162e565b600081848411156114585760405162461bcd60e51b815260040161050791906119f0565b505050900390565b600081836114815760405162461bcd60e51b815260040161050791906119f0565b50600083858161148d57fe5b0495945050505050565b60606114ec826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116329092919063ffffffff16565b805190915015611018578080602001905181019061150a91906118c4565b6110185760405162461bcd60e51b815260040161050790611e02565b6000610b33836001600160a01b038416611649565b6000610b33836001600160a01b038416611693565b815460009082106115735760405162461bcd60e51b815260040161050790611a46565b82600001828154811061158257fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600054610100900460ff16806115c657506115c661127d565b806115d4575060005460ff16155b6115f05760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015611301576000805460ff1961ff0019909116610100171660011790558015611313576000805461ff001916905550565b5490565b60606116418484600085611759565b949350505050565b60006116558383611595565b61168b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610492565b506000610492565b6000818152600183016020526040812054801561174f57835460001980830191908101906000908790839081106116c657fe5b90600052602060002001549050808760000184815481106116e357fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061171357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610492565b6000915050610492565b60606117648561181d565b6117805760405162461bcd60e51b815260040161050790611d7e565b60006060866001600160a01b0316858760405161179d919061196f565b60006040518083038185875af1925050503d80600081146117da576040519150601f19603f3d011682016040523d82523d6000602084013e6117df565b606091505b509150915081156117f35791506116419050565b8051156118035780518082602001fd5b8360405162461bcd60e51b815260040161050791906119f0565b3b151590565b80356001600160a01b038116811461049257600080fd5b60006020828403121561184b578081fd5b610b338383611823565b600080600060608486031215611869578182fd5b6118738585611823565b92506118828560208601611823565b91506118918560408601611823565b90509250925092565b600080604083850312156118ac578182fd5b6118b68484611823565b946020939093013593505050565b6000602082840312156118d5578081fd5b81518015158114610b33578182fd5b6000602082840312156118f5578081fd5b5035919050565b6000806040838503121561190e578182fd5b8235915060208301356001600160a01b038116811461192b578182fd5b809150509250929050565b60008060408385031215611948578182fd5b50508035926020909101359150565b600060208284031215611968578081fd5b5051919050565b60008251611981818460208701611eed565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b6000602082528251806020840152611a0f816040850160208701611eed565b601f01601f19169190910160400192915050565b60208082526009908201526837b7363ca0b236b4b760b91b604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526058908201527f50726576696f7573207265776172647320706572696f64206d7573742062652060408201527f636f6d706c657465206265666f7265206368616e67696e67207468652064757260608201527f6174696f6e20666f7220746865206e657720706572696f640000000000000000608082015260a00190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252600e908201526d043616e6e6f74207374616b6520360941b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526012908201527137b7363ca0b8383937bb32b229ba30b5b2b960711b604082015260600190565b602080825260119082015270043616e6e6f74207769746864726177203607c1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526018908201527f50726f76696465642072657761726420746f6f20686967680000000000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602d908201527f43616e6e6f7420776974686472617720746865207374616b696e67206f72207260408201526c65776172647320746f6b656e7360981b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b93845260208401929092526040830152606082015260800190565b60005b83811015611f08578181015183820152602001611ef0565b83811115610d8f575050600091015256fea2646970667358221220fce74a12b8f7511b923180010a268fc7d81c28b6d6b959b997487c91cb0e693464736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102105760003560e01c80638456cb5911610125578063c8f33c91116100ad578063d1af0c7d1161007c578063d1af0c7d146103e7578063d547741f146103ef578063df136d6514610402578063e9fad8ee1461040a578063ebe2b12b1461041257610210565b8063c8f33c91146103b1578063ca15c873146103b9578063cc1a378f146103cc578063cd3daf9d146103df57610210565b80639010d07c116100f45780639010d07c1461035d57806391d1485414610370578063a217fddf14610383578063a694fc3a1461038b578063c0c53b8b1461039e57610210565b80638456cb5914610327578063867e75e01461032f5780638980f11f146103375780638b8763471461034a57610210565b8063386a9525116101a85780635c975abb116101775780635c975abb146102da57806370a08231146102ef57806372f702f3146103025780637b0a47ee1461031757806380faa57d1461031f57610210565b8063386a9525146102af5780633c6b16ab146102b75780633d18b912146102ca5780633f4ba83a146102d257610210565b8063248a9ca3116101e4578063248a9ca3146102615780632e1a7d4d146102745780632f2ff15d1461028957806336568abe1461029c57610210565b80628cc262146102155780630700037d1461023e57806318160ddd146102515780631c1f78eb14610259575b600080fd5b61022861022336600461183a565b61041a565b60405161023591906119e7565b60405180910390f35b61022861024c36600461183a565b610498565b6102286104aa565b6102286104b1565b61022861026f3660046118e4565b6104cf565b6102876102823660046118e4565b6104e4565b005b6102876102973660046118fc565b610630565b6102876102aa3660046118fc565b610678565b6102286106ba565b6102876102c53660046118e4565b6106c0565b6102876108cc565b6102876109d0565b6102e26109e2565b60405161023591906119dc565b6102286102fd36600461183a565b6109eb565b61030a610a06565b604051610235919061198b565b610228610a15565b610228610a1b565b610287610a29565b610228610a39565b61028761034536600461189a565b610a5d565b61022861035836600461183a565b610b09565b61030a61036b366004611936565b610b1b565b6102e261037e3660046118fc565b610b3a565b610228610b52565b6102876103993660046118e4565b610b57565b6102876103ac366004611855565b610cb5565b610228610d95565b6102286103c73660046118e4565b610d9b565b6102876103da3660046118e4565b610db2565b610228610e1b565b61030a610e69565b6102876103fd3660046118fc565b610e78565b610228610eb2565b610287610eb8565b610228610ed9565b6001600160a01b038116600090815260d1602090815260408083205460d0909252822054610492919061048c90670de0b6b3a7640000906104869061046790610461610e1b565b90610edf565b6001600160a01b038816600090815260d3602052604090205490610f21565b90610f5b565b90610f9d565b92915050565b60d16020526000908152604090205481565b60d2545b90565b60006104ca60cd5460cc54610f2190919063ffffffff16565b905090565b60009081526033602052604090206002015490565b600260975414156105105760405162461bcd60e51b815260040161050790611e4c565b60405180910390fd5b60026097553361051e610e1b565b60cf55610529610a1b565b60ce556001600160a01b03811615610570576105448161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b600082116105905760405162461bcd60e51b815260040161050790611cdb565b60d25461059d9083610edf565b60d25533600090815260d360205260409020546105ba9083610edf565b33600081815260d3602052604090209190915560ca546105e6916001600160a01b039091169084610fc2565b336001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d58360405161061f91906119e7565b60405180910390a250506001609755565b60008281526033602052604090206002015461064e9061037e61101d565b61066a5760405162461bcd60e51b815260040161050790611b0b565b6106748282611021565b5050565b61068061101d565b6001600160a01b0316816001600160a01b0316146106b05760405162461bcd60e51b815260040161050790611e83565b610674828261108a565b60cd5481565b60006106ca610e1b565b60cf556106d5610a1b565b60ce556001600160a01b0381161561071c576106f08161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b6107246110f3565b60cb5442106107435760cd5461073b908390610f5b565b60cc55610786565b60cb546000906107539042610edf565b9050600061076c60cc5483610f2190919063ffffffff16565b60cd54909150610780906104868684610f9d565b60cc5550505b60c9546040516370a0823160e01b81526000916001600160a01b0316906370a08231906107b790309060040161198b565b60206040518083038186803b1580156107cf57600080fd5b505afa1580156107e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108079190611957565b90507f194b98d7327f7e5a21b302ad3be9f3402fad62465a1e4b5fe0d14a3e4696be3060cc54828560cd546040516108429493929190611ed2565b60405180910390a160cd54610858908290610f5b565b60cc5411156108795760405162461bcd60e51b815260040161050790611d47565b4260ce81905560cd5461088c9190610f9d565b60cb556040517fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d906108bf9085906119e7565b60405180910390a1505050565b600260975414156108ef5760405162461bcd60e51b815260040161050790611e4c565b6002609755336108fd610e1b565b60cf55610908610a1b565b60ce556001600160a01b0381161561094f576109238161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b33600090815260d1602052604090205480156109c75733600081815260d1602052604081205560c95461098e916001600160a01b039091169083610fc2565b336001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868260405161061f91906119e7565b50506001609755565b6109d86110f3565b6109e061111a565b565b60655460ff1690565b6001600160a01b0316600090815260d3602052604090205490565b60ca546001600160a01b031681565b60cc5481565b60006104ca4260cb54611186565b610a316110f3565b6109e061119c565b7fcaf8f629423b88c901c4a0224e3af9b8b6789801a2ab637bc6e101d939d0b1f381565b610a656110f3565b60ca546001600160a01b03838116911614801590610a91575060c9546001600160a01b03838116911614155b610aad5760405162461bcd60e51b815260040161050790611db5565b610acc610abb600080610b1b565b6001600160a01b0384169083610fc2565b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288282604051610afd9291906119c3565b60405180910390a15050565b60d06020526000908152604090205481565b6000828152603360205260408120610b3390836111f5565b9392505050565b6000828152603360205260408120610b339083611201565b600081565b60026097541415610b7a5760405162461bcd60e51b815260040161050790611e4c565b600260975560655460ff1615610ba25760405162461bcd60e51b815260040161050790611c37565b33610bab610e1b565b60cf55610bb6610a1b565b60ce556001600160a01b03811615610bfd57610bd18161041a565b6001600160a01b038216600090815260d1602090815260408083209390935560cf5460d0909152919020555b610c05611216565b60008211610c255760405162461bcd60e51b815260040161050790611b88565b60d254610c329083610f9d565b60d25533600090815260d36020526040902054610c4f9083610f9d565b33600081815260d3602052604090209190915560ca54610c7c916001600160a01b0390911690308561125c565b336001600160a01b03167f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d8360405161061f91906119e7565b600054610100900460ff1680610cce5750610cce61127d565b80610cdc575060005460ff16155b610cf85760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015610d23576000805460ff1961ff0019909116610100171660011790555b610d2b611283565b610d33611316565b610d3b6113a2565b610d4660008561066a565b60c980546001600160a01b038086166001600160a01b03199283161790925560ca80549285169290911691909117905562093a8060cd558015610d8f576000805461ff00191690555b50505050565b60ce5481565b600081815260336020526040812061049290611429565b610dba6110f3565b60cb544211610ddb5760405162461bcd60e51b815260040161050790611a88565b60cd8190556040517ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d390610e109083906119e7565b60405180910390a150565b600060d25460001415610e31575060cf546104ae565b6104ca610e6060d254610486670de0b6b3a7640000610e5a60cc54610e5a60ce54610461610a1b565b90610f21565b60cf5490610f9d565b60c9546001600160a01b031681565b600082815260336020526040902060020154610e969061037e61101d565b6106b05760405162461bcd60e51b815260040161050790611be7565b60cf5481565b33600090815260d36020526040902054610ed1906104e4565b6109e06108cc565b60cb5481565b6000610b3383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611434565b600082610f3057506000610492565b82820282848281610f3d57fe5b0414610b335760405162461bcd60e51b815260040161050790611d06565b6000610b3383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611460565b600082820183811015610b335760405162461bcd60e51b815260040161050790611bb0565b6110188363a9059cbb60e01b8484604051602401610fe19291906119c3565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611497565b505050565b3390565b60008281526033602052604090206110399082611526565b156106745761104661101d565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526033602052604090206110a2908261153b565b15610674576110af61101d565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6110fe600033610b3a565b6109e05760405162461bcd60e51b815260040161050790611a23565b60655460ff1661113c5760405162461bcd60e51b815260040161050790611b5a565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61116f61101d565b60405161117c919061198b565b60405180910390a1565b60008183106111955781610b33565b5090919050565b60655460ff16156111bf5760405162461bcd60e51b815260040161050790611c37565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861116f61101d565b6000610b338383611550565b6000610b33836001600160a01b038416611595565b6112407fcaf8f629423b88c901c4a0224e3af9b8b6789801a2ab637bc6e101d939d0b1f333610b3a565b6109e05760405162461bcd60e51b815260040161050790611caf565b610d8f846323b872dd60e01b858585604051602401610fe19392919061199f565b303b1590565b600054610100900460ff168061129c575061129c61127d565b806112aa575060005460ff16155b6112c65760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff161580156112f1576000805460ff1961ff0019909116610100171660011790555b6112f96115ad565b6113016115ad565b8015611313576000805461ff00191690555b50565b600054610100900460ff168061132f575061132f61127d565b8061133d575060005460ff16155b6113595760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015611384576000805460ff1961ff0019909116610100171660011790555b6065805460ff191690558015611313576000805461ff001916905550565b600054610100900460ff16806113bb57506113bb61127d565b806113c9575060005460ff16155b6113e55760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015611410576000805460ff1961ff0019909116610100171660011790555b60016097558015611313576000805461ff001916905550565b60006104928261162e565b600081848411156114585760405162461bcd60e51b815260040161050791906119f0565b505050900390565b600081836114815760405162461bcd60e51b815260040161050791906119f0565b50600083858161148d57fe5b0495945050505050565b60606114ec826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116329092919063ffffffff16565b805190915015611018578080602001905181019061150a91906118c4565b6110185760405162461bcd60e51b815260040161050790611e02565b6000610b33836001600160a01b038416611649565b6000610b33836001600160a01b038416611693565b815460009082106115735760405162461bcd60e51b815260040161050790611a46565b82600001828154811061158257fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600054610100900460ff16806115c657506115c661127d565b806115d4575060005460ff16155b6115f05760405162461bcd60e51b815260040161050790611c61565b600054610100900460ff16158015611301576000805460ff1961ff0019909116610100171660011790558015611313576000805461ff001916905550565b5490565b60606116418484600085611759565b949350505050565b60006116558383611595565b61168b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610492565b506000610492565b6000818152600183016020526040812054801561174f57835460001980830191908101906000908790839081106116c657fe5b90600052602060002001549050808760000184815481106116e357fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061171357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610492565b6000915050610492565b60606117648561181d565b6117805760405162461bcd60e51b815260040161050790611d7e565b60006060866001600160a01b0316858760405161179d919061196f565b60006040518083038185875af1925050503d80600081146117da576040519150601f19603f3d011682016040523d82523d6000602084013e6117df565b606091505b509150915081156117f35791506116419050565b8051156118035780518082602001fd5b8360405162461bcd60e51b815260040161050791906119f0565b3b151590565b80356001600160a01b038116811461049257600080fd5b60006020828403121561184b578081fd5b610b338383611823565b600080600060608486031215611869578182fd5b6118738585611823565b92506118828560208601611823565b91506118918560408601611823565b90509250925092565b600080604083850312156118ac578182fd5b6118b68484611823565b946020939093013593505050565b6000602082840312156118d5578081fd5b81518015158114610b33578182fd5b6000602082840312156118f5578081fd5b5035919050565b6000806040838503121561190e578182fd5b8235915060208301356001600160a01b038116811461192b578182fd5b809150509250929050565b60008060408385031215611948578182fd5b50508035926020909101359150565b600060208284031215611968578081fd5b5051919050565b60008251611981818460208701611eed565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b90815260200190565b6000602082528251806020840152611a0f816040850160208701611eed565b601f01601f19169190910160400192915050565b60208082526009908201526837b7363ca0b236b4b760b91b604082015260600190565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526058908201527f50726576696f7573207265776172647320706572696f64206d7573742062652060408201527f636f6d706c657465206265666f7265206368616e67696e67207468652064757260608201527f6174696f6e20666f7220746865206e657720706572696f640000000000000000608082015260a00190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b6020808252600e908201526d043616e6e6f74207374616b6520360941b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526012908201527137b7363ca0b8383937bb32b229ba30b5b2b960711b604082015260600190565b602080825260119082015270043616e6e6f74207769746864726177203607c1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526018908201527f50726f76696465642072657761726420746f6f20686967680000000000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602d908201527f43616e6e6f7420776974686472617720746865207374616b696e67206f72207260408201526c65776172647320746f6b656e7360981b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b93845260208401929092526040830152606082015260800190565b60005b83811015611f08578181015183820152602001611ef0565b83811115610d8f575050600091015256fea2646970667358221220fce74a12b8f7511b923180010a268fc7d81c28b6d6b959b997487c91cb0e693464736f6c634300060c0033
Deployed Bytecode Sourcemap
44371:7025:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46388:198;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44981:42;;;;;;:::i;:::-;;:::i;45724:93::-;;;:::i;46594:121::-;;;:::i;34676:114::-;;;;;;:::i;:::-;;:::i;47200:357::-;;;;;;:::i;:::-;;:::i;:::-;;35052:227;;;;;;:::i;:::-;;:::i;36261:209::-;;;;;;:::i;:::-;;:::i;44800:30::-;;;:::i;48041:1151::-;;;;;;:::i;:::-;;:::i;47565:307::-;;;:::i;50219:80::-;;;:::i;42114:78::-;;;:::i;:::-;;;;;;;:::i;45825:112::-;;;;;;:::i;:::-;;:::i;44690:37::-;;;:::i;:::-;;;;;;;:::i;44768:25::-;;;:::i;45945:142::-;;;:::i;50135:76::-;;;:::i;45121:80::-;;;:::i;49307:476::-;;;;;;:::i;:::-;;:::i;44917:57::-;;;;;;:::i;:::-;;:::i;34349:138::-;;;;;;:::i;:::-;;:::i;33310:139::-;;;;;;:::i;:::-;;:::i;32055:49::-;;;:::i;46777:415::-;;;;;;:::i;:::-;;:::i;45210:465::-;;;;;;:::i;:::-;;:::i;44837:29::-;;;:::i;33623:127::-;;;;;;:::i;:::-;;:::i;49791:336::-;;;;;;:::i;:::-;;:::i;46095:285::-;;;:::i;44646:37::-;;;:::i;35524:230::-;;;;;;:::i;:::-;;:::i;44873:35::-;;;:::i;47880:97::-;;;:::i;44734:27::-;;;:::i;46388:198::-;-1:-1:-1;;;;;46561:16:0;;46442:7;46561:16;;;:7;:16;;;;;;;;;46513:22;:31;;;;;;46469:109;;46561:16;46469:87;;46551:4;;46469:77;;46492:53;;:16;:14;:16::i;:::-;:20;;:53::i;:::-;-1:-1:-1;;;;;46469:18:0;;;;;;:9;:18;;;;;;;:22;:77::i;:::-;:81;;:87::i;:::-;:91;;:109::i;:::-;46462:116;46388:198;-1:-1:-1;;46388:198:0:o;44981:42::-;;;;;;;;;;;;;:::o;45724:93::-;45797:12;;45724:93;;:::o;46594:121::-;46649:7;46676:31;46691:15;;46676:10;;:14;;:31;;;;:::i;:::-;46669:38;;46594:121;:::o;34676:114::-;34733:7;34760:12;;;:6;:12;;;;;:22;;;;34676:114::o;47200:357::-;39692:1;40455:7;;:19;;40447:63;;;;-1:-1:-1;;;40447:63:0;;;;;;;:::i;:::-;;;;;;;;;39692:1;40588:7;:18;47267:10:::1;50425:16;:14;:16::i;:::-;50402:20;:39:::0;50469:26:::1;:24;:26::i;:::-;50452:14;:43:::0;-1:-1:-1;;;;;50510:21:0;::::1;::::0;50506:157:::1;;50567:15;50574:7;50567:6;:15::i;:::-;-1:-1:-1::0;;;;;50548:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;50631:20:::1;::::0;50597:22:::1;:31:::0;;;;;;:54;50506:157:::1;47307:1:::2;47298:6;:10;47290:40;;;;-1:-1:-1::0;;;47290:40:0::2;;;;;;;:::i;:::-;47356:12;::::0;:24:::2;::::0;47373:6;47356:16:::2;:24::i;:::-;47341:12;:39:::0;47425:10:::2;47415:21;::::0;;;:9:::2;:21;::::0;;;;;:33:::2;::::0;47441:6;47415:25:::2;:33::i;:::-;47401:10;47391:21;::::0;;;:9:::2;:21;::::0;;;;:57;;;;47459:12:::2;::::0;:45:::2;::::0;-1:-1:-1;;;;;47459:12:0;;::::2;::::0;47497:6;47459:25:::2;:45::i;:::-;47530:10;-1:-1:-1::0;;;;;47520:29:0::2;;47542:6;47520:29;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;39648:1:0;40767:7;:22;47200:357::o;35052:227::-;35144:12;;;;:6;:12;;;;;:22;;;35136:45;;35168:12;:10;:12::i;35136:45::-;35128:105;;;;-1:-1:-1;;;35128:105:0;;;;;;;:::i;:::-;35246:25;35257:4;35263:7;35246:10;:25::i;:::-;35052:227;;:::o;36261:209::-;36359:12;:10;:12::i;:::-;-1:-1:-1;;;;;36348:23:0;:7;-1:-1:-1;;;;;36348:23:0;;36340:83;;;;-1:-1:-1;;;36340:83:0;;;;;;;:::i;:::-;36436:26;36448:4;36454:7;36436:11;:26::i;44800:30::-;;;;:::o;48041:1151::-;48115:1;50425:16;:14;:16::i;:::-;50402:20;:39;50469:26;:24;:26::i;:::-;50452:14;:43;-1:-1:-1;;;;;50510:21:0;;;50506:157;;50567:15;50574:7;50567:6;:15::i;:::-;-1:-1:-1;;;;;50548:16:0;;;;;;:7;:16;;;;;;;;:34;;;;50631:20;;50597:22;:31;;;;;;:54;50506:157;48130:12:::1;:10;:12::i;:::-;48176;;48157:15;:31;48153:318;;48229:15;::::0;48218:27:::1;::::0;:6;;:10:::1;:27::i;:::-;48205:10;:40:::0;48153:318:::1;;;48298:12;::::0;48278:17:::1;::::0;48298:33:::1;::::0;48315:15:::1;48298:16;:33::i;:::-;48278:53;;48346:16;48365:25;48379:10;;48365:9;:13;;:25;;;;:::i;:::-;48443:15;::::0;48346:44;;-1:-1:-1;48418:41:0::1;::::0;:20:::1;:6:::0;48346:44;48418:10:::1;:20::i;:41::-;48405:10;:54:::0;-1:-1:-1;;48153:318:0::1;48849:12;::::0;:37:::1;::::0;-1:-1:-1;;;48849:37:0;;48831:15:::1;::::0;-1:-1:-1;;;;;48849:12:0::1;::::0;:22:::1;::::0;:37:::1;::::0;48880:4:::1;::::0;48849:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48831:55;;48902:50;48907:10;;48919:7;48928:6;48936:15;;48902:50;;;;;;;;;:::i;:::-;;;;;;;;48997:15;::::0;48985:28:::1;::::0;:7;;:11:::1;:28::i;:::-;48971:10;;:42;;48963:79;;;;-1:-1:-1::0;;;48963:79:0::1;;;;;;;:::i;:::-;49072:15;49055:14;:32:::0;;;49133:15:::1;::::0;49113:36:::1;::::0;49072:15;49113:19:::1;:36::i;:::-;49098:12;:51:::0;49165:19:::1;::::0;::::1;::::0;::::1;::::0;49177:6;;49165:19:::1;:::i;:::-;;;;;;;;50673:1;48041:1151:::0;;:::o;47565:307::-;39692:1;40455:7;;:19;;40447:63;;;;-1:-1:-1;;;40447:63:0;;;;;;;:::i;:::-;39692:1;40588:7;:18;47619:10:::1;50425:16;:14;:16::i;:::-;50402:20;:39:::0;50469:26:::1;:24;:26::i;:::-;50452:14;:43:::0;-1:-1:-1;;;;;50510:21:0;::::1;::::0;50506:157:::1;;50567:15;50574:7;50567:6;:15::i;:::-;-1:-1:-1::0;;;;;50548:16:0;::::1;;::::0;;;:7:::1;:16;::::0;;;;;;;:34;;;;50631:20:::1;::::0;50597:22:::1;:31:::0;;;;;;:54;50506:157:::1;47667:10:::2;47642:14;47659:19:::0;;;:7:::2;:19;::::0;;;;;47693:10;;47689:176:::2;;47728:10;47742:1;47720:19:::0;;;:7:::2;:19;::::0;;;;:23;47758:12:::2;::::0;:45:::2;::::0;-1:-1:-1;;;;;47758:12:0;;::::2;::::0;47796:6;47758:25:::2;:45::i;:::-;47834:10;-1:-1:-1::0;;;;;47823:30:0::2;;47846:6;47823:30;;;;;;:::i;47689:176::-;-1:-1:-1::0;;39648:1:0;40767:7;:22;47565:307::o;50219:80::-;50258:12;:10;:12::i;:::-;50281:10;:8;:10::i;:::-;50219:80::o;42114:78::-;42177:7;;;;42114:78;:::o;45825:112::-;-1:-1:-1;;;;;45911:18:0;45884:7;45911:18;;;:9;:18;;;;;;;45825:112::o;44690:37::-;;;-1:-1:-1;;;;;44690:37:0;;:::o;44768:25::-;;;;:::o;45945:142::-;46002:7;46029:50;46049:15;46066:12;;46029:19;:50::i;50135:76::-;50172:12;:10;:12::i;:::-;50195:8;:6;:8::i;45121:80::-;45168:33;45121:80;:::o;49307:476::-;49392:12;:10;:12::i;:::-;49513;;-1:-1:-1;;;;;49489:37:0;;;49513:12;;49489:37;;;;:78;;-1:-1:-1;49554:12:0;;-1:-1:-1;;;;;49530:37:0;;;49554:12;;49530:37;;49489:78;49481:136;;;;-1:-1:-1;;;49481:136:0;;;;;;;:::i;:::-;49628:95;49673:36;32100:4;;49673:13;:36::i;:::-;-1:-1:-1;;;;;49628:44:0;;;49711:11;49628:44;:95::i;:::-;49739:36;49749:12;49763:11;49739:36;;;;;;;:::i;:::-;;;;;;;;49307:476;;:::o;44917:57::-;;;;;;;;;;;;;:::o;34349:138::-;34422:7;34449:12;;;:6;:12;;;;;:30;;34473:5;34449:23;:30::i;:::-;34442:37;34349:138;-1:-1:-1;;;34349:138:0:o;33310:139::-;33379:4;33403:12;;;:6;:12;;;;;:38;;33433:7;33403:29;:38::i;32055:49::-;32100:4;32055:49;:::o;46777:415::-;39692:1;40455:7;;:19;;40447:63;;;;-1:-1:-1;;;40447:63:0;;;;;;;:::i;:::-;39692:1;40588:7;:18;42432:7:::1;::::0;::::1;;42431:8;42423:37;;;;-1:-1:-1::0;;;42423:37:0::1;;;;;;;:::i;:::-;46857:10:::2;50425:16;:14;:16::i;:::-;50402:20;:39:::0;50469:26:::2;:24;:26::i;:::-;50452:14;:43:::0;-1:-1:-1;;;;;50510:21:0;::::2;::::0;50506:157:::2;;50567:15;50574:7;50567:6;:15::i;:::-;-1:-1:-1::0;;;;;50548:16:0;::::2;;::::0;;;:7:::2;:16;::::0;;;;;;;:34;;;;50631:20:::2;::::0;50597:22:::2;:31:::0;;;;;;:54;50506:157:::2;46880:21:::3;:19;:21::i;:::-;46929:1;46920:6;:10;46912:37;;;;-1:-1:-1::0;;;46912:37:0::3;;;;;;;:::i;:::-;46975:12;::::0;:24:::3;::::0;46992:6;46975:16:::3;:24::i;:::-;46960:12;:39:::0;47044:10:::3;47034:21;::::0;;;:9:::3;:21;::::0;;;;;:33:::3;::::0;47060:6;47034:25:::3;:33::i;:::-;47020:10;47010:21;::::0;;;:9:::3;:21;::::0;;;;:57;;;;47078:12:::3;::::0;:64:::3;::::0;-1:-1:-1;;;;;47078:12:0;;::::3;::::0;47128:4:::3;47135:6:::0;47078:29:::3;:64::i;:::-;47165:10;-1:-1:-1::0;;;;;47158:26:0::3;;47177:6;47158:26;;;;;;:::i;45210:465::-:0;27775:13;;;;;;;;:33;;;27792:16;:14;:16::i;:::-;27775:50;;;-1:-1:-1;27813:12:0;;;;27812:13;27775:50;27767:109;;;;-1:-1:-1;;;27767:109:0;;;;;;;:::i;:::-;27889:19;27912:13;;;;;;27911:14;27936:101;;;;27971:13;:20;;-1:-1:-1;;;;27971:20:0;;;;;28006:19;27987:4;28006:19;;;27936:101;45356:22:::1;:20;:22::i;:::-;45389:27;:25;:27::i;:::-;45427:34;:32;:34::i;:::-;45474:38;32100:4;45505:6:::0;45474:10:::1;:38::i;:::-;45525:12;:47:::0;;-1:-1:-1;;;;;45525:47:0;;::::1;-1:-1:-1::0;;;;;;45525:47:0;;::::1;;::::0;;;45583:12:::1;:47:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;45661:6:::1;45643:15;:24:::0;28063:68;;;;28114:5;28098:21;;-1:-1:-1;;28098:21:0;;;28063:68;45210:465;;;;:::o;44837:29::-;;;;:::o;33623:127::-;33686:7;33713:12;;;:6;:12;;;;;:29;;:27;:29::i;49791:336::-;49865:12;:10;:12::i;:::-;49914;;49896:15;:30;49888:131;;;;-1:-1:-1;;;49888:131:0;;;;;;;:::i;:::-;50030:15;:34;;;50080:39;;;;;;50048:16;;50080:39;:::i;:::-;;;;;;;;49791:336;:::o;46095:285::-;46142:7;46166:12;;46182:1;46166:17;46162:77;;;-1:-1:-1;46207:20:0;;46200:27;;46162:77;46256:116;46281:90;46358:12;;46281:72;46348:4;46281:62;46332:10;;46281:46;46312:14;;46281:26;:24;:26::i;:46::-;:50;;:62::i;:90::-;46256:20;;;:24;:116::i;44646:37::-;;;-1:-1:-1;;;;;44646:37:0;;:::o;35524:230::-;35617:12;;;;:6;:12;;;;;:22;;;35609:45;;35641:12;:10;:12::i;35609:45::-;35601:106;;;;-1:-1:-1;;;35601:106:0;;;;;;;:::i;44873:35::-;;;;:::o;47880:97::-;47935:10;47925:21;;;;:9;:21;;;;;;47916:31;;:8;:31::i;:::-;47958:11;:9;:11::i;44734:27::-;;;;:::o;1555:136::-;1613:7;1640:43;1644:1;1647;1640:43;;;;;;;;;;;;;;;;;:3;:43::i;2445:471::-;2503:7;2748:6;2744:47;;-1:-1:-1;2778:1:0;2771:8;;2744:47;2815:5;;;2819:1;2815;:5;:1;2839:5;;;;;:10;2831:56;;;;-1:-1:-1;;;2831:56:0;;;;;;;:::i;3392:132::-;3450:7;3477:39;3481:1;3484;3477:39;;;;;;;;;;;;;;;;;:3;:39::i;1091:181::-;1149:7;1181:5;;;1205:6;;;;1197:46;;;;-1:-1:-1;;;1197:46:0;;;;;;;:::i;15102:188::-;15196:86;15216:5;15246:23;;;15271:2;15275:5;15223:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;15223:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;15223:58:0;-1:-1:-1;;;;;;15223:58:0;;;;;;;;;;15196:19;:86::i;:::-;15102:188;;;:::o;29665:106::-;29753:10;29665:106;:::o;37504:188::-;37578:12;;;;:6;:12;;;;;:33;;37603:7;37578:24;:33::i;:::-;37574:111;;;37660:12;:10;:12::i;:::-;-1:-1:-1;;;;;37633:40:0;37651:7;-1:-1:-1;;;;;37633:40:0;37645:4;37633:40;;;;;;;;;;37504:188;;:::o;37700:192::-;37775:12;;;;:6;:12;;;;;:36;;37803:7;37775:27;:36::i;:::-;37771:114;;;37860:12;:10;:12::i;:::-;-1:-1:-1;;;;;37833:40:0;37851:7;-1:-1:-1;;;;;37833:40:0;37845:4;37833:40;;;;;;;;;;37700:192;;:::o;50690:111::-;50740:39;32100:4;50768:10;50740:7;:39::i;:::-;50732:61;;;;-1:-1:-1;;;50732:61:0;;;;;;;:::i;43163:120::-;42708:7;;;;42700:40;;;;-1:-1:-1;;;42700:40:0;;;;;;;:::i;:::-;43222:7:::1;:15:::0;;-1:-1:-1;;43222:15:0::1;::::0;;43253:22:::1;43262:12;:10;:12::i;:::-;43253:22;;;;;;:::i;:::-;;;;;;;;43163:120::o:0;43759:106::-;43817:7;43848:1;43844;:5;:13;;43856:1;43844:13;;;-1:-1:-1;43852:1:0;;43759:106;-1:-1:-1;43759:106:0:o;42904:118::-;42432:7;;;;42431:8;42423:37;;;;-1:-1:-1;;;42423:37:0;;;;;;;:::i;:::-;42964:7:::1;:14:::0;;-1:-1:-1;;42964:14:0::1;42974:4;42964:14;::::0;;42994:20:::1;43001:12;:10;:12::i;24548:149::-:0;24622:7;24665:22;24669:3;24681:5;24665:3;:22::i;23843:158::-;23923:4;23947:46;23957:3;-1:-1:-1;;;;;23977:14:0;;23947:9;:46::i;50809:131::-;50868:41;45168:33;50898:10;50868:7;:41::i;:::-;50860:72;;;;-1:-1:-1;;;50860:72:0;;;;;;;:::i;15298:216::-;15410:96;15430:5;15460:27;;;15489:4;15495:2;15499:5;15437:68;;;;;;;;;;:::i;28231:604::-;28673:4;28784:17;28820:7;28231:604;:::o;31540:141::-;27775:13;;;;;;;;:33;;;27792:16;:14;:16::i;:::-;27775:50;;;-1:-1:-1;27813:12:0;;;;27812:13;27775:50;27767:109;;;;-1:-1:-1;;;27767:109:0;;;;;;;:::i;:::-;27889:19;27912:13;;;;;;27911:14;27936:101;;;;27971:13;:20;;-1:-1:-1;;;;27971:20:0;;;;;28006:19;27987:4;28006:19;;;27936:101;31604:26:::1;:24;:26::i;:::-;31641:32;:30;:32::i;:::-;28067:14:::0;28063:68;;;28114:5;28098:21;;-1:-1:-1;;28098:21:0;;;28063:68;31540:141;:::o;41922:92::-;27775:13;;;;;;;;:33;;;27792:16;:14;:16::i;:::-;27775:50;;;-1:-1:-1;27813:12:0;;;;27812:13;27775:50;27767:109;;;;-1:-1:-1;;;27767:109:0;;;;;;;:::i;:::-;27889:19;27912:13;;;;;;27911:14;27936:101;;;;27971:13;:20;;-1:-1:-1;;;;27971:20:0;;;;;28006:19;27987:4;28006:19;;;27936:101;41991:7:::1;:15:::0;;-1:-1:-1;;41991:15:0::1;::::0;;28063:68;;;;28114:5;28098:21;;-1:-1:-1;;28098:21:0;;;41922:92;:::o;39850:106::-;27775:13;;;;;;;;:33;;;27792:16;:14;:16::i;:::-;27775:50;;;-1:-1:-1;27813:12:0;;;;27812:13;27775:50;27767:109;;;;-1:-1:-1;;;27767:109:0;;;;;;;:::i;:::-;27889:19;27912:13;;;;;;27911:14;27936:101;;;;27971:13;:20;;-1:-1:-1;;;;27971:20:0;;;;;28006:19;27987:4;28006:19;;;27936:101;39648:1:::1;39926:7;:22:::0;28063:68;;;;28114:5;28098:21;;-1:-1:-1;;28098:21:0;;;39850:106;:::o;24087:117::-;24150:7;24177:19;24185:3;24177:7;:19::i;1994:192::-;2080:7;2116:12;2108:6;;;;2100:29;;;;-1:-1:-1;;;2100:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;2152:5:0;;;1994:192::o;4020:278::-;4106:7;4141:12;4134:5;4126:28;;;;-1:-1:-1;;;4126:28:0;;;;;;;;:::i;:::-;;4165:9;4181:1;4177;:5;;;;;;;4020:278;-1:-1:-1;;;;;4020:278:0:o;17462:772::-;17897:23;17923:69;17951:4;17923:69;;;;;;;;;;;;;;;;;17931:5;-1:-1:-1;;;;;17923:27:0;;;:69;;;;;:::i;:::-;18007:17;;17897:95;;-1:-1:-1;18007:21:0;18003:224;;18149:10;18138:30;;;;;;;;;;;;:::i;:::-;18130:85;;;;-1:-1:-1;;;18130:85:0;;;;;;;:::i;23289:143::-;23359:4;23383:41;23388:3;-1:-1:-1;;;;;23408:14:0;;23383:4;:41::i;23608:149::-;23681:4;23705:44;23713:3;-1:-1:-1;;;;;23733:14:0;;23705:7;:44::i;22831:204::-;22926:18;;22898:7;;22926:26;-1:-1:-1;22918:73:0;;;;-1:-1:-1;;;22918:73:0;;;;;;;:::i;:::-;23009:3;:11;;23021:5;23009:18;;;;;;;;;;;;;;;;23002:25;;22831:204;;;;:::o;22163:129::-;22236:4;22260:19;;;:12;;;;;:19;;;;;;:24;;;22163:129::o;29594:65::-;27775:13;;;;;;;;:33;;;27792:16;:14;:16::i;:::-;27775:50;;;-1:-1:-1;27813:12:0;;;;27812:13;27775:50;27767:109;;;;-1:-1:-1;;;27767:109:0;;;;;;;:::i;:::-;27889:19;27912:13;;;;;;27911:14;27936:101;;;;27971:13;:20;;-1:-1:-1;;;;27971:20:0;;;;;28006:19;27987:4;28006:19;;;28067:14;28063:68;;;28114:5;28098:21;;-1:-1:-1;;28098:21:0;;;29594:65;:::o;22378:109::-;22461:18;;22378:109::o;12056:196::-;12159:12;12191:53;12214:6;12222:4;12228:1;12231:12;12191:22;:53::i;:::-;12184:60;12056:196;-1:-1:-1;;;;12056:196:0:o;19943:414::-;20006:4;20028:21;20038:3;20043:5;20028:9;:21::i;:::-;20023:327;;-1:-1:-1;20066:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;20249:18;;20227:19;;;:12;;;:19;;;;;;:40;;;;20282:11;;20023:327;-1:-1:-1;20333:5:0;20326:12;;20533:1544;20599:4;20738:19;;;:12;;;:19;;;;;;20774:15;;20770:1300;;21209:18;;-1:-1:-1;;21160:14:0;;;;21209:22;;;;21136:21;;21209:3;;:22;;21496;;;;;;;;;;;;;;21476:42;;21642:9;21613:3;:11;;21625:13;21613:26;;;;;;;;;;;;;;;;;;;:38;;;;21719:23;;;21761:1;21719:12;;;:23;;;;;;21745:17;;;21719:43;;21871:17;;21719:3;;21871:17;;;;;;;;;;;;;;;;;;;;;;21966:3;:12;;:19;21979:5;21966:19;;;;;;;;;;;21959:26;;;22009:4;22002:11;;;;;;;;20770:1300;22053:5;22046:12;;;;;13433:979;13563:12;13596:18;13607:6;13596:10;:18::i;:::-;13588:60;;;;-1:-1:-1;;;13588:60:0;;;;;;;:::i;:::-;13722:12;13736:23;13763:6;-1:-1:-1;;;;;13763:11:0;13783:8;13794:4;13763:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13721:78;;;;13814:7;13810:595;;;13845:10;-1:-1:-1;13838:17:0;;-1:-1:-1;13838:17:0;13810:595;13959:17;;:21;13955:439;;14222:10;14216:17;14283:15;14270:10;14266:2;14262:19;14255:44;14170:148;14365:12;14358:20;;-1:-1:-1;;;14358:20:0;;;;;;;;:::i;9138:422::-;9505:20;9544:8;;;9138:422::o;5:130:-1:-;72:20;;-1:-1;;;;;24309:54;;25592:35;;25582:2;;25641:1;;25631:12;692:241;;796:2;784:9;775:7;771:23;767:32;764:2;;;-1:-1;;802:12;764:2;864:53;909:7;885:22;864:53;:::i;940:491::-;;;;1078:2;1066:9;1057:7;1053:23;1049:32;1046:2;;;-1:-1;;1084:12;1046:2;1146:53;1191:7;1167:22;1146:53;:::i;:::-;1136:63;;1254:53;1299:7;1236:2;1279:9;1275:22;1254:53;:::i;:::-;1244:63;;1362:53;1407:7;1344:2;1387:9;1383:22;1362:53;:::i;:::-;1352:63;;1040:391;;;;;:::o;1438:366::-;;;1559:2;1547:9;1538:7;1534:23;1530:32;1527:2;;;-1:-1;;1565:12;1527:2;1627:53;1672:7;1648:22;1627:53;:::i;:::-;1617:63;1717:2;1756:22;;;;481:20;;-1:-1;;;1521:283::o;1811:257::-;;1923:2;1911:9;1902:7;1898:23;1894:32;1891:2;;;-1:-1;;1929:12;1891:2;223:6;217:13;25738:5;24142:13;24135:21;25716:5;25713:32;25703:2;;-1:-1;;25749:12;2075:241;;2179:2;2167:9;2158:7;2154:23;2150:32;2147:2;;;-1:-1;;2185:12;2147:2;-1:-1;344:20;;2141:175;-1:-1;2141:175::o;2323:366::-;;;2444:2;2432:9;2423:7;2419:23;2415:32;2412:2;;;-1:-1;;2450:12;2412:2;344:20;;;-1:-1;2602:2;2641:22;;72:20;-1:-1;;;;;24309:54;;25592:35;;25582:2;;-1:-1;;25631:12;25582:2;2610:63;;;;2406:283;;;;;:::o;2696:366::-;;;2817:2;2805:9;2796:7;2792:23;2788:32;2785:2;;;-1:-1;;2823:12;2785:2;-1:-1;;344:20;;;2975:2;3014:22;;;481:20;;-1:-1;2779:283::o;3317:263::-;;3432:2;3420:9;3411:7;3407:23;3403:32;3400:2;;;-1:-1;;3438:12;3400:2;-1:-1;629:13;;3394:186;-1:-1;3394:186::o;11982:271::-;;4247:5;23483:12;4358:52;4403:6;4398:3;4391:4;4384:5;4380:16;4358:52;:::i;:::-;4422:16;;;;;12116:137;-1:-1;;12116:137::o;12260:222::-;-1:-1;;;;;24309:54;;;;3807:37;;12387:2;12372:18;;12358:124::o;12734:444::-;-1:-1;;;;;24309:54;;;3807:37;;24309:54;;;;13081:2;13066:18;;3807:37;13164:2;13149:18;;4038:37;;;;12917:2;12902:18;;12888:290::o;13185:333::-;-1:-1;;;;;24309:54;;;;3807:37;;13504:2;13489:18;;4038:37;13340:2;13325:18;;13311:207::o;13525:210::-;24142:13;;24135:21;3921:34;;13646:2;13631:18;;13617:118::o;13742:222::-;4038:37;;;13869:2;13854:18;;13840:124::o;14250:310::-;;14397:2;14418:17;14411:47;4778:5;23483:12;23922:6;14397:2;14386:9;14382:18;23910:19;4872:52;4917:6;23950:14;14386:9;23950:14;14397:2;4898:5;4894:16;4872:52;:::i;:::-;25512:7;25496:14;-1:-1;;25492:28;4936:39;;;;23950:14;4936:39;;14368:192;-1:-1;;14368:192::o;14567:416::-;14767:2;14781:47;;;5212:1;14752:18;;;23910:19;-1:-1;;;23950:14;;;5227:32;5278:12;;;14738:245::o;14990:416::-;15190:2;15204:47;;;5529:2;15175:18;;;23910:19;5565:34;23950:14;;;5545:55;-1:-1;;;5620:12;;;5613:26;5658:12;;;15161:245::o;15413:416::-;15613:2;15627:47;;;5909:2;15598:18;;;23910:19;5945:34;23950:14;;;5925:55;6014:34;6000:12;;;5993:56;6083:26;6069:12;;;6062:48;6129:12;;;15584:245::o;15836:416::-;16036:2;16050:47;;;6380:2;16021:18;;;23910:19;6416:34;23950:14;;;6396:55;-1:-1;;;6471:12;;;6464:39;6522:12;;;16007:245::o;16259:416::-;16459:2;16473:47;;;6773:2;16444:18;;;23910:19;-1:-1;;;23950:14;;;6789:43;6851:12;;;16430:245::o;16682:416::-;16882:2;16896:47;;;7102:2;16867:18;;;23910:19;-1:-1;;;23950:14;;;7118:37;7174:12;;;16853:245::o;17105:416::-;17305:2;17319:47;;;7425:2;17290:18;;;23910:19;7461:29;23950:14;;;7441:50;7510:12;;;17276:245::o;17528:416::-;17728:2;17742:47;;;7761:2;17713:18;;;23910:19;7797:34;23950:14;;;7777:55;-1:-1;;;7852:12;;;7845:40;7904:12;;;17699:245::o;17951:416::-;18151:2;18165:47;;;8155:2;18136:18;;;23910:19;-1:-1;;;23950:14;;;8171:39;8229:12;;;18122:245::o;18374:416::-;18574:2;18588:47;;;8480:2;18559:18;;;23910:19;8516:34;23950:14;;;8496:55;-1:-1;;;8571:12;;;8564:38;8621:12;;;18545:245::o;18797:416::-;18997:2;19011:47;;;8872:2;18982:18;;;23910:19;-1:-1;;;23950:14;;;8888:41;8948:12;;;18968:245::o;19220:416::-;19420:2;19434:47;;;9199:2;19405:18;;;23910:19;-1:-1;;;23950:14;;;9215:40;9274:12;;;19391:245::o;19643:416::-;19843:2;19857:47;;;9525:2;19828:18;;;23910:19;9561:34;23950:14;;;9541:55;-1:-1;;;9616:12;;;9609:25;9653:12;;;19814:245::o;20066:416::-;20266:2;20280:47;;;9904:2;20251:18;;;23910:19;9940:26;23950:14;;;9920:47;9986:12;;;20237:245::o;20489:416::-;20689:2;20703:47;;;10237:2;20674:18;;;23910:19;10273:31;23950:14;;;10253:52;10324:12;;;20660:245::o;20912:416::-;21112:2;21126:47;;;10575:2;21097:18;;;23910:19;10611:34;23950:14;;;10591:55;-1:-1;;;10666:12;;;10659:37;10715:12;;;21083:245::o;21335:416::-;21535:2;21549:47;;;10966:2;21520:18;;;23910:19;11002:34;23950:14;;;10982:55;-1:-1;;;11057:12;;;11050:34;11103:12;;;21506:245::o;21758:416::-;21958:2;21972:47;;;11354:2;21943:18;;;23910:19;11390:33;23950:14;;;11370:54;11443:12;;;21929:245::o;22181:416::-;22381:2;22395:47;;;11694:2;22366:18;;;23910:19;11730:34;23950:14;;;11710:55;-1:-1;;;11785:12;;;11778:39;11836:12;;;22352:245::o;22833:556::-;4038:37;;;23209:2;23194:18;;4038:37;;;;23292:2;23277:18;;4038:37;23375:2;23360:18;;4038:37;23044:3;23029:19;;23015:374::o;25152:268::-;25217:1;25224:101;25238:6;25235:1;25232:13;25224:101;;;25305:11;;;25299:18;25286:11;;;25279:39;25260:2;25253:10;25224:101;;;25340:6;25337:1;25334:13;25331:2;;;-1:-1;;25217:1;25387:16;;25380:27;25201:219::o
Swarm Source
ipfs://fce74a12b8f7511b923180010a268fc7d81c28b6d6b959b997487c91cb0e6934
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.