Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a06040 | 16435102 | 597 days ago | IN | 0 ETH | 0.35814684 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
PowerToken
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-01-18 */ // SPDX-License-Identifier: BSD-3-Clause // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); } // File: contracts/interfaces/IStakedToken.sol pragma solidity 0.8.17; /// @title Interface of the Staked Token. interface IStakedToken is IERC20 { /** * @dev Contract id. * The keccak-256 hash of "io.ipor.IporToken" decreased by 1 */ function getContractId() external pure returns (bytes32); } // File: contracts/libraries/Constants.sol pragma solidity 0.8.17; library Constants { uint256 public constant MAX_VALUE = type(uint256).max; uint256 public constant D10 = 1e10; uint256 public constant D17 = 1e17; uint256 public constant D18 = 1e18; uint256 public constant D19 = 1e19; uint256 public constant D45 = 1e45; } // File: contracts/libraries/math/Math.sol pragma solidity 0.8.17; library Math { //@notice Division with the rounding up on last position, x, and y is with MD function division(uint256 x, uint256 y) internal pure returns (uint256 z) { z = (x + (y / 2)) / y; } } // File: contracts/libraries/errors/Errors.sol pragma solidity 0.8.17; library Errors { /// @notice Error thrown when the lpToken address is not supported /// @dev List of supported LpTokens are defined in {LiquidityMining._lpTokens} string public constant LP_TOKEN_NOT_SUPPORTED = "PT_701"; /// @notice Error thrown when the caller / msgSender is not a PowerToken smart contract string public constant CALLER_NOT_POWER_TOKEN = "PT_702"; /// @notice Error thrown when the caller / msgSender is not a LiquidityMining smart contract string public constant CALLER_NOT_LIQUIDITY_MINING = "PT_703"; /// @notice Error thrown when the caller / msgSender is not a Pause Manager address. /// @dev Pause Manager can be defined by smart contract's Onwer string public constant CALLER_NOT_PAUSE_MANAGER = "PT_704"; /// @notice Error thrown when the account's base balance is too low string public constant ACCOUNT_BASE_BALANCE_IS_TOO_LOW = "PT_705"; /// @notice Error thrown when the account's Lp Token balance is too low string public constant ACCOUNT_LP_TOKEN_BALANCE_IS_TOO_LOW = "PT_706"; /// @notice Error thrown when the account's delegated balance is too low string public constant ACC_DELEGATED_TO_LIQUIDITY_MINING_BALANCE_IS_TOO_LOW = "PT_707"; /// @notice Error thrown when the account's available Power Token balance is too low string public constant ACC_AVAILABLE_POWER_TOKEN_BALANCE_IS_TOO_LOW = "PT_708"; /// @notice Error thrown when the account doesn't have the rewards (Staked Tokens / Power Tokens) to claim string public constant NO_REWARDS_TO_CLAIM = "PT_709"; /// @notice Error thrown when the cooldown is not finished. string public constant COOL_DOWN_NOT_FINISH = "PT_710"; /// @notice Error thrown when the aggregate power up indicator is going to be negative during the calculation. string public constant AGGREGATE_POWER_UP_COULD_NOT_BE_NEGATIVE = "PT_711"; /// @notice Error thrown when the block number used in the function is lower than previous block number stored in the liquidity mining indicators. string public constant BLOCK_NUMBER_LOWER_THAN_PREVIOUS_BLOCK_NUMBER = "PT_712"; /// @notice Account Composite Multiplier indicator is greater or equal to Composit Multiplier indicator, but it should be lower or equal string public constant ACCOUNT_COMPOSITE_MULTIPLIER_GT_COMPOSITE_MULTIPLIER = "PT_713"; /// @notice The fee for unstacking of Power Tokens should be number between (0, 1e18) string public constant UNSTAKE_WITHOUT_COOLDOWN_FEE_IS_TO_HIGH = "PT_714"; /// @notice General problem, address is wrong string public constant WRONG_ADDRESS = "PT_715"; /// @notice General problem, contract is wrong string public constant WRONG_CONTRACT_ID = "PT_716"; /// @notice Value not greater than zero string public constant VALUE_NOT_GREATER_THAN_ZERO = "PT_717"; /// @notice Appeared when input of two arrays length mismatch string public constant INPUT_ARRAYS_LENGTH_MISMATCH = "PT_718"; /// @notice msg.sender is not an appointed owner, it cannot confirm their ownership string public constant SENDER_NOT_APPOINTED_OWNER = "PT_719"; } // File: @openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } } // File: @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // File: @openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @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 proxied contracts do not make use of 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. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } } // File: @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract 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 onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _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 making 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; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: contracts/security/MiningOwnableUpgradeable.sol pragma solidity 0.8.17; contract MiningOwnableUpgradeable is OwnableUpgradeable { address private _appointedOwner; event AppointedToTransferOwnership(address indexed appointedOwner); modifier onlyAppointedOwner() { require(_appointedOwner == _msgSender(), Errors.SENDER_NOT_APPOINTED_OWNER); _; } function transferOwnership(address appointedOwner) public override onlyOwner { require(appointedOwner != address(0), Errors.WRONG_ADDRESS); _appointedOwner = appointedOwner; emit AppointedToTransferOwnership(appointedOwner); } function confirmTransferOwnership() public onlyAppointedOwner { _appointedOwner = address(0); _transferOwnership(_msgSender()); } function renounceOwnership() public virtual override onlyOwner { _transferOwnership(address(0)); _appointedOwner = address(0); } } // File: @openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @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. */ abstract 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 onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { 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()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[45] private __gap; } // File: contracts/interfaces/types/PowerTokenTypes.sol pragma solidity 0.8.17; /// @title Struct used across Liquidity Mining. library PowerTokenTypes { struct PwTokenCooldown { // @dev The timestamp when the account can redeem Power Tokens uint256 endTimestamp; // @dev The amount of Power Tokens which can be redeemed without fee when the cooldown reaches `endTimestamp` uint256 pwTokenAmount; } } // File: contracts/interfaces/IPowerTokenInternal.sol pragma solidity 0.8.17; /// @title PowerToken smart contract interface interface IPowerTokenInternal { /// @notice Returns the current version of the PowerToken smart contract /// @return Current PowerToken smart contract version function getVersion() external pure returns (uint256); /// @notice Gets the total supply base amount /// @return total supply base amount, represented with 18 decimals function totalSupplyBase() external view returns (uint256); /// @notice Calculates the internal exchange rate between the Staked Token and total supply of a base amount /// @return Current exchange rate between the Staked Token and the total supply of a base amount, represented with 18 decimals. function calculateExchangeRate() external view returns (uint256); /// @notice Method for seting up the unstaking fee /// @param unstakeWithoutCooldownFee fee percentage, represented with 18 decimals. function setUnstakeWithoutCooldownFee(uint256 unstakeWithoutCooldownFee) external; /// @notice method allowing for claiming of the rewards /// @param account - address of user claiming rewards /// @param rewardsAmount - amount of rewards, represented with 18 decimals. function receiveRewardsFromLiquidityMining(address account, uint256 rewardsAmount) external; /// @notice method returning address of liquidity rewards contract - the LiquidityMining function getLiquidityMining() external view returns (address); /// @notice method returning address of the Staked Token function getStakedToken() external view returns (address); /// @notice Gets the Pause Manager's address /// @return Pause Manager's address function getPauseManager() external view returns (address); /// @notice method for setting up the address of LiquidityMining /// @param liquidityMining - the new address of the LiquidityMining contract function setLiquidityMining(address liquidityMining) external; /// @notice Sets the new Pause Manager address /// @param newPauseManagerAddr - new Pause Manager's address function setPauseManager(address newPauseManagerAddr) external; /// @notice Pauses the smart contract, it can only be executed by the Owner /// @dev Emits {Paused} event. function pause() external; /// @notice Unpauses the smart contract, it can only be executed by the Owner /// @dev Emits {Unpaused}. function unpause() external; /// @notice Emitted when the user receives rewards from the LiquidityMining /// @dev Receiving rewards does not change Internal Exchange Rate of Power Tokens in PowerToken smart contract. /// @param account address /// @param rewardsAmount amount of Power Tokens received from LiquidityMining event RewardsReceived(address account, uint256 rewardsAmount); /// @notice Emitted when the fee for immediate unstaking is modified. /// @param changedBy account address that changed the configuration /// @param oldFee old value of the fee, represented with 18 decimals /// @param newFee new value of the fee, represented with 18 decimals event UnstakeWithoutCooldownFeeChanged( address indexed changedBy, uint256 oldFee, uint256 newFee ); /// @notice Emmited when PauseManager's address had been changed by its owner. /// @param changedBy account address that has changed the LiquidityMining's address /// @param oldLiquidityMining PauseManager's old address /// @param newLiquidityMining PauseManager's new address event LiquidityMiningChanged( address indexed changedBy, address indexed oldLiquidityMining, address indexed newLiquidityMining ); /// @notice Emmited when the PauseManager's address is changed by its owner. /// @param changedBy account address that has changed the LiquidityMining's address /// @param oldPauseManager PauseManager's old address /// @param newPauseManager PauseManager's new address event PauseManagerChanged( address indexed changedBy, address indexed oldPauseManager, address indexed newPauseManager ); } // File: contracts/interfaces/IPowerToken.sol pragma solidity 0.8.17; /// @title The Interface for the interaction with the PowerToken - smart contract responsible /// for managing Power Token (pwToken), Swapping Staked Token for Power Tokens, and /// delegating Power Tokens to other components. interface IPowerToken { /// @notice Gets the name of the Power Token /// @return Returns the name of the Power Token. function name() external pure returns (string memory); /// @notice Contract ID. The keccak-256 hash of "io.ipor.PowerToken" decreased by 1 /// @return Returns the ID of the contract function getContractId() external pure returns (bytes32); /// @notice Gets the symbol of the Power Token. /// @return Returns the symbol of the Power Token. function symbol() external pure returns (string memory); /// @notice Returns the number of the decimals used by Power Token. By default it's 18 decimals. /// @return Returns the number of decimals: 18. function decimals() external pure returns (uint8); /// @notice Gets the total supply of the Power Token. /// @dev Value is calculated in runtime using baseTotalSupply and internal exchange rate. /// @return Total supply of Power tokens, represented with 18 decimals function totalSupply() external view returns (uint256); /// @notice Gets the balance of Power Tokens for a given account /// @param account account address for which the balance of Power Tokens is fetched /// @return Returns the amount of the Power Tokens owned by the `account`. function balanceOf(address account) external view returns (uint256); /// @notice Gets the delegated balance of the Power Tokens for a given account. /// Tokens are delegated from PowerToken to LiquidityMining smart contract (reponsible for rewards distribution). /// @param account account address for which the balance of delegated Power Tokens is checked /// @return Returns the amount of the Power Tokens owned by the `account` and delegated to the LiquidityMining contracts. function delegatedToLiquidityMiningBalanceOf(address account) external view returns (uint256); /// @notice Gets the rate of the fee from the configuration. This fee is applied when the owner of Power Tokens wants to unstake them immediately. /// @dev Fee value represented in as a percentage with 18 decimals /// @return value, a percentage represented with 18 decimal function getUnstakeWithoutCooldownFee() external view returns (uint256); /// @notice Gets the state of the active cooldown for the sender. /// @dev If PowerTokenTypes.PowerTokenCoolDown contains only zeros it represents no active cool down. /// Struct containing information on when the cooldown end and what is the quantity of the Power Tokens locked. /// @param account account address that owns Power Tokens in the cooldown /// @return Object PowerTokenTypes.PowerTokenCoolDown represents active cool down function getActiveCooldown(address account) external view returns (PowerTokenTypes.PwTokenCooldown memory); /// @notice Stakes [Staked] Tokens and mints Power Tokens (pwToken). /// @param stakedTokenAmount Tokens that sender staked to mint the Power Tokens function stake(uint256 stakedTokenAmount) external; /// @notice Unstakes Staked Tokens in the amount specified. /// @dev If the sender unstake tokens immediately (without the cooldown), then fee is applied by the PowerToken smart contract. See: `UnstakeWithoutCooldownFee`. /// @param pwTokenAmount Power Tokens amount which will be unstake or a given sender function unstake(uint256 pwTokenAmount) external; /// @notice Delegates the Power Tokens to the LiquidityMining /// @param lpTokens - list of lpTokens to which Power Tokens are delegated /// @param pwTokenAmounts - list of the amounts of Power Tokens delegated to correspondng lpTokens function delegateToLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external; /// @notice Delegates Power Tokens and stakes lpTokens /// @dev Power Token amounts can equal zero. lpToken amounts can qual zero. /// @param lpTokens - list of lpTokens to which the sender delegates Power Tokens /// @param pwTokenAmounts - list of the amounts of Power Tokens delegated to correspondng lpTokens /// @param lpTokenAmounts - list of staked lpToken amounts function delegateAndStakeToLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts, uint256[] calldata lpTokenAmounts ) external; /// @notice Undelegates the Power Tokens from the LiquidityMining /// @dev Power Token amounts have to be higher than zero, otherwise transaction is reverted. /// @param lpTokens - list of the lpToken from which Power Tokens are undelegated /// @param pwTokenAmounts - list of the undelegated amounts of the Power Tokens function undelegateFromLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external; /// @notice Resets the colldown of Power Tokens to the set duration of 2 weeks. /// @dev Power Tokens in cooldown cannot be unstaked without fee, /// when the cooldown is elapsed then Power Tokens can be unstaked without fee. /// Fee for immediate unstaking (without cooldown) is configured in param `_unstakeWithoutCooldownFee` /// Power Tokens can be redeemed for Staked Tokens in relation of 1:1. /// @param pwTokenAmount Power Token amount to be set in the cooldown function cooldown(uint256 pwTokenAmount) external; /// @notice Cancel the cooldown. /// @dev When this method is executed, all Power Tokens are released. function cancelCooldown() external; /// @notice The method allowing redemption of Power Tokens for the Staked Token after cooldown has passed. /// @dev Power Tokens are redeemable for Staked tokens at 1:1 ratio. /// @dev When the sender executes `redeem` method then the structure {PowerTokenTypes.PwTokenCoolDown} is cleared for a given sender in `_coolDowns` storage. function redeem() external; /// @notice Emitted when the account stakes [Staked] Tokens /// @param account account address that executed the staking /// @param stakedTokenAmount of Staked Token amount being staked into PowerToken contract /// @param internalExchangeRate internal exchange rate used to calculate the base amount /// @param baseAmount value calculated based on the stakedTokenAmount and the internalExchangeRate event Staked( address indexed account, uint256 stakedTokenAmount, uint256 internalExchangeRate, uint256 baseAmount ); /// @notice Emitted when the account unstakes the Power Tokens /// @param account address that executed the unstaking /// @param pwTokenAmount amount of Power Tokens that were unstaked /// @param internalExchangeRate which was used to calculate the base amount /// @param fee amount subtracted from the pwTokenAmount event Unstaked( address indexed account, uint256 pwTokenAmount, uint256 internalExchangeRate, uint256 fee ); /// @notice Emitted when the sender delegates the Power Tokens to the LiquidityMining contract /// @param account address delegating the Power Tokens /// @param lpTokens list of the tokens representing staking pools /// @param pwTokenAmounts amounts of Power Tokens delegated to respective lpTokens event ToLiquidityMiningDelegated( address indexed account, address[] lpTokens, uint256[] pwTokenAmounts ); /// @notice Emitted when the sender undelegates Power Tokens from the LiquidityMining /// @param account address undelegating Power Tokens /// @param lpTokens list of the tokens representing staking pools /// @param pwTokenAmounts amounts of Power Tokens undelegated form respective lpTokens event FromLiquidityMiningUndelegated( address indexed account, address[] lpTokens, uint256[] pwTokenAmounts ); /// @notice Emitted when the sender sets the cooldown on Power Tokens /// @param changedBy account address that has changed the cooldown rules /// @param pwTokenAmount amount of pwToken in cooldown /// @param endTimestamp end time of the cooldown event CooldownChanged(address indexed changedBy, uint256 pwTokenAmount, uint256 endTimestamp); /// @notice Emitted when the sender redeems the pwTokens after the cooldown /// @param account address that executed the redeem function /// @param pwTokenAmount amount of the pwTokens that was transferred to the Power Token owner's address event Redeem(address indexed account, uint256 pwTokenAmount); } // File: contracts/interfaces/types/LiquidityMiningTypes.sol pragma solidity 0.8.17; /// @title Structures used in the LiquidityMining. library LiquidityMiningTypes { /// @title Struct pair representing delegated pwToken balance struct DelegatedPwTokenBalance { /// @notice lpToken address address lpToken; /// @notice The amount of Power Token delegated to lpToken staking pool /// @dev value represented in 18 decimals uint256 pwTokenAmount; } /// @title Global indicators used in rewards calculation. struct GlobalRewardsIndicators { /// @notice powerUp indicator aggregated /// @dev It can be changed many times during transaction, represended with 18 decimals uint256 aggregatedPowerUp; /// @notice composite multiplier in a block described in field blockNumber /// @dev It can be changed many times during transaction, represented with 27 decimals uint128 compositeMultiplierInTheBlock; /// @notice Composite multiplier updated in block {blockNumber} but calculated for PREVIOUS (!) block. /// @dev It can be changed once per block, represented with 27 decimals uint128 compositeMultiplierCumulativePrevBlock; /// @dev It can be changed once per block. Block number in which all other params of this structure are updated uint32 blockNumber; /// @notice value describing amount of rewards issued per block, /// @dev It can be changed at most once per block, represented with 8 decimals uint32 rewardsPerBlock; /// @notice amount of accrued rewards since inception /// @dev It can be changed at most once per block, represented with 8 decimals uint88 accruedRewards; } /// @title Params recorded for a given account. These params are used by the algorithm responsible for rewards distribution. /// @dev The structure in storage is updated when account interacts with the LiquidityMining smart contract (stake, unstake, delegate, undelegate, claim) struct AccountRewardsIndicators { /// @notice `composite multiplier cumulative` is calculated for previous block /// @dev represented in 27 decimals uint128 compositeMultiplierCumulativePrevBlock; /// @notice lpToken account's balance uint128 lpTokenBalance; /// @notive PowerUp is a result of logarithmic equastion, /// @dev powerUp < 100 *10^18 uint72 powerUp; /// @notice balance of Power Tokens delegated to LiquidityMining /// @dev delegatedPwTokenBalance < 10^26 < 2^87 uint96 delegatedPwTokenBalance; } } // File: contracts/interfaces/ILiquidityMining.sol pragma solidity 0.8.17; /// @title The interface for interaction with the LiquidityMining. /// LiquidityMining is responsible for the distribution of the Power Token rewards to accounts /// staking lpTokens and / or delegating Power Tokens to LiquidityMining. LpTokens can be staked directly to the LiquidityMining, /// Power Tokens are a staked version of the [Staked] Tokens minted by the PowerToken smart contract. interface ILiquidityMining { /// @notice Contract ID. The keccak-256 hash of "io.ipor.LiquidityMining" decreased by 1 /// @return Returns an ID of the contract function getContractId() external pure returns (bytes32); /// @notice Returns the balance of staked lpTokens /// @param account the account's address /// @param lpToken the address of lpToken /// @return balance of the lpTokens staked by the sender function balanceOf(address account, address lpToken) external view returns (uint256); /// @notice It returns the balance of delegated Power Tokens for a given `account` and the list of lpToken addresses. /// @param account address for which to fetch the information about balance of delegated Power Tokens /// @param lpTokens list of lpTokens addresses(lpTokens) /// @return balances list of {LiquidityMiningTypes.DelegatedPwTokenBalance} structure, with information how much Power Token is delegated per lpToken address. function balanceOfDelegatedPwToken(address account, address[] memory lpTokens) external view returns (LiquidityMiningTypes.DelegatedPwTokenBalance[] memory balances); /// @notice Gets the account's allocated rewards /// @param account The address for which to fetch information about balance of allocated Power Tokens /// @return allocatedPwTokens - The amount of the allocated rewards. function balanceOfAllocatedPwTokens(address account) external view returns (uint256 allocatedPwTokens); /// @notice Calculates the accrued rewards since the last rebalancing. /// @param lpToken the lpToken address /// @return rewards accrued since the last rebalancing, represented with 18 decimals. function calculateAccruedRewards(address lpToken) external view returns (uint256); /// @notice Calculates account's rewards based on the current state of the sender and global indicators. /// @dev Calculation does not consider rewards accrued for the current block /// @param account address for which the rewards are calculated /// @param lpToken address for which the rewards are calculated /// @return Sender's rewards, represented with 18 decimals. function calculateAccountRewards(address account, address lpToken) external view returns (uint256); /// @notice Stakes the lpToken amount into the LiquidityMining. /// @param lpToken address of the lpToken /// @param lpTokenAmount lpToken amount being staked, represented with 18 decimals function stake(address lpToken, uint256 lpTokenAmount) external; /// @notice Unstakes the lpToken amount from the LiquidityMining. /// @param lpToken address of the underlying asset /// @param lpTokenAmount lpToken amount being unstaked, represented with 18 decimals function unstake(address lpToken, uint256 lpTokenAmount) external; /// @notice Unstakes the lpToken amount from LiquidityMining and allocates the rewards into storage. /// This function can be used in the situation, when the are not enoguh rewards to cover claim and where /// regular unstake of lpTokens would not be possible. /// @param lpToken address of the underlying asset /// @param lpTokenAmount lpToken amount being unstaked, represented with 18 decimals function unstakeAndAllocatePwTokens(address lpToken, uint256 lpTokenAmount) external; /// @notice method allowing to claim the rewards per asset (lpToken) /// @param lpToken of the staking pool from which to claim the rewards function claim(address lpToken) external; /// @notice method allowed to claim the allocated rewards function claimAllocatedPwTokens() external; /// @notice Emitted when the account stakes the lpTokens /// @param account Account's address in the context of which the activities of staking of lpTokens are performed /// @param lpToken address of lpToken being staked /// @param lpTokenAmount of lpTokens to stake, represented with 18 decimals event LpTokensStaked(address account, address lpToken, uint256 lpTokenAmount); /// @notice Emitted when the account claims the rewards /// @param account Account's address in the context of which activities of claiming are performed /// @param lpToken The address of the lpToken /// @param rewardsAmount Reward amount denominated in pwToken, represented with 18 decimals event Claimed(address account, address lpToken, uint256 rewardsAmount); /// @notice Emitted when the account claims the allocated rewards /// @param account Account address in the context of which activities of claiming are performed /// @param allocatedRewards Reward amount denominated in pwToken, represented in 18 decimals event AllocatedTokensClaimed(address account, uint256 allocatedRewards); } // File: contracts/tokens/PowerTokenInternal.sol pragma solidity 0.8.17; abstract contract PowerTokenInternal is PausableUpgradeable, UUPSUpgradeable, ReentrancyGuardUpgradeable, MiningOwnableUpgradeable, IPowerTokenInternal { /// @dev 14 days uint256 public constant COOL_DOWN_IN_SECONDS = 2 * 7 * 24 * 60 * 60; bytes32 internal constant _STAKED_TOKEN_ID = 0xdba05ed67d0251facfcab8345f27ccd3e72b5a1da8cebfabbcccf4316e6d053c; bytes32 internal constant _LIQUIDITY_MINING_ID = 0x9b1f3aa590476fc9aa58d44ad1419ab53d34c344bd5ed46b12e4af7d27c38e06; address internal _liquidityMining; address internal _stakedToken; address internal _pauseManager; /// @dev account address -> base amount, represented with 18 decimals mapping(address => uint256) internal _baseBalance; /// @dev balance of Power Token delegated to LiquidityMining, information per account, balance represented with 18 decimals mapping(address => uint256) internal _delegatedToLiquidityMiningBalance; // account address -> {endTimestamp, amount} mapping(address => PowerTokenTypes.PwTokenCooldown) internal _cooldowns; uint256 internal _baseTotalSupply; uint256 internal _unstakeWithoutCooldownFee; modifier onlyLiquidityMining() { require(_msgSender() == _liquidityMining, Errors.CALLER_NOT_LIQUIDITY_MINING); _; } modifier onlyPauseManager() { require(_msgSender() == _pauseManager, Errors.CALLER_NOT_PAUSE_MANAGER); _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize(address stakedToken) public initializer { __Pausable_init_unchained(); __Ownable_init_unchained(); __UUPSUpgradeable_init_unchained(); require(stakedToken != address(0), Errors.WRONG_ADDRESS); require( IStakedToken(stakedToken).getContractId() == _STAKED_TOKEN_ID, Errors.WRONG_CONTRACT_ID ); _stakedToken = stakedToken; _pauseManager = _msgSender(); _unstakeWithoutCooldownFee = Constants.D17 * 5; } function getVersion() external pure override returns (uint256) { return 1; } function totalSupplyBase() external view override returns (uint256) { return _baseTotalSupply; } function calculateExchangeRate() external view override returns (uint256) { return _calculateInternalExchangeRate(_stakedToken); } function getLiquidityMining() external view override returns (address) { return _liquidityMining; } function getStakedToken() external view override returns (address) { return _stakedToken; } function getPauseManager() external view override returns (address) { return _pauseManager; } function setUnstakeWithoutCooldownFee(uint256 unstakeWithoutCooldownFee) external override onlyOwner { require( unstakeWithoutCooldownFee <= Constants.D18, Errors.UNSTAKE_WITHOUT_COOLDOWN_FEE_IS_TO_HIGH ); uint256 oldValue = _unstakeWithoutCooldownFee; _unstakeWithoutCooldownFee = unstakeWithoutCooldownFee; emit UnstakeWithoutCooldownFeeChanged(_msgSender(), oldValue, unstakeWithoutCooldownFee); } function setLiquidityMining(address newLiquidityMiningAddr) external override onlyOwner { require(newLiquidityMiningAddr != address(0), Errors.WRONG_ADDRESS); require( ILiquidityMining(newLiquidityMiningAddr).getContractId() == _LIQUIDITY_MINING_ID, Errors.WRONG_CONTRACT_ID ); address oldLiquidityMiningAddr = _liquidityMining; _liquidityMining = newLiquidityMiningAddr; emit LiquidityMiningChanged(_msgSender(), oldLiquidityMiningAddr, newLiquidityMiningAddr); } function setPauseManager(address newPauseManagerAddr) external override onlyOwner { require(newPauseManagerAddr != address(0), Errors.WRONG_ADDRESS); address oldPauseManagerAddr = _pauseManager; _pauseManager = newPauseManagerAddr; emit PauseManagerChanged(_msgSender(), oldPauseManagerAddr, newPauseManagerAddr); } function receiveRewardsFromLiquidityMining(address account, uint256 rewardsAmount) external override whenNotPaused onlyLiquidityMining { address stakedTokenAddress = _stakedToken; /// @dev This value is needed before the tokens transfer uint256 exchangeRate = _calculateInternalExchangeRate(stakedTokenAddress); require(rewardsAmount > 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); IERC20Upgradeable(stakedTokenAddress).transferFrom( _msgSender(), address(this), rewardsAmount ); uint256 baseAmount = Math.division(rewardsAmount * Constants.D18, exchangeRate); _baseBalance[account] += baseAmount; _baseTotalSupply += baseAmount; emit RewardsReceived(account, rewardsAmount); } function pause() external override onlyPauseManager { _pause(); } function unpause() external override onlyPauseManager { _unpause(); } function _calculateInternalExchangeRate(address stakedTokenAddress) internal view returns (uint256) { uint256 baseTotalSupply = _baseTotalSupply; if (baseTotalSupply == 0) { return Constants.D18; } uint256 balanceOfStakedToken = IERC20Upgradeable(stakedTokenAddress).balanceOf( address(this) ); if (balanceOfStakedToken == 0) { return Constants.D18; } return Math.division(balanceOfStakedToken * Constants.D18, baseTotalSupply); } function _calculateAmountWithCooldownFeeSubtracted(uint256 baseAmount) internal view returns (uint256) { return Math.division((Constants.D18 - _unstakeWithoutCooldownFee) * baseAmount, Constants.D18); } function _calculateBaseAmountToPwToken(uint256 baseAmount, uint256 exchangeRate) internal pure returns (uint256) { return Math.division(baseAmount * exchangeRate, Constants.D18); } function _getAvailablePwTokenAmount(address account, uint256 exchangeRate) internal view returns (uint256) { return _calculateBaseAmountToPwToken(_baseBalance[account], exchangeRate) - _delegatedToLiquidityMiningBalance[account] - _cooldowns[account].pwTokenAmount; } function _balanceOf(address account) internal view returns (uint256) { return _calculateBaseAmountToPwToken( _baseBalance[account], _calculateInternalExchangeRate(_stakedToken) ); } //solhint-disable no-empty-blocks function _authorizeUpgrade(address) internal override onlyOwner {} } // File: contracts/interfaces/ILiquidityMiningInternal.sol pragma solidity 0.8.17; /// @title The interface for interaction with the LiquidityMining contract. Contains mainly technical methods or methods used by PowerToken smart contract. interface ILiquidityMiningInternal { /// @notice Returns the current version of the LiquidityMining contract /// @return Current LiquidityMining (Liquidity Rewards) version function getVersion() external pure returns (uint256); /// @notice Gets the Pause Manager's address /// @return Pause Manager's address function getPauseManager() external view returns (address); /// @notice Checks if lpToken is supported by the liquidity mining module. /// @param lpToken lpToken address /// @return returns true if lpToken is supported by the LiquidityMining, false otherwise function isLpTokenSupported(address lpToken) external view returns (bool); /// @notice Gets the global indicators for a given lpToken /// @param lpToken lpToken address /// @return {LiquidityMiningTypes.GlobalRewardsIndicators} structure with global indicators used in the rewards calculation. function getGlobalIndicators(address lpToken) external view returns (LiquidityMiningTypes.GlobalRewardsIndicators memory); /// @notice Gets the sender's rewards indicators for a given lpToken /// @param account account's address /// @param lpToken lpToken address /// @return {LiquidityMiningTypes.AccountRewardsIndicators} structure with the sender rewards indicators used in rewards calculation. function getAccountIndicators(address account, address lpToken) external view returns (LiquidityMiningTypes.AccountRewardsIndicators memory); /// @notice Delegates the Power Tokens of s given account to LiquidityMining smart contract. /// @param account account address delegating its Power Tokens to LiquidityMining /// @param lpTokens list of lpToken addresses to which Power Tokens are delegated /// @param pwTokenAmount list of Power Token amounts for delegated to given lpTokens, represented with 18 decimals function delegatePwToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmount ) external; /// @notice Delegates the Power Tokens an stakes lpTokens in LiquidityMining. /// @dev Power Token amounts can equal zero. lpToken amounts can equal zero. /// @param account account address delegating its Power Tokens and staking lpTokens in LiquidityMining /// @param lpTokens list of the lpToken addresses to which Power Tokens are delegated /// @param pwTokenAmounts list of the Power Token amounts delegated , represented with 18 decimals /// @param lpTokenAmounts list of the lpToken amounts to be staked in liquidityMining, represented with 18 decimals function delegatePwTokenAndStakeLpToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmounts, uint256[] calldata lpTokenAmounts ) external; /// @notice Undelegates the Power Tokens from the LiquidityMining /// @dev Power Token amounts can equal zero. /// @param account address undelegating Power Tokens /// @param lpTokens list of the lpTokens reprenseting staking pools from which to undelegate Power Tokens /// @param pwTokenAmounts list of the amounts of Power Tokens to be undelegated, represented with 18 decimals function undelegatePwToken( address account, address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external; /// @notice Sets the global configuration indicator - rewardsPerBlock for a given lpToken /// @param lpToken address for which to setup `rewards per block` /// @param pwTokenAmount amount of the `rewards per block`, denominated in Power Token, represented with 8 decimals function setRewardsPerBlock(address lpToken, uint32 pwTokenAmount) external; /// @notice Adds LiquidityMining's support for a new lpToken /// @dev Can only be executed by the Owner /// @param lpToken address of the lpToken function addLpToken(address lpToken) external; /// @notice Removes lpToken from the list of tokens supported by the LiquidityMining contract /// @dev Can be executed only by the Owner. Note! That when lpToken is removed, the rewards cannot be claimed. To restore claiming, run function {addLpToken()} and {setRewardsPerBlock()} /// @param lpToken address of the lpToken function removeLpToken(address lpToken) external; /// @notice Sets the new Pause Manager address /// @param newPauseManagerAddr - new address of Pause Manager function setPauseManager(address newPauseManagerAddr) external; /// @notice Pauses current smart contract, it can only be executed by the Owner /// @dev Emits {Paused} event. function pause() external; /// @notice Unpauses current smart contract, it can only be executed by the Owner /// @dev Emits {Unpaused}. function unpause() external; /// @notice Emitted when the account unstakes lpTokens /// @param account account unstaking tokens /// @param lpToken address of lpToken being unstaked /// @param lpTokenAmount of lpTokens to unstake, represented with 18 decimals event LpTokensUnstaked(address account, address lpToken, uint256 lpTokenAmount); /// @notice Emitted when the LiquidityMining's Owner changes the `rewards per block` /// @param changedBy address of account executing changes /// @param oldPwTokenAmount old value of `rewards per block`, denominated in Power Token, represented in 8 decimals /// @param newPwTokenAmount new value of `rewards per block`, denominated in Power Token, represented in 8 decimals event RewardsPerBlockChanged( address indexed changedBy, uint256 oldPwTokenAmount, uint256 newPwTokenAmount ); /// @notice Emitted when the LiquidityMining's Owner adds support for lpToken /// @param account address of LiquidityMining's Owner /// @param lpToken address of newly supported lpToken event LpTokenAdded(address account, address lpToken); /// @notice Emitted when the LiquidityMining's Owner removes ssupport for lpToken /// @param account address of LiquidityMining's Owner /// @param lpToken address of dropped lpToken event LpTokenRemoved(address account, address lpToken); /// @notice Emitted when the account delegates Power Tokens to the LiquidityMining /// @param account performing delegation /// @param lpToken address of lpToken to which Power Token are delegated /// @param pwTokenAmount amount of Power Tokens delegated, represented with 18 decimals event PwTokenDelegated(address account, address lpToken, uint256 pwTokenAmount); /// @notice Emitted when the account delegates Power Tokens and stakes lpTokens to the LiquidityMining /// @param account account delegating Power Tokens and staking lpTokens /// @param lpToken address of lpToken staked /// @param pwTokenAmount of Power Token delegated, represented with 18 decimals /// @param lpTokenAmount of lpTokens to stake, represented with 18 decimals event PwTokenDelegatedAndLpTokenStaked( address account, address lpToken, uint256 pwTokenAmount, uint256 lpTokenAmount ); /// @notice Emitted when the account undelegates Power Tokens from the LiquidityMining /// @param account undelegating /// @param lpToken address of lpToken /// @param pwTokenAmount amount of Power Token undelegated, represented with 18 decimals event PwTokenUndelegated(address account, address lpToken, uint256 pwTokenAmount); /// @notice Emitted when the PauseManager's address is changed by its owner. /// @param changedBy account address that has changed LiquidityMining's address /// @param oldPauseManager PauseManager's old address /// @param newPauseManager PauseManager's new address event PauseManagerChanged( address indexed changedBy, address indexed oldPauseManager, address indexed newPauseManager ); } // File: contracts/tokens/PowerToken.sol pragma solidity 0.8.17; ///@title Smart contract responsible for managing Power Token. /// @notice Power Token is retrieved when the account stakes [Staked] Token. /// PowerToken smart contract allows staking, unstaking of [Staked] Token, delegating, undelegating of Power Token balance to LiquidityMining. contract PowerToken is PowerTokenInternal, IPowerToken { function name() external pure override returns (string memory) { return "Power IPOR"; } function symbol() external pure override returns (string memory) { return "pwIPOR"; } function decimals() external pure override returns (uint8) { return 18; } function getContractId() external pure returns (bytes32) { return 0xbd22bf01cb7daed462db61de31bb111aabcdae27adc748450fb9a9ea1c419cce; } function totalSupply() external view override returns (uint256) { return Math.division( _baseTotalSupply * _calculateInternalExchangeRate(_stakedToken), Constants.D18 ); } function balanceOf(address account) external view override returns (uint256) { return _balanceOf(account); } function delegatedToLiquidityMiningBalanceOf(address account) external view override returns (uint256) { return _delegatedToLiquidityMiningBalance[account]; } function getUnstakeWithoutCooldownFee() external view override returns (uint256) { return _unstakeWithoutCooldownFee; } function getActiveCooldown(address account) external view returns (PowerTokenTypes.PwTokenCooldown memory) { return _cooldowns[account]; } function stake(uint256 stakedTokenAmount) external override whenNotPaused nonReentrant { require(stakedTokenAmount != 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); address stakedTokenAddress = _stakedToken; address msgSender = _msgSender(); uint256 exchangeRate = _calculateInternalExchangeRate(stakedTokenAddress); IERC20Upgradeable(stakedTokenAddress).transferFrom( msgSender, address(this), stakedTokenAmount ); uint256 baseAmount = Math.division(stakedTokenAmount * Constants.D18, exchangeRate); _baseBalance[msgSender] += baseAmount; _baseTotalSupply += baseAmount; emit Staked(msgSender, stakedTokenAmount, exchangeRate, baseAmount); } function unstake(uint256 pwTokenAmount) external override whenNotPaused nonReentrant { require(pwTokenAmount > 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); address stakedTokenAddress = _stakedToken; address msgSender = _msgSender(); uint256 exchangeRate = _calculateInternalExchangeRate(stakedTokenAddress); uint256 availablePwTokenAmount = _getAvailablePwTokenAmount(msgSender, exchangeRate); require( availablePwTokenAmount >= pwTokenAmount, Errors.ACC_AVAILABLE_POWER_TOKEN_BALANCE_IS_TOO_LOW ); uint256 baseAmountToUnstake = Math.division(pwTokenAmount * Constants.D18, exchangeRate); require( _baseBalance[msgSender] >= baseAmountToUnstake, Errors.ACCOUNT_BASE_BALANCE_IS_TOO_LOW ); _baseBalance[msgSender] -= baseAmountToUnstake; _baseTotalSupply -= baseAmountToUnstake; uint256 stakedTokenAmountToTransfer = _calculateBaseAmountToPwToken( _calculateAmountWithCooldownFeeSubtracted(baseAmountToUnstake), exchangeRate ); IERC20Upgradeable(stakedTokenAddress).transfer(msgSender, stakedTokenAmountToTransfer); emit Unstaked( msgSender, pwTokenAmount, exchangeRate, pwTokenAmount - stakedTokenAmountToTransfer ); } function delegateToLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external override whenNotPaused nonReentrant { uint256 pwTokenAmountsLength = pwTokenAmounts.length; require(lpTokens.length == pwTokenAmountsLength, Errors.INPUT_ARRAYS_LENGTH_MISMATCH); uint256 pwTokenToDelegate; for (uint256 i; i != pwTokenAmountsLength; ++i) { pwTokenToDelegate += pwTokenAmounts[i]; } require( _getAvailablePwTokenAmount( _msgSender(), _calculateInternalExchangeRate(_stakedToken) ) >= pwTokenToDelegate, Errors.ACC_AVAILABLE_POWER_TOKEN_BALANCE_IS_TOO_LOW ); _delegatedToLiquidityMiningBalance[_msgSender()] += pwTokenToDelegate; ILiquidityMiningInternal(_liquidityMining).delegatePwToken( _msgSender(), lpTokens, pwTokenAmounts ); emit ToLiquidityMiningDelegated(_msgSender(), lpTokens, pwTokenAmounts); } function delegateAndStakeToLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts, uint256[] calldata lpTokenAmounts ) external override whenNotPaused nonReentrant { require( lpTokens.length == pwTokenAmounts.length && lpTokens.length == lpTokenAmounts.length, Errors.INPUT_ARRAYS_LENGTH_MISMATCH ); uint256 pwTokenToDelegate; uint256 pwTokenAmountsLength = pwTokenAmounts.length; for (uint256 i; i != pwTokenAmountsLength; ++i) { pwTokenToDelegate += pwTokenAmounts[i]; } require( _getAvailablePwTokenAmount( _msgSender(), _calculateInternalExchangeRate(_stakedToken) ) >= pwTokenToDelegate, Errors.ACC_AVAILABLE_POWER_TOKEN_BALANCE_IS_TOO_LOW ); _delegatedToLiquidityMiningBalance[_msgSender()] += pwTokenToDelegate; ILiquidityMiningInternal(_liquidityMining).delegatePwTokenAndStakeLpToken( _msgSender(), lpTokens, pwTokenAmounts, lpTokenAmounts ); emit ToLiquidityMiningDelegated(_msgSender(), lpTokens, pwTokenAmounts); } function undelegateFromLiquidityMining( address[] calldata lpTokens, uint256[] calldata pwTokenAmounts ) external override whenNotPaused nonReentrant { uint256 lpTokensLength = lpTokens.length; require(lpTokensLength == pwTokenAmounts.length, Errors.INPUT_ARRAYS_LENGTH_MISMATCH); uint256 pwTokenAmountToUndelegate; for (uint256 i; i != lpTokensLength; ++i) { require(pwTokenAmounts[i] > 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); pwTokenAmountToUndelegate += pwTokenAmounts[i]; } address msgSender = _msgSender(); require( _delegatedToLiquidityMiningBalance[msgSender] >= pwTokenAmountToUndelegate, Errors.ACC_DELEGATED_TO_LIQUIDITY_MINING_BALANCE_IS_TOO_LOW ); ILiquidityMiningInternal(_liquidityMining).undelegatePwToken( msgSender, lpTokens, pwTokenAmounts ); _delegatedToLiquidityMiningBalance[msgSender] -= pwTokenAmountToUndelegate; emit FromLiquidityMiningUndelegated(msgSender, lpTokens, pwTokenAmounts); } function cooldown(uint256 pwTokenAmount) external override whenNotPaused nonReentrant { require(pwTokenAmount > 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); address msgSender = _msgSender(); uint256 availablePwTokenAmount = _calculateBaseAmountToPwToken( _baseBalance[msgSender], _calculateInternalExchangeRate(_stakedToken) ) - _delegatedToLiquidityMiningBalance[msgSender]; require( availablePwTokenAmount >= pwTokenAmount, Errors.ACC_AVAILABLE_POWER_TOKEN_BALANCE_IS_TOO_LOW ); _cooldowns[msgSender] = PowerTokenTypes.PwTokenCooldown( block.timestamp + COOL_DOWN_IN_SECONDS, pwTokenAmount ); emit CooldownChanged(msgSender, pwTokenAmount, block.timestamp + COOL_DOWN_IN_SECONDS); } function cancelCooldown() external override whenNotPaused { delete _cooldowns[_msgSender()]; emit CooldownChanged(_msgSender(), 0, 0); } function redeem() external override whenNotPaused nonReentrant { address msgSender = _msgSender(); PowerTokenTypes.PwTokenCooldown memory accountCooldown = _cooldowns[msgSender]; require(block.timestamp >= accountCooldown.endTimestamp, Errors.COOL_DOWN_NOT_FINISH); require(accountCooldown.pwTokenAmount > 0, Errors.VALUE_NOT_GREATER_THAN_ZERO); address stakedTokenAddress = _stakedToken; uint256 exchangeRate = _calculateInternalExchangeRate(stakedTokenAddress); uint256 baseAmountToUnstake = Math.division( accountCooldown.pwTokenAmount * Constants.D18, exchangeRate ); require( _baseBalance[msgSender] >= baseAmountToUnstake, Errors.ACCOUNT_BASE_BALANCE_IS_TOO_LOW ); _baseBalance[msgSender] -= baseAmountToUnstake; _baseTotalSupply -= baseAmountToUnstake; delete _cooldowns[msgSender]; ///@dev We can transfer pwTokenAmount because it is in relation 1:1 to Staked Token IERC20Upgradeable(stakedTokenAddress).transfer(msgSender, accountCooldown.pwTokenAmount); emit Redeem(msgSender, accountCooldown.pwTokenAmount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"appointedOwner","type":"address"}],"name":"AppointedToTransferOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"changedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"pwTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTimestamp","type":"uint256"}],"name":"CooldownChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address[]","name":"lpTokens","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"}],"name":"FromLiquidityMiningUndelegated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"changedBy","type":"address"},{"indexed":true,"internalType":"address","name":"oldLiquidityMining","type":"address"},{"indexed":true,"internalType":"address","name":"newLiquidityMining","type":"address"}],"name":"LiquidityMiningChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"changedBy","type":"address"},{"indexed":true,"internalType":"address","name":"oldPauseManager","type":"address"},{"indexed":true,"internalType":"address","name":"newPauseManager","type":"address"}],"name":"PauseManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"pwTokenAmount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewardsAmount","type":"uint256"}],"name":"RewardsReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"internalExchangeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseAmount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address[]","name":"lpTokens","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"}],"name":"ToLiquidityMiningDelegated","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":"changedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UnstakeWithoutCooldownFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"pwTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"internalExchangeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"COOL_DOWN_IN_SECONDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pwTokenAmount","type":"uint256"}],"name":"cooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"lpTokenAmounts","type":"uint256[]"}],"name":"delegateAndStakeToLiquidityMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"}],"name":"delegateToLiquidityMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegatedToLiquidityMiningBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getActiveCooldown","outputs":[{"components":[{"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"internalType":"uint256","name":"pwTokenAmount","type":"uint256"}],"internalType":"struct PowerTokenTypes.PwTokenCooldown","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getLiquidityMining","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauseManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakedToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnstakeWithoutCooldownFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"stakedToken","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"rewardsAmount","type":"uint256"}],"name":"receiveRewardsFromLiquidityMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newLiquidityMiningAddr","type":"address"}],"name":"setLiquidityMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauseManagerAddr","type":"address"}],"name":"setPauseManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"unstakeWithoutCooldownFee","type":"uint256"}],"name":"setUnstakeWithoutCooldownFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakedTokenAmount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"appointedOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"lpTokens","type":"address[]"},{"internalType":"uint256[]","name":"pwTokenAmounts","type":"uint256[]"}],"name":"undelegateFromLiquidityMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pwTokenAmount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516134a06200012060003960008181611120015281816111a5015281816112fb01528181611380015261146a01526134a06000f3fe60806040526004361061029f5760003560e01c80636cec8a1b1161016e578063a694fc3a116100cb578063cc29516a1161007f578063ec3c87c911610064578063ec3c87c914610794578063f2fde38b146107b4578063f596c0e1146107d457600080fd5b8063cc29516a1461075f578063da2760401461077457600080fd5b8063bc8722d0116100b0578063bc8722d01461070b578063be040fb01461072a578063c4d66de81461073f57600080fd5b8063a694fc3a1461066d578063a760f8301461068d57600080fd5b806379920f5311610122578063890d411211610107578063890d4112146105e95780638da5cb5b1461060957806395d89b411461062757600080fd5b806379920f53146105b45780638456cb59146105d457600080fd5b8063715018a611610153578063715018a61461056b5780637674e44e14610580578063769b81d61461059557600080fd5b80636cec8a1b1461052b57806370a082311461054b57600080fd5b80632e17de781161021c5780634788cabf116101d057806352d1902d116101b557806352d1902d146104de5780635c975abb146104f35780636bee47ef1461051657600080fd5b80634788cabf146104985780634f1ef286146104cb57600080fd5b80633581f542116102015780633581f542146104305780633659cfe6146104635780633f4ba83a1461048357600080fd5b80632e17de78146103f4578063313ce5671461041457600080fd5b806318160ddd1161027357806320022d811161025857806320022d811461039e578063206878a4146103be578063278cc7a0146103de57600080fd5b806318160ddd146103675780631e4026a91461037c57600080fd5b8062c07734146102a457806306fdde03146102ee5780630c5c78921461033d5780630d8e6e2c14610353575b600080fd5b3480156102b057600080fd5b506102db6102bf366004612f0a565b6001600160a01b03166000908152610132602052604090205490565b6040519081526020015b60405180910390f35b3480156102fa57600080fd5b5060408051808201909152600a81527f506f7765722049504f520000000000000000000000000000000000000000000060208201525b6040516102e59190612f49565b34801561034957600080fd5b50610135546102db565b34801561035f57600080fd5b5060016102db565b34801561037357600080fd5b506102db6107eb565b34801561038857600080fd5b5061039c610397366004612fc8565b610829565b005b3480156103aa57600080fd5b5061039c6103b9366004612fc8565b610a58565b3480156103ca57600080fd5b5061039c6103d9366004612f0a565b610ced565b3480156103ea57600080fd5b50610134546102db565b34801561040057600080fd5b5061039c61040f366004613034565b610e62565b34801561042057600080fd5b50604051601281526020016102e5565b34801561043c57600080fd5b5061012e546001600160a01b03165b6040516001600160a01b0390911681526020016102e5565b34801561046f57600080fd5b5061039c61047e366004612f0a565b611116565b34801561048f57600080fd5b5061039c611291565b3480156104a457600080fd5b507fbd22bf01cb7daed462db61de31bb111aabcdae27adc748450fb9a9ea1c419cce6102db565b61039c6104d9366004613063565b6112f1565b3480156104ea57600080fd5b506102db61145d565b3480156104ff57600080fd5b5060335460ff1660405190151581526020016102e5565b34801561052257600080fd5b506102db611522565b34801561053757600080fd5b5061039c610546366004613034565b61153b565b34801561055757600080fd5b506102db610566366004612f0a565b6115e9565b34801561057757600080fd5b5061039c6115fa565b34801561058c57600080fd5b5061039c61161f565b3480156105a157600080fd5b50610130546001600160a01b031661044b565b3480156105c057600080fd5b5061039c6105cf366004613125565b61167c565b3480156105e057600080fd5b5061039c6118a2565b3480156105f557600080fd5b5061039c610604366004612f0a565b611900565b34801561061557600080fd5b5060fb546001600160a01b031661044b565b34801561063357600080fd5b5060408051808201909152600681527f707749504f5200000000000000000000000000000000000000000000000000006020820152610330565b34801561067957600080fd5b5061039c610688366004613034565b6119b0565b34801561069957600080fd5b506106f06106a8366004612f0a565b6040805180820190915260008082526020820152506001600160a01b031660009081526101336020908152604091829020825180840190935280548352600101549082015290565b604080518251815260209283015192810192909252016102e5565b34801561071757600080fd5b5061012f546001600160a01b031661044b565b34801561073657600080fd5b5061039c611ba5565b34801561074b57600080fd5b5061039c61075a366004612f0a565b611e88565b34801561076b57600080fd5b5061039c612104565b34801561078057600080fd5b5061039c61078f366004613034565b612180565b3480156107a057600080fd5b5061039c6107af3660046131bf565b612345565b3480156107c057600080fd5b5061039c6107cf366004612f0a565b612563565b3480156107e057600080fd5b506102db6212750081565b61012f5460009061082490610808906001600160a01b03166125fb565b6101345461081691906131ff565b670de0b6b3a76400006126bc565b905090565b6108316126e5565b600260c954036108885760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260c9556040805180820190915260068152650a0a8be6e62760d31b602082015281908482146108cc5760405162461bcd60e51b815260040161087f9190612f49565b506000805b82811461090e578484828181106108ea576108ea613216565b90506020020135826108fc919061322c565b91506109078161323f565b90506108d1565b5080610930335b61012f5461092b906001600160a01b03166125fb565b612738565b1015604051806040016040528060068152602001650a0a8be6e60760d31b8152509061096f5760405162461bcd60e51b815260040161087f9190612f49565b5033600090815261013260205260408120805483929061099090849061322c565b909155505061012e546001600160a01b031663b2cbc4b133888888886040518663ffffffff1660e01b81526004016109cc9594939291906132ea565b600060405180830381600087803b1580156109e657600080fd5b505af11580156109fa573d6000803e3d6000fd5b50505050610a053390565b6001600160a01b03167f21aba0fe9ce04ede80bda33f049609d9b5f3b43bf84908784bc530fff18c92b987878787604051610a43949392919061332c565b60405180910390a25050600160c95550505050565b610a606126e5565b600260c95403610ab25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c9556040805180820190915260068152650a0a8be6e62760d31b60208201528390828214610af65760405162461bcd60e51b815260040161087f9190612f49565b506000805b828114610b92576000858583818110610b1657610b16613216565b90506020020135116040518060400160405280600681526020016550545f37313760d01b81525090610b5b5760405162461bcd60e51b815260040161087f9190612f49565b50848482818110610b6e57610b6e613216565b9050602002013582610b80919061322c565b9150610b8b8161323f565b9050610afb565b503360008181526101326020908152604091829020548251808401909352600683527f50545f373037000000000000000000000000000000000000000000000000000091830191909152831115610bfc5760405162461bcd60e51b815260040161087f9190612f49565b5061012e54604051630fdb94e560e21b81526001600160a01b0390911690633f6e539490610c369084908b908b908b908b906004016132ea565b600060405180830381600087803b158015610c5057600080fd5b505af1158015610c64573d6000803e3d6000fd5b505050506001600160a01b0381166000908152610132602052604081208054849290610c9190849061335e565b92505081905550806001600160a01b03167fb9e7eee7860d52cb5f0f2367c67975c2973203709fc7af03ea55ebe183142be088888888604051610cd7949392919061332c565b60405180910390a25050600160c9555050505050565b610cf561278c565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038216610d395760405162461bcd60e51b815260040161087f9190612f49565b507f9b1f3aa590476fc9aa58d44ad1419ab53d34c344bd5ed46b12e4af7d27c38e0660001b816001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc09190613371565b1460405180604001604052806006815260200165282a2f9b989b60d11b81525090610dfe5760405162461bcd60e51b815260040161087f9190612f49565b5061012e80546001600160a01b038381166001600160a01b031983168117909355169081610e293390565b6001600160a01b03167f3fee58cf9cc0a13404b55baafb0d0c63c6a9dccb39a837541c43be6f64a9d37d60405160405180910390a45050565b610e6a6126e5565b600260c95403610ebc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95560408051808201909152600681526550545f37313760d01b602082015281610efc5760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b0316336000610f16836125fb565b90506000610f248383612738565b905084811015604051806040016040528060068152602001650a0a8be6e60760d31b81525090610f675760405162461bcd60e51b815260040161087f9190612f49565b506000610f85610f7f670de0b6b3a7640000886131ff565b846126bc565b9050806101316000866001600160a01b03166001600160a01b031681526020019081526020016000205410156040518060400160405280600681526020016550545f37303560d01b81525090610fee5760405162461bcd60e51b815260040161087f9190612f49565b506001600160a01b038416600090815261013160205260408120805483929061101890849061335e565b92505081905550806101346000828254611032919061335e565b909155506000905061104c611046836127e6565b8561280d565b60405163a9059cbb60e01b81526001600160a01b038781166004830152602482018390529192509087169063a9059cbb906044016020604051808303816000875af115801561109f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c3919061338a565b506001600160a01b0385167f204fccf0d92ed8d48f204adb39b2e81e92bad0dedb93f5716ca9478cfb57de0088866110fb858361335e565b60408051938452602084019290925290820152606001610cd7565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036111a35760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b606482015260840161087f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166111fe7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146112695760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b606482015260840161087f565b6112728161281c565b6040805160008082526020820190925261128e91839190612824565b50565b610130546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b815250906112e65760405162461bcd60e51b815260040161087f9190612f49565b506112ef6129c9565b565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361137e5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b606482015260840161087f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113d97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146114445760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b606482015260840161087f565b61144d8261281c565b61145982826001612824565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114fd5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161087f565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b61012f54600090610824906001600160a01b03166125fb565b61154361278c565b60408051808201909152600681527f50545f37313400000000000000000000000000000000000000000000000000006020820152670de0b6b3a76400008211156115a05760405162461bcd60e51b815260040161087f9190612f49565b50610135805490829055604080518281526020810184905233917f01bc8f4f8aa55421c207245e5d644d4773ecdbe83bc8a77baedb8116fe3e7c4e910160405180910390a25050565b60006115f482612a1b565b92915050565b61160261278c565b61160c6000612a4a565b61012d80546001600160a01b0319169055565b6116276126e5565b336000818152610133602090815260408083208381556001018390558051838152918201929092527ff5f8de3de281af7b164aec3dd23cdabdf4a7d7093b47fe2d1c1623be453eb67e910160405180910390a2565b6116846126e5565b600260c954036116d65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95584831480156116e957508481145b604051806040016040528060068152602001650a0a8be6e62760d31b815250906117265760405162461bcd60e51b815260040161087f9190612f49565b50600083815b8181146117695786868281811061174557611745613216565b9050602002013583611757919061322c565b92506117628161323f565b905061172c565b508161177433610915565b1015604051806040016040528060068152602001650a0a8be6e60760d31b815250906117b35760405162461bcd60e51b815260040161087f9190612f49565b503360009081526101326020526040812080548492906117d490849061322c565b909155505061012e546001600160a01b031663cf4858b7338a8a8a8a8a8a6040518863ffffffff1660e01b815260040161181497969594939291906133ac565b600060405180830381600087803b15801561182e57600080fd5b505af1158015611842573d6000803e3d6000fd5b5050505061184d3390565b6001600160a01b03167f21aba0fe9ce04ede80bda33f049609d9b5f3b43bf84908784bc530fff18c92b98989898960405161188b949392919061332c565b60405180910390a25050600160c955505050505050565b610130546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b815250906118f75760405162461bcd60e51b815260040161087f9190612f49565b506112ef612a9c565b61190861278c565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b03821661194c5760405162461bcd60e51b815260040161087f9190612f49565b5061013080546001600160a01b038381166001600160a01b0319831681179093551690816119773390565b6001600160a01b03167fb1f2133e27463d1f096faf22e79896b5ebbf2d047633dc7451139a1fe14854a960405160405180910390a45050565b6119b86126e5565b600260c95403611a0a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95560408051808201909152600681526550545f37313760d01b602082015281611a4a5760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b0316336000611a64836125fb565b6040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201879052919250908416906323b872dd906064016020604051808303816000875af1158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae1919061338a565b506000611aff611af9670de0b6b3a7640000876131ff565b836126bc565b6001600160a01b03841660009081526101316020526040812080549293508392909190611b2d90849061322c565b92505081905550806101346000828254611b47919061322c565b909155505060408051868152602081018490529081018290526001600160a01b038416907fb4caaf29adda3eefee3ad552a8e85058589bf834c7466cae4ee58787f70589ed906060015b60405180910390a25050600160c955505050565b611bad6126e5565b600260c95403611bff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c9553360008181526101336020908152604091829020825180840184528154808252600190920154818401528351808501909452600684527f50545f373130000000000000000000000000000000000000000000000000000092840192909252909190421015611c855760405162461bcd60e51b815260040161087f9190612f49565b5060008160200151116040518060400160405280600681526020016550545f37313760d01b81525090611ccb5760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b03166000611ce4826125fb565b90506000611d03670de0b6b3a76400008560200151611af991906131ff565b9050806101316000876001600160a01b03166001600160a01b031681526020019081526020016000205410156040518060400160405280600681526020016550545f37303560d01b81525090611d6c5760405162461bcd60e51b815260040161087f9190612f49565b506001600160a01b0385166000908152610131602052604081208054839290611d9690849061335e565b92505081905550806101346000828254611db0919061335e565b90915550506001600160a01b0385811660008181526101336020908152604080832083815560010192909255870151905163a9059cbb60e01b8152600481019290925260248201529084169063a9059cbb906044016020604051808303816000875af1158015611e24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e48919061338a565b50846001600160a01b03167f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a68560200151604051611b9191815260200190565b600054610100900460ff1615808015611ea85750600054600160ff909116105b80611ec25750303b158015611ec2575060005460ff166001145b611f345760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161087f565b6000805460ff191660011790558015611f57576000805461ff0019166101001790555b611f5f612ad9565b611f67612b50565b611f6f612bc4565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038316611fb35760405162461bcd60e51b815260040161087f9190612f49565b507fdba05ed67d0251facfcab8345f27ccd3e72b5a1da8cebfabbcccf4316e6d053c60001b826001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612016573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203a9190613371565b1460405180604001604052806006815260200165282a2f9b989b60d11b815250906120785760405162461bcd60e51b815260040161087f9190612f49565b5061012f80546001600160a01b0384166001600160a01b0319918216179091556101308054909116331790556120b767016345785d8a000060056131ff565b610135558015611459576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61012d5460408051808201909152600681527f50545f37313900000000000000000000000000000000000000000000000000006020820152906001600160a01b031633146121655760405162461bcd60e51b815260040161087f9190612f49565b5061012d80546001600160a01b03191690556112ef33612a4a565b6121886126e5565b600260c954036121da5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95560408051808201909152600681526550545f37313760d01b60208201528161221a5760405162461bcd60e51b815260040161087f9190612f49565b50336000818152610132602090815260408083205461013190925282205461012f546122589190612253906001600160a01b03166125fb565b61280d565b612262919061335e565b905082811015604051806040016040528060068152602001650a0a8be6e60760d31b815250906122a55760405162461bcd60e51b815260040161087f9190612f49565b50604051806040016040528062127500426122c0919061322c565b815260209081018590526001600160a01b03841660008181526101338352604090208351815592909101516001909201919091557ff5f8de3de281af7b164aec3dd23cdabdf4a7d7093b47fe2d1c1623be453eb67e84612323621275004261322c565b6040805192835260208301919091520160405180910390a25050600160c95550565b61234d6126e5565b61012e546001600160a01b0316336001600160a01b0316146040518060400160405280600681526020017f50545f3730330000000000000000000000000000000000000000000000000000815250906123b95760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b031660006123d2826125fb565b9050600083116040518060400160405280600681526020016550545f37313760d01b815250906124155760405162461bcd60e51b815260040161087f9190612f49565b506001600160a01b0382166323b872dd336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152306024820152604481018690526064016020604051808303816000875af1158015612491573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b5919061338a565b5060006124cd611af9670de0b6b3a7640000866131ff565b6001600160a01b038616600090815261013160205260408120805492935083929091906124fb90849061322c565b92505081905550806101346000828254612515919061322c565b9091555050604080516001600160a01b0387168152602081018690527f577e40010b42fd80bafa850999e7cec91750c749202445266b373708c5929420910160405180910390a15050505050565b61256b61278c565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0382166125af5760405162461bcd60e51b815260040161087f9190612f49565b5061012d80546001600160a01b0319166001600160a01b0383169081179091556040517f3ec7bb1d452f3c36260fa8ef678a597fd97574d8ec42f6dc98ffce3dbc91228f90600090a250565b610134546000908082036126195750670de0b6b3a764000092915050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015612660573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126849190613371565b90508060000361269f5750670de0b6b3a76400009392505050565b6126b4611af9670de0b6b3a7640000836131ff565b949350505050565b6000816126ca600282613405565b6126d4908561322c565b6126de9190613405565b9392505050565b60335460ff16156112ef5760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161087f565b6001600160a01b0382166000908152610133602090815260408083206001015461013283528184205461013190935290832054909190612778908561280d565b612782919061335e565b6126de919061335e565b60fb546001600160a01b031633146112ef5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161087f565b60006115f48261013554670de0b6b3a7640000612803919061335e565b61081691906131ff565b60006126de61081683856131ff565b61128e61278c565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561285c5761285783612c2f565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128b6575060408051601f3d908101601f191682019092526128b391810190613371565b60015b6129285760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f742055555053000000000000000000000000000000000000606482015260840161087f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146129bd5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c65555549440000000000000000000000000000000000000000000000606482015260840161087f565b50612857838383612ced565b6129d1612d18565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b038082166000908152610131602052604081205461012f5491926115f49261225391166125fb565b60fb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612aa46126e5565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586129fe3390565b600054610100900460ff16612b445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161087f565b6033805460ff19169055565b600054610100900460ff16612bbb5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161087f565b6112ef33612a4a565b600054610100900460ff166112ef5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161087f565b6001600160a01b0381163b612cac5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161087f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b612cf683612d6a565b600082511180612d035750805b1561285757612d128383612daa565b50505050565b60335460ff166112ef5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161087f565b612d7381612c2f565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b612e295760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161087f565b600080846001600160a01b031684604051612e449190613427565b600060405180830381855af49150503d8060008114612e7f576040519150601f19603f3d011682016040523d82523d6000602084013e612e84565b606091505b5091509150612eac828260405180606001604052806027815260200161344460279139612eb5565b95945050505050565b60608315612ec45750816126de565b825115612ed45782518084602001fd5b8160405162461bcd60e51b815260040161087f9190612f49565b80356001600160a01b0381168114612f0557600080fd5b919050565b600060208284031215612f1c57600080fd5b6126de82612eee565b60005b83811015612f40578181015183820152602001612f28565b50506000910152565b6020815260008251806020840152612f68816040850160208701612f25565b601f01601f19169190910160400192915050565b60008083601f840112612f8e57600080fd5b50813567ffffffffffffffff811115612fa657600080fd5b6020830191508360208260051b8501011115612fc157600080fd5b9250929050565b60008060008060408587031215612fde57600080fd5b843567ffffffffffffffff80821115612ff657600080fd5b61300288838901612f7c565b9096509450602087013591508082111561301b57600080fd5b5061302887828801612f7c565b95989497509550505050565b60006020828403121561304657600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561307657600080fd5b61307f83612eee565b9150602083013567ffffffffffffffff8082111561309c57600080fd5b818501915085601f8301126130b057600080fd5b8135818111156130c2576130c261304d565b604051601f8201601f19908116603f011681019083821181831017156130ea576130ea61304d565b8160405282815288602084870101111561310357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000806000806000806060878903121561313e57600080fd5b863567ffffffffffffffff8082111561315657600080fd5b6131628a838b01612f7c565b9098509650602089013591508082111561317b57600080fd5b6131878a838b01612f7c565b909650945060408901359150808211156131a057600080fd5b506131ad89828a01612f7c565b979a9699509497509295939492505050565b600080604083850312156131d257600080fd5b6131db83612eee565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176115f4576115f46131e9565b634e487b7160e01b600052603260045260246000fd5b808201808211156115f4576115f46131e9565b600060018201613251576132516131e9565b5060010190565b8183526000602080850194508260005b85811015613294576001600160a01b0361328183612eee565b1687529582019590820190600101613268565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156132d157600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b038616815260606020820152600061330d606083018688613258565b828103604084015261332081858761329f565b98975050505050505050565b604081526000613340604083018688613258565b828103602084015261335381858761329f565b979650505050505050565b818103818111156115f4576115f46131e9565b60006020828403121561338357600080fd5b5051919050565b60006020828403121561339c57600080fd5b815180151581146126de57600080fd5b6001600160a01b03881681526080602082015260006133cf60808301888a613258565b82810360408401526133e281878961329f565b905082810360608401526133f781858761329f565b9a9950505050505050505050565b60008261342257634e487b7160e01b600052601260045260246000fd5b500490565b60008251613439818460208701612f25565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220121b656699a7d9b8b4a631920479102186bbf509a7401ddb478eeb565dd0eabf64736f6c63430008110033
Deployed Bytecode
0x60806040526004361061029f5760003560e01c80636cec8a1b1161016e578063a694fc3a116100cb578063cc29516a1161007f578063ec3c87c911610064578063ec3c87c914610794578063f2fde38b146107b4578063f596c0e1146107d457600080fd5b8063cc29516a1461075f578063da2760401461077457600080fd5b8063bc8722d0116100b0578063bc8722d01461070b578063be040fb01461072a578063c4d66de81461073f57600080fd5b8063a694fc3a1461066d578063a760f8301461068d57600080fd5b806379920f5311610122578063890d411211610107578063890d4112146105e95780638da5cb5b1461060957806395d89b411461062757600080fd5b806379920f53146105b45780638456cb59146105d457600080fd5b8063715018a611610153578063715018a61461056b5780637674e44e14610580578063769b81d61461059557600080fd5b80636cec8a1b1461052b57806370a082311461054b57600080fd5b80632e17de781161021c5780634788cabf116101d057806352d1902d116101b557806352d1902d146104de5780635c975abb146104f35780636bee47ef1461051657600080fd5b80634788cabf146104985780634f1ef286146104cb57600080fd5b80633581f542116102015780633581f542146104305780633659cfe6146104635780633f4ba83a1461048357600080fd5b80632e17de78146103f4578063313ce5671461041457600080fd5b806318160ddd1161027357806320022d811161025857806320022d811461039e578063206878a4146103be578063278cc7a0146103de57600080fd5b806318160ddd146103675780631e4026a91461037c57600080fd5b8062c07734146102a457806306fdde03146102ee5780630c5c78921461033d5780630d8e6e2c14610353575b600080fd5b3480156102b057600080fd5b506102db6102bf366004612f0a565b6001600160a01b03166000908152610132602052604090205490565b6040519081526020015b60405180910390f35b3480156102fa57600080fd5b5060408051808201909152600a81527f506f7765722049504f520000000000000000000000000000000000000000000060208201525b6040516102e59190612f49565b34801561034957600080fd5b50610135546102db565b34801561035f57600080fd5b5060016102db565b34801561037357600080fd5b506102db6107eb565b34801561038857600080fd5b5061039c610397366004612fc8565b610829565b005b3480156103aa57600080fd5b5061039c6103b9366004612fc8565b610a58565b3480156103ca57600080fd5b5061039c6103d9366004612f0a565b610ced565b3480156103ea57600080fd5b50610134546102db565b34801561040057600080fd5b5061039c61040f366004613034565b610e62565b34801561042057600080fd5b50604051601281526020016102e5565b34801561043c57600080fd5b5061012e546001600160a01b03165b6040516001600160a01b0390911681526020016102e5565b34801561046f57600080fd5b5061039c61047e366004612f0a565b611116565b34801561048f57600080fd5b5061039c611291565b3480156104a457600080fd5b507fbd22bf01cb7daed462db61de31bb111aabcdae27adc748450fb9a9ea1c419cce6102db565b61039c6104d9366004613063565b6112f1565b3480156104ea57600080fd5b506102db61145d565b3480156104ff57600080fd5b5060335460ff1660405190151581526020016102e5565b34801561052257600080fd5b506102db611522565b34801561053757600080fd5b5061039c610546366004613034565b61153b565b34801561055757600080fd5b506102db610566366004612f0a565b6115e9565b34801561057757600080fd5b5061039c6115fa565b34801561058c57600080fd5b5061039c61161f565b3480156105a157600080fd5b50610130546001600160a01b031661044b565b3480156105c057600080fd5b5061039c6105cf366004613125565b61167c565b3480156105e057600080fd5b5061039c6118a2565b3480156105f557600080fd5b5061039c610604366004612f0a565b611900565b34801561061557600080fd5b5060fb546001600160a01b031661044b565b34801561063357600080fd5b5060408051808201909152600681527f707749504f5200000000000000000000000000000000000000000000000000006020820152610330565b34801561067957600080fd5b5061039c610688366004613034565b6119b0565b34801561069957600080fd5b506106f06106a8366004612f0a565b6040805180820190915260008082526020820152506001600160a01b031660009081526101336020908152604091829020825180840190935280548352600101549082015290565b604080518251815260209283015192810192909252016102e5565b34801561071757600080fd5b5061012f546001600160a01b031661044b565b34801561073657600080fd5b5061039c611ba5565b34801561074b57600080fd5b5061039c61075a366004612f0a565b611e88565b34801561076b57600080fd5b5061039c612104565b34801561078057600080fd5b5061039c61078f366004613034565b612180565b3480156107a057600080fd5b5061039c6107af3660046131bf565b612345565b3480156107c057600080fd5b5061039c6107cf366004612f0a565b612563565b3480156107e057600080fd5b506102db6212750081565b61012f5460009061082490610808906001600160a01b03166125fb565b6101345461081691906131ff565b670de0b6b3a76400006126bc565b905090565b6108316126e5565b600260c954036108885760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260c9556040805180820190915260068152650a0a8be6e62760d31b602082015281908482146108cc5760405162461bcd60e51b815260040161087f9190612f49565b506000805b82811461090e578484828181106108ea576108ea613216565b90506020020135826108fc919061322c565b91506109078161323f565b90506108d1565b5080610930335b61012f5461092b906001600160a01b03166125fb565b612738565b1015604051806040016040528060068152602001650a0a8be6e60760d31b8152509061096f5760405162461bcd60e51b815260040161087f9190612f49565b5033600090815261013260205260408120805483929061099090849061322c565b909155505061012e546001600160a01b031663b2cbc4b133888888886040518663ffffffff1660e01b81526004016109cc9594939291906132ea565b600060405180830381600087803b1580156109e657600080fd5b505af11580156109fa573d6000803e3d6000fd5b50505050610a053390565b6001600160a01b03167f21aba0fe9ce04ede80bda33f049609d9b5f3b43bf84908784bc530fff18c92b987878787604051610a43949392919061332c565b60405180910390a25050600160c95550505050565b610a606126e5565b600260c95403610ab25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c9556040805180820190915260068152650a0a8be6e62760d31b60208201528390828214610af65760405162461bcd60e51b815260040161087f9190612f49565b506000805b828114610b92576000858583818110610b1657610b16613216565b90506020020135116040518060400160405280600681526020016550545f37313760d01b81525090610b5b5760405162461bcd60e51b815260040161087f9190612f49565b50848482818110610b6e57610b6e613216565b9050602002013582610b80919061322c565b9150610b8b8161323f565b9050610afb565b503360008181526101326020908152604091829020548251808401909352600683527f50545f373037000000000000000000000000000000000000000000000000000091830191909152831115610bfc5760405162461bcd60e51b815260040161087f9190612f49565b5061012e54604051630fdb94e560e21b81526001600160a01b0390911690633f6e539490610c369084908b908b908b908b906004016132ea565b600060405180830381600087803b158015610c5057600080fd5b505af1158015610c64573d6000803e3d6000fd5b505050506001600160a01b0381166000908152610132602052604081208054849290610c9190849061335e565b92505081905550806001600160a01b03167fb9e7eee7860d52cb5f0f2367c67975c2973203709fc7af03ea55ebe183142be088888888604051610cd7949392919061332c565b60405180910390a25050600160c9555050505050565b610cf561278c565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038216610d395760405162461bcd60e51b815260040161087f9190612f49565b507f9b1f3aa590476fc9aa58d44ad1419ab53d34c344bd5ed46b12e4af7d27c38e0660001b816001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc09190613371565b1460405180604001604052806006815260200165282a2f9b989b60d11b81525090610dfe5760405162461bcd60e51b815260040161087f9190612f49565b5061012e80546001600160a01b038381166001600160a01b031983168117909355169081610e293390565b6001600160a01b03167f3fee58cf9cc0a13404b55baafb0d0c63c6a9dccb39a837541c43be6f64a9d37d60405160405180910390a45050565b610e6a6126e5565b600260c95403610ebc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95560408051808201909152600681526550545f37313760d01b602082015281610efc5760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b0316336000610f16836125fb565b90506000610f248383612738565b905084811015604051806040016040528060068152602001650a0a8be6e60760d31b81525090610f675760405162461bcd60e51b815260040161087f9190612f49565b506000610f85610f7f670de0b6b3a7640000886131ff565b846126bc565b9050806101316000866001600160a01b03166001600160a01b031681526020019081526020016000205410156040518060400160405280600681526020016550545f37303560d01b81525090610fee5760405162461bcd60e51b815260040161087f9190612f49565b506001600160a01b038416600090815261013160205260408120805483929061101890849061335e565b92505081905550806101346000828254611032919061335e565b909155506000905061104c611046836127e6565b8561280d565b60405163a9059cbb60e01b81526001600160a01b038781166004830152602482018390529192509087169063a9059cbb906044016020604051808303816000875af115801561109f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c3919061338a565b506001600160a01b0385167f204fccf0d92ed8d48f204adb39b2e81e92bad0dedb93f5716ca9478cfb57de0088866110fb858361335e565b60408051938452602084019290925290820152606001610cd7565b6001600160a01b037f000000000000000000000000586ac86675bd933c4b9a26c55b6e62b6496d49eb1630036111a35760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b606482015260840161087f565b7f000000000000000000000000586ac86675bd933c4b9a26c55b6e62b6496d49eb6001600160a01b03166111fe7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146112695760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b606482015260840161087f565b6112728161281c565b6040805160008082526020820190925261128e91839190612824565b50565b610130546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b815250906112e65760405162461bcd60e51b815260040161087f9190612f49565b506112ef6129c9565b565b6001600160a01b037f000000000000000000000000586ac86675bd933c4b9a26c55b6e62b6496d49eb16300361137e5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b606482015260840161087f565b7f000000000000000000000000586ac86675bd933c4b9a26c55b6e62b6496d49eb6001600160a01b03166113d97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146114445760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b606482015260840161087f565b61144d8261281c565b61145982826001612824565b5050565b6000306001600160a01b037f000000000000000000000000586ac86675bd933c4b9a26c55b6e62b6496d49eb16146114fd5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161087f565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b61012f54600090610824906001600160a01b03166125fb565b61154361278c565b60408051808201909152600681527f50545f37313400000000000000000000000000000000000000000000000000006020820152670de0b6b3a76400008211156115a05760405162461bcd60e51b815260040161087f9190612f49565b50610135805490829055604080518281526020810184905233917f01bc8f4f8aa55421c207245e5d644d4773ecdbe83bc8a77baedb8116fe3e7c4e910160405180910390a25050565b60006115f482612a1b565b92915050565b61160261278c565b61160c6000612a4a565b61012d80546001600160a01b0319169055565b6116276126e5565b336000818152610133602090815260408083208381556001018390558051838152918201929092527ff5f8de3de281af7b164aec3dd23cdabdf4a7d7093b47fe2d1c1623be453eb67e910160405180910390a2565b6116846126e5565b600260c954036116d65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95584831480156116e957508481145b604051806040016040528060068152602001650a0a8be6e62760d31b815250906117265760405162461bcd60e51b815260040161087f9190612f49565b50600083815b8181146117695786868281811061174557611745613216565b9050602002013583611757919061322c565b92506117628161323f565b905061172c565b508161177433610915565b1015604051806040016040528060068152602001650a0a8be6e60760d31b815250906117b35760405162461bcd60e51b815260040161087f9190612f49565b503360009081526101326020526040812080548492906117d490849061322c565b909155505061012e546001600160a01b031663cf4858b7338a8a8a8a8a8a6040518863ffffffff1660e01b815260040161181497969594939291906133ac565b600060405180830381600087803b15801561182e57600080fd5b505af1158015611842573d6000803e3d6000fd5b5050505061184d3390565b6001600160a01b03167f21aba0fe9ce04ede80bda33f049609d9b5f3b43bf84908784bc530fff18c92b98989898960405161188b949392919061332c565b60405180910390a25050600160c955505050505050565b610130546001600160a01b0316336001600160a01b03161460405180604001604052806006815260200165141517cdcc0d60d21b815250906118f75760405162461bcd60e51b815260040161087f9190612f49565b506112ef612a9c565b61190861278c565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b03821661194c5760405162461bcd60e51b815260040161087f9190612f49565b5061013080546001600160a01b038381166001600160a01b0319831681179093551690816119773390565b6001600160a01b03167fb1f2133e27463d1f096faf22e79896b5ebbf2d047633dc7451139a1fe14854a960405160405180910390a45050565b6119b86126e5565b600260c95403611a0a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95560408051808201909152600681526550545f37313760d01b602082015281611a4a5760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b0316336000611a64836125fb565b6040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201879052919250908416906323b872dd906064016020604051808303816000875af1158015611abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae1919061338a565b506000611aff611af9670de0b6b3a7640000876131ff565b836126bc565b6001600160a01b03841660009081526101316020526040812080549293508392909190611b2d90849061322c565b92505081905550806101346000828254611b47919061322c565b909155505060408051868152602081018490529081018290526001600160a01b038416907fb4caaf29adda3eefee3ad552a8e85058589bf834c7466cae4ee58787f70589ed906060015b60405180910390a25050600160c955505050565b611bad6126e5565b600260c95403611bff5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c9553360008181526101336020908152604091829020825180840184528154808252600190920154818401528351808501909452600684527f50545f373130000000000000000000000000000000000000000000000000000092840192909252909190421015611c855760405162461bcd60e51b815260040161087f9190612f49565b5060008160200151116040518060400160405280600681526020016550545f37313760d01b81525090611ccb5760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b03166000611ce4826125fb565b90506000611d03670de0b6b3a76400008560200151611af991906131ff565b9050806101316000876001600160a01b03166001600160a01b031681526020019081526020016000205410156040518060400160405280600681526020016550545f37303560d01b81525090611d6c5760405162461bcd60e51b815260040161087f9190612f49565b506001600160a01b0385166000908152610131602052604081208054839290611d9690849061335e565b92505081905550806101346000828254611db0919061335e565b90915550506001600160a01b0385811660008181526101336020908152604080832083815560010192909255870151905163a9059cbb60e01b8152600481019290925260248201529084169063a9059cbb906044016020604051808303816000875af1158015611e24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e48919061338a565b50846001600160a01b03167f222838db2794d11532d940e8dec38ae307ed0b63cd97c233322e221f998767a68560200151604051611b9191815260200190565b600054610100900460ff1615808015611ea85750600054600160ff909116105b80611ec25750303b158015611ec2575060005460ff166001145b611f345760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161087f565b6000805460ff191660011790558015611f57576000805461ff0019166101001790555b611f5f612ad9565b611f67612b50565b611f6f612bc4565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b038316611fb35760405162461bcd60e51b815260040161087f9190612f49565b507fdba05ed67d0251facfcab8345f27ccd3e72b5a1da8cebfabbcccf4316e6d053c60001b826001600160a01b0316634788cabf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612016573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203a9190613371565b1460405180604001604052806006815260200165282a2f9b989b60d11b815250906120785760405162461bcd60e51b815260040161087f9190612f49565b5061012f80546001600160a01b0384166001600160a01b0319918216179091556101308054909116331790556120b767016345785d8a000060056131ff565b610135558015611459576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b61012d5460408051808201909152600681527f50545f37313900000000000000000000000000000000000000000000000000006020820152906001600160a01b031633146121655760405162461bcd60e51b815260040161087f9190612f49565b5061012d80546001600160a01b03191690556112ef33612a4a565b6121886126e5565b600260c954036121da5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161087f565b600260c95560408051808201909152600681526550545f37313760d01b60208201528161221a5760405162461bcd60e51b815260040161087f9190612f49565b50336000818152610132602090815260408083205461013190925282205461012f546122589190612253906001600160a01b03166125fb565b61280d565b612262919061335e565b905082811015604051806040016040528060068152602001650a0a8be6e60760d31b815250906122a55760405162461bcd60e51b815260040161087f9190612f49565b50604051806040016040528062127500426122c0919061322c565b815260209081018590526001600160a01b03841660008181526101338352604090208351815592909101516001909201919091557ff5f8de3de281af7b164aec3dd23cdabdf4a7d7093b47fe2d1c1623be453eb67e84612323621275004261322c565b6040805192835260208301919091520160405180910390a25050600160c95550565b61234d6126e5565b61012e546001600160a01b0316336001600160a01b0316146040518060400160405280600681526020017f50545f3730330000000000000000000000000000000000000000000000000000815250906123b95760405162461bcd60e51b815260040161087f9190612f49565b5061012f546001600160a01b031660006123d2826125fb565b9050600083116040518060400160405280600681526020016550545f37313760d01b815250906124155760405162461bcd60e51b815260040161087f9190612f49565b506001600160a01b0382166323b872dd336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152306024820152604481018690526064016020604051808303816000875af1158015612491573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b5919061338a565b5060006124cd611af9670de0b6b3a7640000866131ff565b6001600160a01b038616600090815261013160205260408120805492935083929091906124fb90849061322c565b92505081905550806101346000828254612515919061322c565b9091555050604080516001600160a01b0387168152602081018690527f577e40010b42fd80bafa850999e7cec91750c749202445266b373708c5929420910160405180910390a15050505050565b61256b61278c565b60408051808201909152600681526550545f37313560d01b60208201526001600160a01b0382166125af5760405162461bcd60e51b815260040161087f9190612f49565b5061012d80546001600160a01b0319166001600160a01b0383169081179091556040517f3ec7bb1d452f3c36260fa8ef678a597fd97574d8ec42f6dc98ffce3dbc91228f90600090a250565b610134546000908082036126195750670de0b6b3a764000092915050565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015612660573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126849190613371565b90508060000361269f5750670de0b6b3a76400009392505050565b6126b4611af9670de0b6b3a7640000836131ff565b949350505050565b6000816126ca600282613405565b6126d4908561322c565b6126de9190613405565b9392505050565b60335460ff16156112ef5760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161087f565b6001600160a01b0382166000908152610133602090815260408083206001015461013283528184205461013190935290832054909190612778908561280d565b612782919061335e565b6126de919061335e565b60fb546001600160a01b031633146112ef5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161087f565b60006115f48261013554670de0b6b3a7640000612803919061335e565b61081691906131ff565b60006126de61081683856131ff565b61128e61278c565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561285c5761285783612c2f565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128b6575060408051601f3d908101601f191682019092526128b391810190613371565b60015b6129285760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f742055555053000000000000000000000000000000000000606482015260840161087f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146129bd5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c65555549440000000000000000000000000000000000000000000000606482015260840161087f565b50612857838383612ced565b6129d1612d18565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b038082166000908152610131602052604081205461012f5491926115f49261225391166125fb565b60fb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612aa46126e5565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586129fe3390565b600054610100900460ff16612b445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161087f565b6033805460ff19169055565b600054610100900460ff16612bbb5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161087f565b6112ef33612a4a565b600054610100900460ff166112ef5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161087f565b6001600160a01b0381163b612cac5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161087f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b612cf683612d6a565b600082511180612d035750805b1561285757612d128383612daa565b50505050565b60335460ff166112ef5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161087f565b612d7381612c2f565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b612e295760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161087f565b600080846001600160a01b031684604051612e449190613427565b600060405180830381855af49150503d8060008114612e7f576040519150601f19603f3d011682016040523d82523d6000602084013e612e84565b606091505b5091509150612eac828260405180606001604052806027815260200161344460279139612eb5565b95945050505050565b60608315612ec45750816126de565b825115612ed45782518084602001fd5b8160405162461bcd60e51b815260040161087f9190612f49565b80356001600160a01b0381168114612f0557600080fd5b919050565b600060208284031215612f1c57600080fd5b6126de82612eee565b60005b83811015612f40578181015183820152602001612f28565b50506000910152565b6020815260008251806020840152612f68816040850160208701612f25565b601f01601f19169190910160400192915050565b60008083601f840112612f8e57600080fd5b50813567ffffffffffffffff811115612fa657600080fd5b6020830191508360208260051b8501011115612fc157600080fd5b9250929050565b60008060008060408587031215612fde57600080fd5b843567ffffffffffffffff80821115612ff657600080fd5b61300288838901612f7c565b9096509450602087013591508082111561301b57600080fd5b5061302887828801612f7c565b95989497509550505050565b60006020828403121561304657600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561307657600080fd5b61307f83612eee565b9150602083013567ffffffffffffffff8082111561309c57600080fd5b818501915085601f8301126130b057600080fd5b8135818111156130c2576130c261304d565b604051601f8201601f19908116603f011681019083821181831017156130ea576130ea61304d565b8160405282815288602084870101111561310357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000806000806000806060878903121561313e57600080fd5b863567ffffffffffffffff8082111561315657600080fd5b6131628a838b01612f7c565b9098509650602089013591508082111561317b57600080fd5b6131878a838b01612f7c565b909650945060408901359150808211156131a057600080fd5b506131ad89828a01612f7c565b979a9699509497509295939492505050565b600080604083850312156131d257600080fd5b6131db83612eee565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176115f4576115f46131e9565b634e487b7160e01b600052603260045260246000fd5b808201808211156115f4576115f46131e9565b600060018201613251576132516131e9565b5060010190565b8183526000602080850194508260005b85811015613294576001600160a01b0361328183612eee565b1687529582019590820190600101613268565b509495945050505050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156132d157600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b038616815260606020820152600061330d606083018688613258565b828103604084015261332081858761329f565b98975050505050505050565b604081526000613340604083018688613258565b828103602084015261335381858761329f565b979650505050505050565b818103818111156115f4576115f46131e9565b60006020828403121561338357600080fd5b5051919050565b60006020828403121561339c57600080fd5b815180151581146126de57600080fd5b6001600160a01b03881681526080602082015260006133cf60808301888a613258565b82810360408401526133e281878961329f565b905082810360608401526133f781858761329f565b9a9950505050505050505050565b60008261342257634e487b7160e01b600052601260045260246000fd5b500490565b60008251613439818460208701612f25565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220121b656699a7d9b8b4a631920479102186bbf509a7401ddb478eeb565dd0eabf64736f6c63430008110033
Deployed Bytecode Sourcemap
104933:9491:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105846:213;;;;;;;;;;-1:-1:-1;105846:213:0;;;;;:::i;:::-;-1:-1:-1;;;;;106008:43:0;105976:7;106008:43;;;:34;:43;;;;;;;105846:213;;;;552:25:1;;;540:2;525:18;105846:213:0;;;;;;;;104995:101;;;;;;;;;;-1:-1:-1;105069:19:0;;;;;;;;;;;;;;;;;104995:101;;;;;;;:::i;106067:133::-;;;;;;;;;;-1:-1:-1;106166:26:0;;106067:133;;91156:90;;;;;;;;;;-1:-1:-1;91237:1:0;91156:90;;105463:245;;;;;;;;;;;;;:::i;108615:1092::-;;;;;;;;;;-1:-1:-1;108615:1092:0;;;;;:::i;:::-;;:::i;:::-;;110995:1153;;;;;;;;;;-1:-1:-1;110995:1153:0;;;;;:::i;:::-;;:::i;92389:549::-;;;;;;;;;;-1:-1:-1;92389:549:0;;;;;:::i;:::-;;:::i;91254:110::-;;;;;;;;;;-1:-1:-1;91340:16:0;;91254:110;;107189:1418;;;;;;;;;;-1:-1:-1;107189:1418:0;;;;;:::i;:::-;;:::i;105211:87::-;;;;;;;;;;-1:-1:-1;105211:87:0;;105288:2;2721:36:1;;2709:2;2694:18;105211:87:0;2579:184:1;91524:113:0;;;;;;;;;;-1:-1:-1;91613:16:0;;-1:-1:-1;;;;;91613:16:0;91524:113;;;-1:-1:-1;;;;;2932:55:1;;;2914:74;;2902:2;2887:18;91524:113:0;2768:226:1;36121:200:0;;;;;;;;;;-1:-1:-1;36121:200:0;;;;;:::i;:::-;;:::i;94259:83::-;;;;;;;;;;;;;:::i;105306:149::-;;;;;;;;;;-1:-1:-1;105381:66:0;105306:149;;36580:225;;;;;;:::i;:::-;;:::i;35799:133::-;;;;;;;;;;;;;:::i;48379:86::-;;;;;;;;;;-1:-1:-1;48450:7:0;;;;48379:86;;4478:14:1;;4471:22;4453:41;;4441:2;4426:18;48379:86:0;4313:187:1;91372:144:0;;;;;;;;;;;;;:::i;91873:508::-;;;;;;;;;;-1:-1:-1;91873:508:0;;;;;:::i;:::-;;:::i;105716:122::-;;;;;;;;;;-1:-1:-1;105716:122:0;;;;;:::i;:::-;;:::i;46330:151::-;;;;;;;;;;;;;:::i;113015:159::-;;;;;;;;;;;;;:::i;91758:107::-;;;;;;;;;;-1:-1:-1;91844:13:0;;-1:-1:-1;;;;;91844:13:0;91758:107;;109715:1272;;;;;;;;;;-1:-1:-1;109715:1272:0;;;;;:::i;:::-;;:::i;94172:79::-;;;;;;;;;;;;;:::i;92946:356::-;;;;;;;;;;-1:-1:-1;92946:356:0;;;;;:::i;:::-;;:::i;43726:87::-;;;;;;;;;;-1:-1:-1;43799:6:0;;-1:-1:-1;;;;;43799:6:0;43726:87;;105104:99;;;;;;;;;;-1:-1:-1;105180:15:0;;;;;;;;;;;;;;;;;105104:99;;106400:781;;;;;;;;;;-1:-1:-1;106400:781:0;;;;;:::i;:::-;;:::i;106208:184::-;;;;;;;;;;-1:-1:-1;106208:184:0;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;106365:19:0;;;;;:10;:19;;;;;;;;;106358:26;;;;;;;;;;;;;;;;;;;;106208:184;;;;;5828:13:1;;5810:32;;5898:4;5886:17;;;5880:24;5858:20;;;5851:54;;;;5783:18;106208:184:0;5598:313:1;91645:105:0;;;;;;;;;;-1:-1:-1;91730:12:0;;-1:-1:-1;;;;;91730:12:0;91645:105;;113182:1239;;;;;;;;;;;;;:::i;90616:532::-;;;;;;;;;;-1:-1:-1;90616:532:0;;;;;:::i;:::-;;:::i;46170:152::-;;;;;;;;;;;;;:::i;112156:851::-;;;;;;;;;;-1:-1:-1;112156:851:0;;;;;:::i;:::-;;:::i;93310:854::-;;;;;;;;;;-1:-1:-1;93310:854:0;;;;;:::i;:::-;;:::i;45904:258::-;;;;;;;;;;-1:-1:-1;45904:258:0;;;;;:::i;:::-;;:::i;89203:67::-;;;;;;;;;;;;89250:20;89203:67;;105463:245;105640:12;;105518:7;;105558:142;;105609:44;;-1:-1:-1;;;;;105640:12:0;105609:30;:44::i;:::-;105590:16;;:63;;;;:::i;:::-;3531:4;105558:13;:142::i;:::-;105538:162;;105463:245;:::o;108615:1092::-;47984:19;:17;:19::i;:::-;39466:1:::1;40241:7;;:19:::0;40233:63:::1;;;::::0;-1:-1:-1;;;40233:63:0;;6682:2:1;40233:63:0::1;::::0;::::1;6664:21:1::0;6721:2;6701:18;;;6694:30;6760:33;6740:18;;;6733:61;6811:18;;40233:63:0::1;;;;;;;;;39466:1;40374:7;:18:::0;108907:35:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;108907:35:0::2;::::0;::::2;::::0;108826:14;;108866:39;;::::2;108858:85;;;;-1:-1:-1::0;;;108858:85:0::2;;;;;;;;:::i;:::-;;108954:25;108997:9:::0;108992:113:::2;109013:20;109008:1;:25;108992:113;;109076:14;;109091:1;109076:17;;;;;;;:::i;:::-;;;;;;;109055:38;;;;;:::i;:::-;::::0;-1:-1:-1;109035:3:0::2;::::0;::::2;:::i;:::-;;;108992:113;;;-1:-1:-1::0;109278:17:0;109139:135:::2;41844:10:::0;109184:12:::2;109246;::::0;109215:44:::2;::::0;-1:-1:-1;;;;;109246:12:0::2;109215:30;:44::i;:::-;109139:26;:135::i;:::-;:156;;109310:51;;;;;;;;;;;;;-1:-1:-1::0;;;109310:51:0::2;;::::0;109117:255:::2;;;;;-1:-1:-1::0;;;109117:255:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;41844:10:0;109385:48:::2;::::0;;;:34:::2;:48;::::0;;;;:69;;109437:17;;109385:48;:69:::2;::::0;109437:17;;109385:69:::2;:::i;:::-;::::0;;;-1:-1:-1;;109492:16:0::2;::::0;-1:-1:-1;;;;;109492:16:0::2;109467:58;41844:10:::0;109567:8:::2;;109590:14;;109467:148;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;109660:12;41844:10:::0;;41764:98;109660:12:::2;-1:-1:-1::0;;;;;109633:66:0::2;;109674:8;;109684:14;;109633:66;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;39422:1:0::1;40553:7;:22:::0;-1:-1:-1;;;;108615:1092:0:o;110995:1153::-;47984:19;:17;:19::i;:::-;39466:1:::1;40241:7;;:19:::0;40233:63:::1;;;::::0;-1:-1:-1;;;40233:63:0;;6682:2:1;40233:63:0::1;::::0;::::1;6664:21:1::0;6721:2;6701:18;;;6694:30;6760:33;6740:18;;;6733:61;6811:18;;40233:63:0::1;6480:355:1::0;40233:63:0::1;39466:1;40374:7;:18:::0;111279:35:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;111279:35:0::2;::::0;::::2;::::0;111204:8;;111238:39;;::::2;111230:85;;;;-1:-1:-1::0;;;111230:85:0::2;;;;;;;;:::i;:::-;;111328:33;111379:9:::0;111374:196:::2;111395:14;111390:1;:19;111374:196;;111459:1;111439:14;;111454:1;111439:17;;;;;;;:::i;:::-;;;;;;;:21;111462:34;;;;;;;;;;;;;-1:-1:-1::0;;;111462:34:0::2;;::::0;111431:66:::2;;;;;-1:-1:-1::0;;;111431:66:0::2;;;;;;;;:::i;:::-;;111541:14;;111556:1;111541:17;;;;;;;:::i;:::-;;;;;;;111512:46;;;;;:::i;:::-;::::0;-1:-1:-1;111411:3:0::2;::::0;::::2;:::i;:::-;;;111374:196;;;-1:-1:-1::0;41844:10:0;111582:17:::2;111649:45:::0;;;:34:::2;:45;::::0;;;;;;;;;111738:59;;;;::::2;::::0;;;::::2;::::0;;::::2;::::0;;::::2;::::0;;;;111649:74;-1:-1:-1;111649:74:0::2;111627:181;;;;-1:-1:-1::0;;;111627:181:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;111846:16:0::2;::::0;111821:147:::2;::::0;-1:-1:-1;;;111821:147:0;;-1:-1:-1;;;;;111846:16:0;;::::2;::::0;111821:60:::2;::::0;:147:::2;::::0;111896:9;;111920:8;;;;111943:14;;;;111821:147:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;;;;;;;111981:45:0;::::2;;::::0;;;:34:::2;:45;::::0;;;;:74;;112030:25;;111981:45;:74:::2;::::0;112030:25;;111981:74:::2;:::i;:::-;;;;;;;;112104:9;-1:-1:-1::0;;;;;112073:67:0::2;;112115:8;;112125:14;;112073:67;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;39422:1:0::1;40553:7;:22:::0;-1:-1:-1;;;;;110995:1153:0:o;92389:549::-;43612:13;:11;:13::i;:::-;92534:20:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;92534:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;92496:36:0;::::1;92488:67;;;;-1:-1:-1::0;;;92488:67:0::1;;;;;;;;:::i;:::-;;89464:66;92648:20;;92605:22;-1:-1:-1::0;;;;;92588:54:0::1;;:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;92683:24;;;;;;;;;;;;;-1:-1:-1::0;;;92683:24:0::1;;::::0;92566:152:::1;;;;;-1:-1:-1::0;;;92566:152:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;92762:16:0::1;::::0;;-1:-1:-1;;;;;92789:41:0;;::::1;-1:-1:-1::0;;;;;;92789:41:0;::::1;::::0;::::1;::::0;;;92762:16:::1;::::0;;92869:12:::1;41844:10:::0;;41764:98;92869:12:::1;-1:-1:-1::0;;;;;92846:84:0::1;;;;;;;;;;;92477:461;92389:549:::0;:::o;107189:1418::-;47984:19;:17;:19::i;:::-;39466:1:::1;40241:7;;:19:::0;40233:63:::1;;;::::0;-1:-1:-1;;;40233:63:0;;6682:2:1;40233:63:0::1;::::0;::::1;6664:21:1::0;6721:2;6701:18;;;6694:30;6760:33;6740:18;;;6733:61;6811:18;;40233:63:0::1;6480:355:1::0;40233:63:0::1;39466:1;40374:7;:18:::0;107312:34:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;107312:34:0::2;::::0;::::2;::::0;107293:17;107285:62:::2;;;;-1:-1:-1::0;;;107285:62:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;107389:12:0::2;::::0;-1:-1:-1;;;;;107389:12:0::2;41844:10:::0;107360:26:::2;107480:50;107389:12:::0;107480:30:::2;:50::i;:::-;107457:73;;107541:30;107574:51;107601:9;107612:12;107574:26;:51::i;:::-;107541:84;;107686:13;107660:22;:39;;107714:51;;;;;;;;;;;;;-1:-1:-1::0;;;107714:51:0::2;;::::0;107638:138:::2;;;;;-1:-1:-1::0;;;107638:138:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;107789:27:0::2;107819:58;107833:29;3531:4;107833:13:::0;:29:::2;:::i;:::-;107864:12;107819:13;:58::i;:::-;107789:88;;107939:19;107912:12;:23;107925:9;-1:-1:-1::0;;;;;107912:23:0::2;-1:-1:-1::0;;;;;107912:23:0::2;;;;;;;;;;;;;:46;;107973:38;;;;;;;;;;;;;-1:-1:-1::0;;;107973:38:0::2;;::::0;107890:132:::2;;;;;-1:-1:-1::0;;;107890:132:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;108035:23:0;::::2;;::::0;;;:12:::2;:23;::::0;;;;:46;;108062:19;;108035:23;:46:::2;::::0;108062:19;;108035:46:::2;:::i;:::-;;;;;;;;108112:19;108092:16;;:39;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;108144:35:0::2;::::0;-1:-1:-1;108182:144:0::2;108226:62;108268:19:::0;108226:41:::2;:62::i;:::-;108303:12;108182:29;:144::i;:::-;108339:86;::::0;-1:-1:-1;;;108339:86:0;;-1:-1:-1;;;;;9762:55:1;;;108339:86:0::2;::::0;::::2;9744:74:1::0;9834:18;;;9827:34;;;108144:182:0;;-1:-1:-1;108339:46:0;;::::2;::::0;::::2;::::0;9717:18:1;;108339:86:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;108443:156:0;::::2;;108490:13:::0;108518:12;108545:43:::2;108561:27:::0;108490:13;108545:43:::2;:::i;:::-;108443:156;::::0;;10356:25:1;;;10412:2;10397:18;;10390:34;;;;10440:18;;;10433:34;10344:2;10329:18;108443:156:0::2;10154:319:1::0;36121:200:0;-1:-1:-1;;;;;34671:6:0;34654:23;34662:4;34654:23;34646:80;;;;-1:-1:-1;;;34646:80:0;;10680:2:1;34646:80:0;;;10662:21:1;10719:2;10699:18;;;10692:30;10758:34;10738:18;;;10731:62;-1:-1:-1;;;10809:18:1;;;10802:42;10861:19;;34646:80:0;10478:408:1;34646:80:0;34769:6;-1:-1:-1;;;;;34745:30:0;:20;26097:66;26458:65;-1:-1:-1;;;;;26458:65:0;;26378:153;34745:20;-1:-1:-1;;;;;34745:30:0;;34737:87;;;;-1:-1:-1;;;34737:87:0;;11093:2:1;34737:87:0;;;11075:21:1;11132:2;11112:18;;;11105:30;11171:34;11151:18;;;11144:62;-1:-1:-1;;;11222:18:1;;;11215:42;11274:19;;34737:87:0;10891:408:1;34737:87:0;36205:36:::1;36223:17;36205;:36::i;:::-;36293:12;::::0;;36303:1:::1;36293:12:::0;;;::::1;::::0;::::1;::::0;;;36252:61:::1;::::0;36274:17;;36293:12;36252:21:::1;:61::i;:::-;36121:200:::0;:::o;94259:83::-;90424:13;;-1:-1:-1;;;;;90424:13:0;41844:10;-1:-1:-1;;;;;90408:29:0;;90439:31;;;;;;;;;;;;;-1:-1:-1;;;90439:31:0;;;90400:71;;;;;-1:-1:-1;;;90400:71:0;;;;;;;;:::i;:::-;;94324:10:::1;:8;:10::i;:::-;94259:83::o:0;36580:225::-;-1:-1:-1;;;;;34671:6:0;34654:23;34662:4;34654:23;34646:80;;;;-1:-1:-1;;;34646:80:0;;10680:2:1;34646:80:0;;;10662:21:1;10719:2;10699:18;;;10692:30;10758:34;10738:18;;;10731:62;-1:-1:-1;;;10809:18:1;;;10802:42;10861:19;;34646:80:0;10478:408:1;34646:80:0;34769:6;-1:-1:-1;;;;;34745:30:0;:20;26097:66;26458:65;-1:-1:-1;;;;;26458:65:0;;26378:153;34745:20;-1:-1:-1;;;;;34745:30:0;;34737:87;;;;-1:-1:-1;;;34737:87:0;;11093:2:1;34737:87:0;;;11075:21:1;11132:2;11112:18;;;11105:30;11171:34;11151:18;;;11144:62;-1:-1:-1;;;11222:18:1;;;11215:42;11274:19;;34737:87:0;10891:408:1;34737:87:0;36698:36:::1;36716:17;36698;:36::i;:::-;36745:52;36767:17;36786:4;36792;36745:21;:52::i;:::-;36580:225:::0;;:::o;35799:133::-;35877:7;35107:4;-1:-1:-1;;;;;35116:6:0;35099:23;;35091:92;;;;-1:-1:-1;;;35091:92:0;;11506:2:1;35091:92:0;;;11488:21:1;11545:2;11525:18;;;11518:30;11584:34;11564:18;;;11557:62;11655:26;11635:18;;;11628:54;11699:19;;35091:92:0;11304:420:1;35091:92:0;-1:-1:-1;26097:66:0::1;35799:133:::0;:::o;91372:144::-;91495:12;;91437:7;;91464:44;;-1:-1:-1;;;;;91495:12:0;91464:30;:44::i;91873:508::-;43612:13;:11;:13::i;:::-;92096:46:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;3531:4:::1;92039:42:::0;::::1;;92017:136;;;;-1:-1:-1::0;;;92017:136:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;92183:26:0::1;::::0;;92220:54;;;;92290:83:::1;::::0;;11903:25:1;;;11959:2;11944:18;;11937:34;;;41844:10:0;;92290:83:::1;::::0;11876:18:1;92290:83:0::1;;;;;;;92006:375;91873:508:::0;:::o;105716:122::-;105784:7;105811:19;105822:7;105811:10;:19::i;:::-;105804:26;105716:122;-1:-1:-1;;105716:122:0:o;46330:151::-;43612:13;:11;:13::i;:::-;46404:30:::1;46431:1;46404:18;:30::i;:::-;46445:15;:28:::0;;-1:-1:-1;;;;;;46445:28:0::1;::::0;;46330:151::o;113015:159::-;47984:19;:17;:19::i;:::-;41844:10;113091:24:::1;::::0;;;:10:::1;:24;::::0;;;;;;;113084:31;;;::::1;;::::0;;;113131:35;;11903:25:1;;;11944:18;;;11937:34;;;;113131:35:0::1;::::0;11876:18:1;113131:35:0::1;;;;;;;113015:159::o:0;109715:1272::-;47984:19;:17;:19::i;:::-;39466:1:::1;40241:7;;:19:::0;40233:63:::1;;;::::0;-1:-1:-1;;;40233:63:0;;6682:2:1;40233:63:0::1;::::0;::::1;6664:21:1::0;6721:2;6701:18;;;6694:30;6760:33;6740:18;;;6733:61;6811:18;;40233:63:0::1;6480:355:1::0;40233:63:0::1;39466:1;40374:7;:18:::0;109969:40;;::::2;:84:::0;::::2;;;-1:-1:-1::0;110013:40:0;;::::2;109969:84;110068:35;;;;;;;;;;;;;-1:-1:-1::0;;;110068:35:0::2;;::::0;109947:167:::2;;;;;-1:-1:-1::0;;;109947:167:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;110127:25:0::2;110196:14:::0;110127:25;110228:113:::2;110249:20;110244:1;:25;110228:113;;110312:14;;110327:1;110312:17;;;;;;;:::i;:::-;;;;;;;110291:38;;;;;:::i;:::-;::::0;-1:-1:-1;110271:3:0::2;::::0;::::2;:::i;:::-;;;110228:113;;;-1:-1:-1::0;110514:17:0;110375:135:::2;41844:10:::0;110420:12:::2;41764:98:::0;110375:135:::2;:156;;110546:51;;;;;;;;;;;;;-1:-1:-1::0;;;110546:51:0::2;;::::0;110353:255:::2;;;;;-1:-1:-1::0;;;110353:255:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;41844:10:0;110621:48:::2;::::0;;;:34:::2;:48;::::0;;;;:69;;110673:17;;110621:48;:69:::2;::::0;110673:17;;110621:69:::2;:::i;:::-;::::0;;;-1:-1:-1;;110728:16:0::2;::::0;-1:-1:-1;;;;;110728:16:0::2;110703:73;41844:10:::0;110818:8:::2;;110841:14;;110870;;110703:192;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;110940:12;41844:10:::0;;41764:98;110940:12:::2;-1:-1:-1::0;;;;;110913:66:0::2;;110954:8;;110964:14;;110913:66;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;39422:1:0::1;40553:7;:22:::0;-1:-1:-1;;;;;;109715:1272:0:o;94172:79::-;90424:13;;-1:-1:-1;;;;;90424:13:0;41844:10;-1:-1:-1;;;;;90408:29:0;;90439:31;;;;;;;;;;;;;-1:-1:-1;;;90439:31:0;;;90400:71;;;;;-1:-1:-1;;;90400:71:0;;;;;;;;:::i;:::-;;94235:8:::1;:6;:8::i;92946:356::-:0;43612:13;:11;:13::i;:::-;93082:20:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;93082:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;93047:33:0;::::1;93039:64;;;;-1:-1:-1::0;;;93039:64:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;93144:13:0::1;::::0;;-1:-1:-1;;;;;93168:35:0;;::::1;-1:-1:-1::0;;;;;;93168:35:0;::::1;::::0;::::1;::::0;;;93144:13:::1;::::0;;93239:12:::1;41844:10:::0;;41764:98;93239:12:::1;-1:-1:-1::0;;;;;93219:75:0::1;;;;;;;;;;;93028:274;92946:356:::0;:::o;106400:781::-;47984:19;:17;:19::i;:::-;39466:1:::1;40241:7;;:19:::0;40233:63:::1;;;::::0;-1:-1:-1;;;40233:63:0;;6682:2:1;40233:63:0::1;::::0;::::1;6664:21:1::0;6721:2;6701:18;;;6694:30;6760:33;6740:18;;;6733:61;6811:18;;40233:63:0::1;6480:355:1::0;40233:63:0::1;39466:1;40374:7;:18:::0;106530:34:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;106530:34:0::2;::::0;::::2;::::0;106506:22;106498:67:::2;;;;-1:-1:-1::0;;;106498:67:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;106607:12:0::2;::::0;-1:-1:-1;;;;;106607:12:0::2;41844:10:::0;106578:26:::2;106698:50;106607:12:::0;106698:30:::2;:50::i;:::-;106761:145;::::0;-1:-1:-1;;;106761:145:0;;-1:-1:-1;;;;;13409:15:1;;;106761:145:0::2;::::0;::::2;13391:34:1::0;106858:4:0::2;13441:18:1::0;;;13434:43;13493:18;;;13486:34;;;106675:73:0;;-1:-1:-1;106761:50:0;;::::2;::::0;::::2;::::0;13303:18:1;;106761:145:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;106919:18:0::2;106940:62;106954:33;3531:4;106954:17:::0;:33:::2;:::i;:::-;106989:12;106940:13;:62::i;:::-;-1:-1:-1::0;;;;;107015:23:0;::::2;;::::0;;;:12:::2;:23;::::0;;;;:37;;106919:83;;-1:-1:-1;106919:83:0;;107015:23;;;:37:::2;::::0;106919:83;;107015:37:::2;:::i;:::-;;;;;;;;107083:10;107063:16;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;107111:62:0::2;::::0;;10356:25:1;;;10412:2;10397:18;;10390:34;;;10440:18;;;10433:34;;;-1:-1:-1;;;;;107111:62:0;::::2;::::0;::::2;::::0;10344:2:1;10329:18;107111:62:0::2;;;;;;;;-1:-1:-1::0;;39422:1:0::1;40553:7;:22:::0;-1:-1:-1;;;106400:781:0:o;113182:1239::-;47984:19;:17;:19::i;:::-;39466:1:::1;40241:7;;:19:::0;40233:63:::1;;;::::0;-1:-1:-1;;;40233:63:0;;6682:2:1;40233:63:0::1;::::0;::::1;6664:21:1::0;6721:2;6701:18;;;6694:30;6760:33;6740:18;;;6733:61;6811:18;;40233:63:0::1;6480:355:1::0;40233:63:0::1;39466:1;40374:7;:18:::0;41844:10;113256:17:::2;113358:21:::0;;;:10:::2;:21;::::0;;;;;;;;113301:78;;;;::::2;::::0;;;;;;;::::2;::::0;;::::2;::::0;;;::::2;::::0;113449:27;;;;::::2;::::0;;;::::2;::::0;;::::2;::::0;;::::2;::::0;;;;113301:78;;113449:27;113400:15:::2;:47;;113392:85;;;;-1:-1:-1::0;;;113392:85:0::2;;;;;;;;:::i;:::-;;113528:1;113496:15;:29;;;:33;113531:34;;;;;;;;;;;;;-1:-1:-1::0;;;113531:34:0::2;;::::0;113488:78:::2;;;;;-1:-1:-1::0;;;113488:78:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;113608:12:0::2;::::0;-1:-1:-1;;;;;113608:12:0::2;113579:26;113656:50;113608:12:::0;113656:30:::2;:50::i;:::-;113633:73;;113717:27;113747:111;3531:4;113775:15;:29;;;:45;;;;:::i;113747:111::-;113717:141;;113920:19;113893:12;:23;113906:9;-1:-1:-1::0;;;;;113893:23:0::2;-1:-1:-1::0;;;;;113893:23:0::2;;;;;;;;;;;;;:46;;113954:38;;;;;;;;;;;;;-1:-1:-1::0;;;113954:38:0::2;;::::0;113871:132:::2;;;;;-1:-1:-1::0;;;113871:132:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;114016:23:0;::::2;;::::0;;;:12:::2;:23;::::0;;;;:46;;114043:19;;114016:23;:46:::2;::::0;114043:19;;114016:46:::2;:::i;:::-;;;;;;;;114093:19;114073:16;;:39;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;114132:21:0;;::::2;;::::0;;;:10:::2;:21;::::0;;;;;;;114125:28;;;::::2;;::::0;;;;114317:29;::::2;::::0;114259:88;;-1:-1:-1;;;114259:88:0;;::::2;::::0;::::2;9744:74:1::0;;;;9834:18;;;9827:34;114259:46:0;;::::2;::::0;::::2;::::0;9717:18:1;;114259:88:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;114372:9;-1:-1:-1::0;;;;;114365:48:0::2;;114383:15;:29;;;114365:48;;;;552:25:1::0;;540:2;525:18;;406:177;90616:532:0;22318:19;22341:13;;;;;;22340:14;;22388:34;;;;-1:-1:-1;22406:12:0;;22421:1;22406:12;;;;:16;22388:34;22387:108;;;-1:-1:-1;22467:4:0;13080:19;:23;;;22428:66;;-1:-1:-1;22477:12:0;;;;;:17;22428:66;22365:204;;;;-1:-1:-1;;;22365:204:0;;13733:2:1;22365:204:0;;;13715:21:1;13772:2;13752:18;;;13745:30;13811:34;13791:18;;;13784:62;13882:16;13862:18;;;13855:44;13916:19;;22365:204:0;13531:410:1;22365:204:0;22580:12;:16;;-1:-1:-1;;22580:16:0;22595:1;22580:16;;;22607:67;;;;22642:13;:20;;-1:-1:-1;;22642:20:0;;;;;22607:67;90687:27:::1;:25;:27::i;:::-;90725:26;:24;:26::i;:::-;90762:34;:32;:34::i;:::-;90842:20;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;90842:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;90815:25:0;::::1;90807:56;;;;-1:-1:-1::0;;;90807:56:0::1;;;;;;;;:::i;:::-;;89333:66;90941:16;;90909:11;-1:-1:-1::0;;;;;90896:39:0::1;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:61;90972:24;;;;;;;;;;;;;-1:-1:-1::0;;;90972:24:0::1;;::::0;90874:133:::1;;;;;-1:-1:-1::0;;;90874:133:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;91018:12:0::1;:26:::0;;-1:-1:-1;;;;;91018:26:0;::::1;-1:-1:-1::0;;;;;;91018:26:0;;::::1;;::::0;;;91055:13:::1;:28:::0;;;;::::1;41844:10:::0;91055:28:::1;::::0;;91123:17:::1;3490:4;91139:1;91123:17;:::i;:::-;91094:26;:46:::0;22696:102;;;;22747:5;22731:21;;-1:-1:-1;;22731:21:0;;;22772:14;;-1:-1:-1;2721:36:1;;22772:14:0;;2709:2:1;2694:18;22772:14:0;;;;;;;22307:498;90616:532;:::o;46170:152::-;45809:15;;45842:33;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45809:15:0;41844:10;45809:31;45801:75;;;;-1:-1:-1;;;45801:75:0;;;;;;;;:::i;:::-;-1:-1:-1;46243:15:0::1;:28:::0;;-1:-1:-1;;;;;;46243:28:0::1;::::0;;46282:32:::1;41844:10:::0;46282:18:::1;:32::i;112156:851::-:0;47984:19;:17;:19::i;:::-;39466:1:::1;40241:7;;:19:::0;40233:63:::1;;;::::0;-1:-1:-1;;;40233:63:0;;6682:2:1;40233:63:0::1;::::0;::::1;6664:21:1::0;6721:2;6701:18;;;6694:30;6760:33;6740:18;;;6733:61;6811:18;;40233:63:0::1;6480:355:1::0;40233:63:0::1;39466:1;40374:7;:18:::0;112280:34:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;112280:34:0::2;::::0;::::2;::::0;112261:17;112253:62:::2;;;;-1:-1:-1::0;;;112253:62:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;41844:10:0;112328:17:::2;112546:45:::0;;;:34:::2;:45;::::0;;;;;;;;112450:12:::2;:23:::0;;;;;;112519:12:::2;::::0;112406:137:::2;::::0;112450:23;112488:44:::2;::::0;-1:-1:-1;;;;;112519:12:0::2;112488:30;:44::i;:::-;112406:29;:137::i;:::-;:185;;;;:::i;:::-;112373:218;;112652:13;112626:22;:39;;112680:51;;;;;;;;;;;;;-1:-1:-1::0;;;112680:51:0::2;;::::0;112604:138:::2;;;;;-1:-1:-1::0;;;112604:138:0::2;;;;;;;;:::i;:::-;;112779:123;;;;;;;;89250:20;112825:15;:38;;;;:::i;:::-;112779:123:::0;;::::2;::::0;;::::2;::::0;;;-1:-1:-1;;;;;112755:21:0;::::2;-1:-1:-1::0;112755:21:0;;;:10:::2;:21:::0;;;;;:147;;;;;;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;112918:81:::2;112878:13:::0;112960:38:::2;89250:20;112960:15;:38;:::i;:::-;112918:81;::::0;;11903:25:1;;;11959:2;11944:18;;11937:34;;;;11876:18;112918:81:0::2;;;;;;;-1:-1:-1::0;;39422:1:0::1;40553:7;:22:::0;-1:-1:-1;112156:851:0:o;93310:854::-;47984:19;:17;:19::i;:::-;90280:16:::1;::::0;-1:-1:-1;;;;;90280:16:0::1;41844:10:::0;-1:-1:-1;;;;;90264:32:0::1;;90298:34;;;;;;;;;;;;;;;;::::0;90256:77:::1;;;;;-1:-1:-1::0;;;90256:77:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;93526:12:0::2;::::0;-1:-1:-1;;;;;93526:12:0::2;93497:26;93638:50;93526:12:::0;93638:30:::2;:50::i;:::-;93615:73;;93723:1;93707:13;:17;93726:34;;;;;;;;;;;;;-1:-1:-1::0;;;93726:34:0::2;;::::0;93699:62:::2;;;;;-1:-1:-1::0;;;93699:62:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;93774:50:0;::::2;;41844:10:::0;93774:144:::2;::::0;;::::2;::::0;;;;;;-1:-1:-1;;;;;13409:15:1;;;93774:144:0::2;::::0;::::2;13391:34:1::0;93874:4:0::2;13441:18:1::0;;;13434:43;13493:18;;;13486:34;;;13303:18;;93774:144:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;93931:18:0::2;93952:58;93966:29;3531:4;93966:13:::0;:29:::2;:::i;93952:58::-;-1:-1:-1::0;;;;;94023:21:0;::::2;;::::0;;;:12:::2;:21;::::0;;;;:35;;93931:79;;-1:-1:-1;93931:79:0;;94023:21;;;:35:::2;::::0;93931:79;;94023:35:::2;:::i;:::-;;;;;;;;94089:10;94069:16;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;94117:39:0::2;::::0;;-1:-1:-1;;;;;9762:55:1;;9744:74;;9849:2;9834:18;;9827:34;;;94117:39:0::2;::::0;9717:18:1;94117:39:0::2;;;;;;;93486:678;;;93310:854:::0;;:::o;45904:258::-;43612:13;:11;:13::i;:::-;46030:20:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;46030:20:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;46000:28:0;::::1;45992:59;;;;-1:-1:-1::0;;;45992:59:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;46062:15:0::1;:32:::0;;-1:-1:-1;;;;;;46062:32:0::1;-1:-1:-1::0;;;;;46062:32:0;::::1;::::0;;::::1;::::0;;;46110:44:::1;::::0;::::1;::::0;-1:-1:-1;;46110:44:0::1;45904:258:::0;:::o;94350:586::-;94519:16;;94468:7;;94552:20;;;94548:73;;-1:-1:-1;3531:4:0;;94350:586;-1:-1:-1;;94350:586:0:o;94548:73::-;94664:86;;-1:-1:-1;;;94664:86:0;;94734:4;94664:86;;;2914:74:1;94633:28:0;;-1:-1:-1;;;;;94664:47:0;;;;;2887:18:1;;94664:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94633:117;;94767:20;94791:1;94767:25;94763:78;;-1:-1:-1;3531:4:0;;94350:586;-1:-1:-1;;;94350:586:0:o;94763:78::-;94860:68;94874:36;3531:4;94874:20;:36;:::i;94860:68::-;94853:75;94350:586;-1:-1:-1;;;;94350:586:0:o;3803:114::-;3866:9;3908:1;3898:5;3902:1;3908;3898:5;:::i;:::-;3893:11;;:1;:11;:::i;:::-;3892:17;;;;:::i;:::-;3888:21;3803:114;-1:-1:-1;;;3803:114:0:o;48538:108::-;48450:7;;;;48608:9;48600:38;;;;-1:-1:-1;;;48600:38:0;;14758:2:1;48600:38:0;;;14740:21:1;14797:2;14777:18;;;14770:30;14836:18;14816;;;14809:46;14872:18;;48600:38:0;14556:340:1;95447:352:0;-1:-1:-1;;;;;95758:19:0;;95572:7;95758:19;;;:10;:19;;;;;;;;:33;;;95699:34;:43;;;;;;95647:12;:21;;;;;;;95758:33;;95699:43;95617:66;;95670:12;95617:29;:66::i;:::-;:125;;;;:::i;:::-;:174;;;;:::i;43891:132::-;43799:6;;-1:-1:-1;;;;;43799:6:0;41844:10;43955:23;43947:68;;;;-1:-1:-1;;;43947:68:0;;15103:2:1;43947:68:0;;;15085:21:1;;;15122:18;;;15115:30;15181:34;15161:18;;;15154:62;15233:18;;43947:68:0;14901:356:1;94944:261:0;95065:7;95110:87;95171:10;95141:26;;3531:4;95125:42;;;;:::i;:::-;95124:57;;;;:::i;95213:226::-;95344:7;95376:55;95390:25;95403:12;95390:10;:25;:::i;96109:66::-;43612:13;:11;:13::i;27796:992::-;25749:66;28250:59;;;28246:535;;;28326:37;28345:17;28326:18;:37::i;:::-;27796:992;;;:::o;28246:535::-;28429:17;-1:-1:-1;;;;;28400:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;28400:63:0;;;;;;;;-1:-1:-1;;28400:63:0;;;;;;;;;;;;:::i;:::-;;;28396:306;;28630:56;;-1:-1:-1;;;28630:56:0;;15464:2:1;28630:56:0;;;15446:21:1;15503:2;15483:18;;;15476:30;15542:34;15522:18;;;15515:62;15613:16;15593:18;;;15586:44;15647:19;;28630:56:0;15262:410:1;28396:306:0;26097:66;28514:28;;28506:82;;;;-1:-1:-1;;;28506:82:0;;15879:2:1;28506:82:0;;;15861:21:1;15918:2;15898:18;;;15891:30;15957:34;15937:18;;;15930:62;16028:11;16008:18;;;16001:39;16057:19;;28506:82:0;15677:405:1;28506:82:0;28464:140;28716:53;28734:17;28753:4;28759:9;28716:17;:53::i;49234:120::-;48243:16;:14;:16::i;:::-;49293:7:::1;:15:::0;;-1:-1:-1;;49293:15:0::1;::::0;;49324:22:::1;41844:10:::0;49333:12:::1;49324:22;::::0;-1:-1:-1;;;;;2932:55:1;;;2914:74;;2902:2;2887:18;49324:22:0::1;;;;;;;49234:120::o:0;95807:255::-;-1:-1:-1;;;;;95955:21:0;;;95867:7;95955:21;;;:12;:21;;;;;;96026:12;;95867:7;;95907:147;;95995:44;;96026:12;95995:30;:44::i;44993:191::-;45086:6;;;-1:-1:-1;;;;;45103:17:0;;;-1:-1:-1;;;;;;45103:17:0;;;;;;;45136:40;;45086:6;;;45103:17;45086:6;;45136:40;;45067:16;;45136:40;45056:128;44993:191;:::o;48975:118::-;47984:19;:17;:19::i;:::-;49035:7:::1;:14:::0;;-1:-1:-1;;49035:14:0::1;49045:4;49035:14;::::0;;49065:20:::1;49072:12;41844:10:::0;;41764:98;47656:97;24159:13;;;;;;;24151:69;;;;-1:-1:-1;;;24151:69:0;;16289:2:1;24151:69:0;;;16271:21:1;16328:2;16308:18;;;16301:30;16367:34;16347:18;;;16340:62;-1:-1:-1;;;16418:18:1;;;16411:41;16469:19;;24151:69:0;16087:407:1;24151:69:0;47730:7:::1;:15:::0;;-1:-1:-1;;47730:15:0::1;::::0;;47656:97::o;43374:113::-;24159:13;;;;;;;24151:69;;;;-1:-1:-1;;;24151:69:0;;16289:2:1;24151:69:0;;;16271:21:1;16328:2;16308:18;;;16301:30;16367:34;16347:18;;;16340:62;-1:-1:-1;;;16418:18:1;;;16411:41;16469:19;;24151:69:0;16087:407:1;24151:69:0;43447:32:::1;41844:10:::0;46282:18:::1;:32::i;33875:78::-:0;24159:13;;;;;;;24151:69;;;;-1:-1:-1;;;24151:69:0;;16289:2:1;24151:69:0;;;16271:21:1;16328:2;16308:18;;;16301:30;16367:34;16347:18;;;16340:62;-1:-1:-1;;;16418:18:1;;;16411:41;16469:19;;24151:69:0;16087:407:1;26627:284:0;-1:-1:-1;;;;;13080:19:0;;;26701:106;;;;-1:-1:-1;;;26701:106:0;;16701:2:1;26701:106:0;;;16683:21:1;16740:2;16720:18;;;16713:30;16779:34;16759:18;;;16752:62;16850:15;16830:18;;;16823:43;16883:19;;26701:106:0;16499:409:1;26701:106:0;26097:66;26818:85;;-1:-1:-1;;;;;;26818:85:0;-1:-1:-1;;;;;26818:85:0;;;;;;;;;;26627:284::o;27320:297::-;27463:29;27474:17;27463:10;:29::i;:::-;27521:1;27507:4;:11;:15;:28;;;;27526:9;27507:28;27503:107;;;27552:46;27574:17;27593:4;27552:21;:46::i;:::-;;27320:297;;;:::o;48723:108::-;48450:7;;;;48782:41;;;;-1:-1:-1;;;48782:41:0;;17115:2:1;48782:41:0;;;17097:21:1;17154:2;17134:18;;;17127:30;17193:22;17173:18;;;17166:50;17233:18;;48782:41:0;16913:344:1;27024:155:0;27091:37;27110:17;27091:18;:37::i;:::-;27144:27;;-1:-1:-1;;;;;27144:27:0;;;;;;;;27024:155;:::o;32057:461::-;32140:12;-1:-1:-1;;;;;13080:19:0;;;32165:88;;;;-1:-1:-1;;;32165:88:0;;17464:2:1;32165:88:0;;;17446:21:1;17503:2;17483:18;;;17476:30;17542:34;17522:18;;;17515:62;17613:8;17593:18;;;17586:36;17639:19;;32165:88:0;17262:402:1;32165:88:0;32327:12;32341:23;32368:6;-1:-1:-1;;;;;32368:19:0;32388:4;32368:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32326:67;;;;32411:99;32447:7;32456:10;32411:99;;;;;;;;;;;;;;;;;:35;:99::i;:::-;32404:106;32057:461;-1:-1:-1;;;;;32057:461:0:o;18359:762::-;18509:12;18538:7;18534:580;;;-1:-1:-1;18569:10:0;18562:17;;18534:580;18683:17;;:21;18679:424;;18931:10;18925:17;18992:15;18979:10;18975:2;18971:19;18964:44;18679:424;19074:12;19067:20;;-1:-1:-1;;;19067:20:0;;;;;;;;:::i;14:196:1:-;82:20;;-1:-1:-1;;;;;131:54:1;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;588:250::-;673:1;683:113;697:6;694:1;691:13;683:113;;;773:11;;;767:18;754:11;;;747:39;719:2;712:10;683:113;;;-1:-1:-1;;830:1:1;812:16;;805:27;588:250::o;843:396::-;992:2;981:9;974:21;955:4;1024:6;1018:13;1067:6;1062:2;1051:9;1047:18;1040:34;1083:79;1155:6;1150:2;1139:9;1135:18;1130:2;1122:6;1118:15;1083:79;:::i;:::-;1223:2;1202:15;-1:-1:-1;;1198:29:1;1183:45;;;;1230:2;1179:54;;843:396;-1:-1:-1;;843:396:1:o;1244:367::-;1307:8;1317:6;1371:3;1364:4;1356:6;1352:17;1348:27;1338:55;;1389:1;1386;1379:12;1338:55;-1:-1:-1;1412:20:1;;1455:18;1444:30;;1441:50;;;1487:1;1484;1477:12;1441:50;1524:4;1516:6;1512:17;1500:29;;1584:3;1577:4;1567:6;1564:1;1560:14;1552:6;1548:27;1544:38;1541:47;1538:67;;;1601:1;1598;1591:12;1538:67;1244:367;;;;;:::o;1616:773::-;1738:6;1746;1754;1762;1815:2;1803:9;1794:7;1790:23;1786:32;1783:52;;;1831:1;1828;1821:12;1783:52;1871:9;1858:23;1900:18;1941:2;1933:6;1930:14;1927:34;;;1957:1;1954;1947:12;1927:34;1996:70;2058:7;2049:6;2038:9;2034:22;1996:70;:::i;:::-;2085:8;;-1:-1:-1;1970:96:1;-1:-1:-1;2173:2:1;2158:18;;2145:32;;-1:-1:-1;2189:16:1;;;2186:36;;;2218:1;2215;2208:12;2186:36;;2257:72;2321:7;2310:8;2299:9;2295:24;2257:72;:::i;:::-;1616:773;;;;-1:-1:-1;2348:8:1;-1:-1:-1;;;;1616:773:1:o;2394:180::-;2453:6;2506:2;2494:9;2485:7;2481:23;2477:32;2474:52;;;2522:1;2519;2512:12;2474:52;-1:-1:-1;2545:23:1;;2394:180;-1:-1:-1;2394:180:1:o;3181:127::-;3242:10;3237:3;3233:20;3230:1;3223:31;3273:4;3270:1;3263:15;3297:4;3294:1;3287:15;3313:995;3390:6;3398;3451:2;3439:9;3430:7;3426:23;3422:32;3419:52;;;3467:1;3464;3457:12;3419:52;3490:29;3509:9;3490:29;:::i;:::-;3480:39;;3570:2;3559:9;3555:18;3542:32;3593:18;3634:2;3626:6;3623:14;3620:34;;;3650:1;3647;3640:12;3620:34;3688:6;3677:9;3673:22;3663:32;;3733:7;3726:4;3722:2;3718:13;3714:27;3704:55;;3755:1;3752;3745:12;3704:55;3791:2;3778:16;3813:2;3809;3806:10;3803:36;;;3819:18;;:::i;:::-;3894:2;3888:9;3862:2;3948:13;;-1:-1:-1;;3944:22:1;;;3968:2;3940:31;3936:40;3924:53;;;3992:18;;;4012:22;;;3989:46;3986:72;;;4038:18;;:::i;:::-;4078:10;4074:2;4067:22;4113:2;4105:6;4098:18;4153:7;4148:2;4143;4139;4135:11;4131:20;4128:33;4125:53;;;4174:1;4171;4164:12;4125:53;4230:2;4225;4221;4217:11;4212:2;4204:6;4200:15;4187:46;4275:1;4270:2;4265;4257:6;4253:15;4249:24;4242:35;4296:6;4286:16;;;;;;;3313:995;;;;;:::o;4505:1088::-;4663:6;4671;4679;4687;4695;4703;4756:2;4744:9;4735:7;4731:23;4727:32;4724:52;;;4772:1;4769;4762:12;4724:52;4812:9;4799:23;4841:18;4882:2;4874:6;4871:14;4868:34;;;4898:1;4895;4888:12;4868:34;4937:70;4999:7;4990:6;4979:9;4975:22;4937:70;:::i;:::-;5026:8;;-1:-1:-1;4911:96:1;-1:-1:-1;5114:2:1;5099:18;;5086:32;;-1:-1:-1;5130:16:1;;;5127:36;;;5159:1;5156;5149:12;5127:36;5198:72;5262:7;5251:8;5240:9;5236:24;5198:72;:::i;:::-;5289:8;;-1:-1:-1;5172:98:1;-1:-1:-1;5377:2:1;5362:18;;5349:32;;-1:-1:-1;5393:16:1;;;5390:36;;;5422:1;5419;5412:12;5390:36;;5461:72;5525:7;5514:8;5503:9;5499:24;5461:72;:::i;:::-;4505:1088;;;;-1:-1:-1;4505:1088:1;;-1:-1:-1;4505:1088:1;;5552:8;;4505:1088;-1:-1:-1;;;4505:1088:1:o;5916:254::-;5984:6;5992;6045:2;6033:9;6024:7;6020:23;6016:32;6013:52;;;6061:1;6058;6051:12;6013:52;6084:29;6103:9;6084:29;:::i;:::-;6074:39;6160:2;6145:18;;;;6132:32;;-1:-1:-1;;;5916:254:1:o;6175:127::-;6236:10;6231:3;6227:20;6224:1;6217:31;6267:4;6264:1;6257:15;6291:4;6288:1;6281:15;6307:168;6380:9;;;6411;;6428:15;;;6422:22;;6408:37;6398:71;;6449:18;;:::i;6840:127::-;6901:10;6896:3;6892:20;6889:1;6882:31;6932:4;6929:1;6922:15;6956:4;6953:1;6946:15;6972:125;7037:9;;;7058:10;;;7055:36;;;7071:18;;:::i;7102:135::-;7141:3;7162:17;;;7159:43;;7182:18;;:::i;:::-;-1:-1:-1;7229:1:1;7218:13;;7102:135::o;7242:470::-;7342:6;7337:3;7330:19;7312:3;7368:4;7397:2;7392:3;7388:12;7381:19;;7423:5;7446:1;7456:231;7470:6;7467:1;7464:13;7456:231;;;-1:-1:-1;;;;;7535:26:1;7554:6;7535:26;:::i;:::-;7531:75;7519:88;;7627:12;;;;7662:15;;;;7492:1;7485:9;7456:231;;;-1:-1:-1;7703:3:1;;7242:470;-1:-1:-1;;;;;7242:470:1:o;7717:358::-;7817:6;7812:3;7805:19;7787:3;7847:66;7839:6;7836:78;7833:98;;;7927:1;7924;7917:12;7833:98;7963:6;7960:1;7956:14;8015:8;8008:5;8001:4;7996:3;7992:14;7979:45;8044:18;;;;8064:4;8040:29;;7717:358;-1:-1:-1;;;7717:358:1:o;8080:639::-;-1:-1:-1;;;;;8389:6:1;8385:55;8374:9;8367:74;8477:2;8472;8461:9;8457:18;8450:30;8348:4;8503:73;8572:2;8561:9;8557:18;8549:6;8541;8503:73;:::i;:::-;8624:9;8616:6;8612:22;8607:2;8596:9;8592:18;8585:50;8652:61;8706:6;8698;8690;8652:61;:::i;:::-;8644:69;8080:639;-1:-1:-1;;;;;;;;8080:639:1:o;8724:519::-;9001:2;8990:9;8983:21;8964:4;9027:73;9096:2;9085:9;9081:18;9073:6;9065;9027:73;:::i;:::-;9148:9;9140:6;9136:22;9131:2;9120:9;9116:18;9109:50;9176:61;9230:6;9222;9214;9176:61;:::i;:::-;9168:69;8724:519;-1:-1:-1;;;;;;;8724:519:1:o;9248:128::-;9315:9;;;9336:11;;;9333:37;;;9350:18;;:::i;9381:184::-;9451:6;9504:2;9492:9;9483:7;9479:23;9475:32;9472:52;;;9520:1;9517;9510:12;9472:52;-1:-1:-1;9543:16:1;;9381:184;-1:-1:-1;9381:184:1:o;9872:277::-;9939:6;9992:2;9980:9;9971:7;9967:23;9963:32;9960:52;;;10008:1;10005;9998:12;9960:52;10040:9;10034:16;10093:5;10086:13;10079:21;10072:5;10069:32;10059:60;;10115:1;10112;10105:12;12251:872;-1:-1:-1;;;;;12648:6:1;12644:55;12633:9;12626:74;12736:3;12731:2;12720:9;12716:18;12709:31;12607:4;12763:74;12832:3;12821:9;12817:19;12809:6;12801;12763:74;:::i;:::-;12885:9;12877:6;12873:22;12868:2;12857:9;12853:18;12846:50;12919:61;12973:6;12965;12957;12919:61;:::i;:::-;12905:75;;13028:9;13020:6;13016:22;13011:2;13000:9;12996:18;12989:50;13056:61;13110:6;13102;13094;13056:61;:::i;:::-;13048:69;12251:872;-1:-1:-1;;;;;;;;;;12251:872:1:o;14334:217::-;14374:1;14400;14390:132;;14444:10;14439:3;14435:20;14432:1;14425:31;14479:4;14476:1;14469:15;14507:4;14504:1;14497:15;14390:132;-1:-1:-1;14536:9:1;;14334:217::o;17669:287::-;17798:3;17836:6;17830:13;17852:66;17911:6;17906:3;17899:4;17891:6;17887:17;17852:66;:::i;:::-;17934:16;;;;;17669:287;-1:-1:-1;;17669:287:1:o
Swarm Source
ipfs://121b656699a7d9b8b4a631920479102186bbf509a7401ddb478eeb565dd0eabf
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.