Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
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 Source Code Verified (Exact Match)
Contract Name:
StrategyCompound
Compiler Version
v0.8.16+commit.07a7930e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-11-03 */ // File: contracts/libraries/errors/StanleyErrors.sol pragma solidity 0.8.16; library StanleyErrors { // 500-599-stanley string public constant ASSET_MISMATCH = "IPOR_500"; // only stanley can have access to function string public constant CALLER_NOT_STANLEY = "IPOR_501"; string public constant INCORRECT_TREASURY_ADDRESS = "IPOR_502"; //@notice amount should be > 0 string public constant IV_TOKEN_MINT_AMOUNT_TOO_LOW = "IPOR_503"; //@notice amount should be > 0 string public constant IV_TOKEN_BURN_AMOUNT_TOO_LOW = "IPOR_504"; // only Treasury Manager can have access to function string public constant CALLER_NOT_TREASURY_MANAGER = "IPOR_505"; // problem with redeem shared token string public constant SHARED_TOKEN_REDEEM_ERROR = "IPOR_506"; } // File: contracts/libraries/errors/IporErrors.sol pragma solidity 0.8.16; library IporErrors { // 000-199 - general codes /// @notice General problem, address is wrong string public constant WRONG_ADDRESS = "IPOR_000"; /// @notice General problem. Wrong decimals string public constant WRONG_DECIMALS = "IPOR_001"; string public constant ADDRESSES_MISMATCH = "IPOR_002"; //@notice Trader doesnt have enought tokens to execute transaction string public constant ASSET_BALANCE_TOO_LOW = "IPOR_003"; string public constant VALUE_NOT_GREATER_THAN_ZERO = "IPOR_004"; string public constant INPUT_ARRAYS_LENGTH_MISMATCH = "IPOR_005"; //@notice Amount is too low to transfer string public constant NOT_ENOUGH_AMOUNT_TO_TRANSFER = "IPOR_006"; //@notice msg.sender is not an appointed owner, so cannot confirm his appointment to be an owner of a specific smart contract string public constant SENDER_NOT_APPOINTED_OWNER = "IPOR_007"; //only milton can have access to function string public constant CALLER_NOT_MILTON = "IPOR_008"; string public constant CHUNK_SIZE_EQUAL_ZERO = "IPOR_009"; string public constant CHUNK_SIZE_TOO_BIG = "IPOR_010"; } // 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: contracts/vault/interfaces/compound/ComptrollerInterface.sol pragma solidity 0.8.16; interface ComptrollerInterface { function claimComp(address holder) external; function claimComp(address holder, address[] calldata) external; function claimComp( address[] calldata holders, address[] calldata cTokens, bool borrowers, bool suppliers ) external; } // File: contracts/vault/interfaces/compound/CErc20.sol pragma solidity 0.8.16; interface CErc20 { function mint(uint256) external returns (uint256); function exchangeRateCurrent() external returns (uint256); function supplyRatePerBlock() external view returns (uint256); function balanceOf(address) external view returns (uint256); function exchangeRateStored() external view returns (uint256); function redeem(uint256) external returns (uint256); function decimals() external view returns (uint8); } // File: contracts/interfaces/IStrategy.sol pragma solidity 0.8.16; /// @title Interface for interaction with Stanley's strategy. /// @notice Strategy represents an external DeFi protocol and acts as and wrapper that standarizes the API of the external protocol. interface IStrategy { /// @notice Returns current version of strategy /// @dev Increase number when implementation inside source code is different that implementation deployed on Mainnet /// @return current Strategy's version function getVersion() external pure returns (uint256); /// @notice Gets asset / underlying token / stablecoin which is assocciated with this Strategy instance /// @return asset / underlying token / stablecoin address function getAsset() external view returns (address); /// @notice Returns strategy's share token address function getShareToken() external view returns (address); /// @notice Gets annualised interest rate (APR) for this strategy. /// @return APR value, represented in 18 decimals. function getApr() external view returns (uint256); /// @notice Gets balance for given asset (underlying / stablecoin) allocated to this strategy. /// @return balance for given asset, represented in 18 decimals. function balanceOf() external view returns (uint256); /// @notice Deposits asset amount from Stanley to this specific Strategy. Function available only for Stanley. /// @dev Emits {Transfer} from ERC20 asset. If available then events from external DeFi protocol assocciated with this strategy. /// @param amount asset amount represented in 18 decimals. function deposit(uint256 amount) external returns (uint256 depositedAmount); /// @notice Withdraws asset amount from Strategy to Stanley. Function available only for Stanley. /// @dev Emits {Transfer} from ERC20 asset. If available then events from external DeFi protocol assocciated with this strategy. /// @param amount asset amount represented in 18 decimals. /// @return withdrawnAmount The final amount withdrawn, represented in 18 decimals function withdraw(uint256 amount) external returns (uint256 withdrawnAmount); /// @notice Claims rewards. Function can be executed by anyone. function doClaim() external; /// @notice Gets Stanley address. function getStanley() external view returns (address); /// @notice Sets new Stanley address. Function can be executed only by the smart contract Owner. /// @param newStanley new Stanley address function setStanley(address newStanley) external; /// @notice Gets Treasury address. /// @return Treasury address. function getTreasury() external view returns (address); /// @notice Sets new Treasury address. Function can be executed only by the smart contract Owner. /// @param newTreasury new Treasury address function setTreasury(address newTreasury) external; /// @notice Gets new Treasury Manager address. /// @return Treasury Manager address. function getTreasuryManager() external view returns (address); /// @notice Sets new Treasury Manager address. Function can be executed only by the smart contract Owner. /// @param newTreasuryManager new Treasury Manager address function setTreasuryManager(address newTreasuryManager) external; /// @notice Pauses current smart contract, it can be executed only by the Owner /// @dev Emits {Paused} event from Strategy implementation. function pause() external; /// @notice Unpauses current smart contract, it can be executed only by the Owner /// @dev Emits {Unpaused} event from Strategy implementation. function unpause() external; /// @notice Emmited when Stanley address is changed by Owner. /// @param changedBy account address that has changed Stanley address /// @param oldStanley old Stanley address /// @param newStanley new Stanley address event StanleyChanged(address changedBy, address oldStanley, address newStanley); /// @notice Emmited when doClaim function had been executed. /// @param claimedBy account that executes claim action /// @param shareToken share token assocciated with one strategy /// @param treasury Treasury address where claimed tokens are transferred. /// @param amount S event DoClaim( address indexed claimedBy, address indexed shareToken, address indexed treasury, uint256 amount ); /// @notice Emmited when Treasury address has changed /// @param changedBy account address that has changed Treasury address /// @param oldTreasury old Treasury address /// @param newTreasury new Treasury address event TreasuryChanged(address changedBy, address oldTreasury, address newTreasury); /// @notice Emmited when Treasury Manager address has changed /// @param changedBy account address that changed Treasury Manager's address /// @param oldTreasuryManager old Treasury Manager address /// @param newTreasuryManager new Treasury Manager address event TreasuryManagerChanged( address changedBy, address oldTreasuryManager, address newTreasuryManager ); } // File: contracts/interfaces/IStrategyCompound.sol pragma solidity 0.8.16; /// @title Interface for interaction with Compound. /// @notice It standarises the calls made by the asset management to the external DeFi protocol. interface IStrategyCompound is IStrategy { /// @notice Emmited when blocks per year changed by Owner. /// @param changedBy account address that changed blocks per year /// @param oldBlocksPerYear old value blocks per year /// @param newBlocksPerYear new value blocks per year event BlocksPerYearChanged( address changedBy, uint256 oldBlocksPerYear, uint256 newBlocksPerYear ); } // File: contracts/libraries/math/IporMath.sol pragma solidity 0.8.16; library IporMath { //@notice Division with 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; } function divisionInt(int256 x, int256 y) internal pure returns (int256 z) { z = (x + (y / 2)) / y; } function divisionWithoutRound(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x / y; } function convertWadToAssetDecimals(uint256 value, uint256 assetDecimals) internal pure returns (uint256) { if (assetDecimals == 18) { return value; } else if (assetDecimals > 18) { return value * 10**(assetDecimals - 18); } else { return division(value, 10**(18 - assetDecimals)); } } function convertWadToAssetDecimalsWithoutRound(uint256 value, uint256 assetDecimals) internal pure returns (uint256) { if (assetDecimals == 18) { return value; } else if (assetDecimals > 18) { return value * 10**(assetDecimals - 18); } else { return divisionWithoutRound(value, 10**(18 - assetDecimals)); } } function convertToWad(uint256 value, uint256 assetDecimals) internal pure returns (uint256) { if (value > 0) { if (assetDecimals == 18) { return value; } else if (assetDecimals > 18) { return division(value, 10**(assetDecimals - 18)); } else { return value * 10**(18 - assetDecimals); } } else { return value; } } function absoluteValue(int256 value) internal pure returns (uint256) { return (uint256)(value < 0 ? -value : value); } function percentOf(uint256 value, uint256 rate) internal pure returns (uint256) { return division(value * rate, 1e18); } } // File: contracts/libraries/Constants.sol pragma solidity 0.8.16; library Constants { uint256 public constant MAX_VALUE = 115792089237316195423570985008687907853269984665640564039457584007913129639935; uint256 public constant D18 = 1e18; int256 public constant D18_INT = 1e18; uint256 public constant D36 = 1e36; uint256 public constant D54 = 1e54; uint256 public constant YEAR_IN_SECONDS = 365 days; uint256 public constant WAD_YEAR_IN_SECONDS = D18 * YEAR_IN_SECONDS; int256 public constant WAD_YEAR_IN_SECONDS_INT = int256(WAD_YEAR_IN_SECONDS); uint256 public constant WAD_P2_YEAR_IN_SECONDS = D18 * D18 * YEAR_IN_SECONDS; int256 public constant WAD_P2_YEAR_IN_SECONDS_INT = int256(WAD_P2_YEAR_IN_SECONDS); uint256 public constant MAX_CHUNK_SIZE = 50; //@notice By default every swap takes 28 days, this variable show this value in seconds uint256 public constant SWAP_DEFAULT_PERIOD_IN_SECONDS = 60 * 60 * 24 * 28; } // 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/IporOwnableUpgradeable.sol pragma solidity 0.8.16; contract IporOwnableUpgradeable is OwnableUpgradeable { address private _appointedOwner; event AppointedToTransferOwnership(address indexed appointedOwner); function transferOwnership(address appointedOwner) public override onlyOwner { require(appointedOwner != address(0), IporErrors.WRONG_ADDRESS); _appointedOwner = appointedOwner; emit AppointedToTransferOwnership(appointedOwner); } function confirmTransferOwnership() public onlyAppointedOwner { _appointedOwner = address(0); _transferOwnership(_msgSender()); } modifier onlyAppointedOwner() { require(_appointedOwner == _msgSender(), IporErrors.SENDER_NOT_APPOINTED_OWNER); _; } } // 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: contracts/vault/strategies/StrategyCore.sol pragma solidity 0.8.16; abstract contract StrategyCore is Initializable, PausableUpgradeable, ReentrancyGuardUpgradeable, UUPSUpgradeable, IporOwnableUpgradeable, IStrategy { address internal _asset; address internal _shareToken; address internal _stanley; address internal _treasury; address internal _treasuryManager; modifier onlyStanley() { require(_msgSender() == _stanley, StanleyErrors.CALLER_NOT_STANLEY); _; } modifier onlyTreasuryManager() { require(_msgSender() == _treasuryManager, StanleyErrors.CALLER_NOT_TREASURY_MANAGER); _; } function getVersion() external pure override returns (uint256) { return 2; } function getAsset() external view override returns (address) { return _asset; } /** * @dev Share token to track _asset (DAI -> cDAI) */ function getShareToken() external view override returns (address) { return _shareToken; } function getStanley() external view override returns (address) { return _stanley; } function setStanley(address newStanley) external whenNotPaused onlyOwner { require(newStanley != address(0), IporErrors.WRONG_ADDRESS); address oldStanley = _stanley; _stanley = newStanley; emit StanleyChanged(_msgSender(), oldStanley, newStanley); } function getTreasuryManager() external view override returns (address) { return _treasuryManager; } function setTreasuryManager(address manager) external whenNotPaused onlyOwner { require(manager != address(0), IporErrors.WRONG_ADDRESS); address oldTreasuryManager = _treasuryManager; _treasuryManager = manager; emit TreasuryManagerChanged(_msgSender(), oldTreasuryManager, manager); } function getTreasury() external view override returns (address) { return _treasury; } function setTreasury(address newTreasury) external whenNotPaused onlyTreasuryManager { require(newTreasury != address(0), StanleyErrors.INCORRECT_TREASURY_ADDRESS); address oldTreasury = _treasury; _treasury = newTreasury; emit TreasuryChanged(_msgSender(), oldTreasury, newTreasury); } function pause() external override onlyOwner { _pause(); } function unpause() external override onlyOwner { _unpause(); } //solhint-disable no-empty-blocks function _authorizeUpgrade(address) internal override onlyOwner {} } // File: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // 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/utils/SafeERC20Upgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20Upgradeable token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20Upgradeable token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20PermitUpgradeable token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @openzeppelin/contracts/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: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.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 IERC20Metadata is IERC20 { /** * @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: contracts/vault/strategies/StrategyCompound.sol pragma solidity 0.8.16; contract StrategyCompound is StrategyCore, IStrategyCompound { using SafeERC20Upgradeable for IERC20Upgradeable; uint256 private _blocksPerYear; ComptrollerInterface private _comptroller; IERC20Upgradeable private _compToken; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /** * @dev Deploy StrategyCompound. * @notice Deploy StrategyCompound. * @param asset underlying token like DAI, USDT etc. * @param shareToken share token like cDAI * @param comptroller _comptroller to claim comp * @param compToken comp token. */ function initialize( address asset, address shareToken, address comptroller, address compToken ) public initializer nonReentrant { __Pausable_init(); __Ownable_init(); __UUPSUpgradeable_init(); require(asset != address(0), IporErrors.WRONG_ADDRESS); require(shareToken != address(0), IporErrors.WRONG_ADDRESS); require(comptroller != address(0), IporErrors.WRONG_ADDRESS); require(compToken != address(0), IporErrors.WRONG_ADDRESS); _asset = asset; _shareToken = shareToken; _comptroller = ComptrollerInterface(comptroller); _compToken = IERC20Upgradeable(compToken); IERC20Upgradeable(_asset).safeApprove(shareToken, type(uint256).max); _blocksPerYear = 2102400; _treasuryManager = _msgSender(); } /** * @notice gets current APR in Compound Protocol. */ function getApr() external view override returns (uint256 apr) { uint256 cRate = CErc20(_shareToken).supplyRatePerBlock(); // interest % per block apr = cRate * _blocksPerYear; } /// @notice Gets Stanley Compound Strategy's asset amount in Compound Protocol. /// @dev Explanation decimals inside implementation /// In Compound exchangeRateStored is calculated in following way: /// uint exchangeRate = cashPlusBorrowsMinusReserves * expScale / _totalSupply; /// When: /// Asset decimals = 18, then exchangeRate decimals := 18 + 18 - 8 = 28 and balanceOf decimals := 28 + 8 - 18 = 18 decimals. /// Asset decimals = 6, then exchangeRate decimals := 6 + 18 - 8 = 16 and balanceOf decimals := 16 + 8 - 6 = 18 decimals. /// In both cases we have 18 decimals which is number of decimals supported in IPOR Protocol. /// @return uint256 Stanley Strategy's asset amount in Compound represented in 18 decimals function balanceOf() external view override returns (uint256) { CErc20 shareToken = CErc20(_shareToken); return ( IporMath.division( (shareToken.exchangeRateStored() * shareToken.balanceOf(address(this))), (10**IERC20Metadata(_asset).decimals()) ) ); } /** * @dev Deposit into compound lending. * @notice deposit can only done by Stanley . * @param wadAmount amount to deposit in compound lending, amount represented in 18 decimals */ function deposit(uint256 wadAmount) external override whenNotPaused onlyStanley returns (uint256 depositedAmount) { address asset = _asset; uint256 assetDecimals = IERC20Metadata(asset).decimals(); uint256 amount = IporMath.convertWadToAssetDecimals(wadAmount, assetDecimals); IERC20Upgradeable(asset).safeTransferFrom(_msgSender(), address(this), amount); CErc20(_shareToken).mint(amount); depositedAmount = IporMath.convertToWad(amount, assetDecimals); } /** * @dev withdraw from compound lending. * @notice withdraw can only done by Stanley. * @param wadAmount candidate amount to withdraw from compound lending, amount represented in 18 decimals */ function withdraw(uint256 wadAmount) external override whenNotPaused onlyStanley returns (uint256 withdrawnAmount) { address asset = _asset; uint256 assetDecimals = IERC20Metadata(asset).decimals(); uint256 amount = IporMath.convertWadToAssetDecimalsWithoutRound(wadAmount, assetDecimals); CErc20 shareToken = CErc20(_shareToken); // Transfer assets from Compound to Strategy uint256 redeemStatus = shareToken.redeem( IporMath.division(amount * Constants.D18, shareToken.exchangeRateStored()) ); require(redeemStatus == 0, StanleyErrors.SHARED_TOKEN_REDEEM_ERROR); uint256 withdrawnAmountCompound = IERC20Upgradeable(asset).balanceOf(address(this)); // Transfer all assets from Strategy to Stanley IERC20Upgradeable(asset).safeTransfer(_msgSender(), withdrawnAmountCompound); withdrawnAmount = IporMath.convertToWad(withdrawnAmountCompound, assetDecimals); } /** * @dev Claim extra reward of Governace token(COMP). */ function doClaim() external override whenNotPaused nonReentrant onlyOwner { address treasury = _treasury; IERC20Upgradeable compToken = _compToken; require(treasury != address(0), IporErrors.WRONG_ADDRESS); address[] memory assets = new address[](1); assets[0] = _shareToken; _comptroller.claimComp(address(this), assets); uint256 balance = compToken.balanceOf(address(this)); compToken.safeTransfer(treasury, balance); emit DoClaim(_msgSender(), assets[0], treasury, balance); } function setBlocksPerYear(uint256 newBlocksPerYear) external whenNotPaused onlyOwner { require(newBlocksPerYear > 0, IporErrors.VALUE_NOT_GREATER_THAN_ZERO); uint256 oldBlocksPerYear = _blocksPerYear; _blocksPerYear = newBlocksPerYear; emit BlocksPerYearChanged(_msgSender(), oldBlocksPerYear, newBlocksPerYear); } } contract StrategyCompoundUsdt is StrategyCompound {} contract StrategyCompoundUsdc is StrategyCompound {} contract StrategyCompoundDai is StrategyCompound {}
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":false,"internalType":"address","name":"changedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldBlocksPerYear","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBlocksPerYear","type":"uint256"}],"name":"BlocksPerYearChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimedBy","type":"address"},{"indexed":true,"internalType":"address","name":"shareToken","type":"address"},{"indexed":true,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DoClaim","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":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"changedBy","type":"address"},{"indexed":false,"internalType":"address","name":"oldStanley","type":"address"},{"indexed":false,"internalType":"address","name":"newStanley","type":"address"}],"name":"StanleyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"changedBy","type":"address"},{"indexed":false,"internalType":"address","name":"oldTreasury","type":"address"},{"indexed":false,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"changedBy","type":"address"},{"indexed":false,"internalType":"address","name":"oldTreasuryManager","type":"address"},{"indexed":false,"internalType":"address","name":"newTreasuryManager","type":"address"}],"name":"TreasuryManagerChanged","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":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"confirmTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wadAmount","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"depositedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"doClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getApr","outputs":[{"internalType":"uint256","name":"apr","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAsset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getShareToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStanley","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"shareToken","type":"address"},{"internalType":"address","name":"comptroller","type":"address"},{"internalType":"address","name":"compToken","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","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":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newBlocksPerYear","type":"uint256"}],"name":"setBlocksPerYear","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newStanley","type":"address"}],"name":"setStanley","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"manager","type":"address"}],"name":"setTreasuryManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"appointedOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","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"},{"inputs":[{"internalType":"uint256","name":"wadAmount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"withdrawnAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051612a9e62000120600039600081816109e301528181610a6801528181610c3f01528181610cc40152610dae0152612a9e6000f3fe6080604052600436106101a15760003560e01c8063722713f7116100e1578063cc29516a1161008a578063f0f4426011610064578063f0f4426014610416578063f2fde38b14610436578063f8c8765e14610456578063fe47a9f21461047657600080fd5b8063cc29516a146103c2578063e4c56260146103d7578063e5fa2b70146103f657600080fd5b80638da5cb5b116100bb5780638da5cb5b146103655780639c4e89f414610383578063b6b55f25146103a257600080fd5b8063722713f7146103265780638456cb591461033b578063845bc8041461035057600080fd5b80633f4ba83a1161014e57806352d1902d1161012857806352d1902d146102ba5780635c222bad146102cf5780635c975abb146102ee578063715018a61461031157600080fd5b80633f4ba83a14610272578063407c359d146102875780634f1ef286146102a757600080fd5b80632e1a7d4d1161017f5780632e1a7d4d146102135780633659cfe6146102335780633b19e84a1461025357600080fd5b80630d8e6e2c146101a6578063209e84ee146101c95780632bdb0d92146101e0575b600080fd5b3480156101b257600080fd5b5060025b6040519081526020015b60405180910390f35b3480156101d557600080fd5b506101de610496565b005b3480156101ec57600080fd5b5061012f546001600160a01b03165b6040516001600160a01b0390911681526020016101c0565b34801561021f57600080fd5b506101b661022e366004612607565b61070f565b34801561023f57600080fd5b506101de61024e36600461263c565b6109d9565b34801561025f57600080fd5b50610131546001600160a01b03166101fb565b34801561027e57600080fd5b506101de610b54565b34801561029357600080fd5b506101de6102a236600461263c565b610b66565b6101de6102b536600461266d565b610c35565b3480156102c657600080fd5b506101b6610da1565b3480156102db57600080fd5b5061012e546001600160a01b03166101fb565b3480156102fa57600080fd5b5060335460ff1660405190151581526020016101c0565b34801561031d57600080fd5b506101de610e66565b34801561033257600080fd5b506101b6610e78565b34801561034757600080fd5b506101de610fe1565b34801561035c57600080fd5b506101b6610ff1565b34801561037157600080fd5b5060fb546001600160a01b03166101fb565b34801561038f57600080fd5b50610132546001600160a01b03166101fb565b3480156103ae57600080fd5b506101b66103bd366004612607565b61107d565b3480156103ce57600080fd5b506101de6111ff565b3480156103e357600080fd5b50610130546001600160a01b03166101fb565b34801561040257600080fd5b506101de610411366004612607565b61127b565b34801561042257600080fd5b506101de61043136600461263c565b611325565b34801561044257600080fd5b506101de61045136600461263c565b61143e565b34801561046257600080fd5b506101de61047136600461272f565b6114d8565b34801561048257600080fd5b506101de61049136600461263c565b6117f8565b61049e611897565b6002606554036104f55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026065556105026118ea565b6101315461013554604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b039283169290911690826105575760405162461bcd60e51b81526004016104ec91906127a7565b5060408051600180825281830190925260009160208083019080368337505061012f5482519293506001600160a01b03169183915060009061059b5761059b6127da565b6001600160a01b0392831660209182029290920101526101345460405162e1ed9760e51b8152911690631c3db2e0906105da90309085906004016127f0565b600060405180830381600087803b1580156105f457600080fd5b505af1158015610608573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03851691506370a0823190602401602060405180830381865afa158015610653573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610677919061284b565b905061068d6001600160a01b0384168583611944565b836001600160a01b0316826000815181106106aa576106aa6127da565b60200260200101516001600160a01b03166106c23390565b6001600160a01b03167fd6e7c12127e6e6ff4ddf62f42bcc614dcaabdff3322b838b26aeb662404fbb77846040516106fc91815260200190565b60405180910390a4505060016065555050565b6000610719611897565b610130546001600160a01b0316336001600160a01b0316146040518060400160405280600881526020016749504f525f35303160c01b815250906107705760405162461bcd60e51b81526004016104ec91906127a7565b5061012e546040805163313ce56760e01b815290516001600160a01b0390921691600091839163313ce567916004808201926020929091908290030181865afa1580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e59190612864565b60ff16905060006107f685836119d9565b61012f549091506001600160a01b031660008163db006a7561088a610823670de0b6b3a76400008761289d565b856001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610885919061284b565b611a3f565b6040518263ffffffff1660e01b81526004016108a891815260200190565b6020604051808303816000875af11580156108c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108eb919061284b565b60408051808201909152600881527f49504f525f353036000000000000000000000000000000000000000000000000602082015290915081156109415760405162461bcd60e51b81526004016104ec91906127a7565b506040516370a0823160e01b81523060048201526000906001600160a01b038716906370a0823190602401602060405180830381865afa158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad919061284b565b90506109c36001600160a01b0387163383611944565b6109cd8186611a68565b98975050505050505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610a665760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b60648201526084016104ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610ac17f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610b2c5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b60648201526084016104ec565b610b3581611ab4565b60408051600080825260208201909252610b5191839190611abc565b50565b610b5c6118ea565b610b64611c5c565b565b610b6e611897565b610b766118ea565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b038216610bbc5760405162461bcd60e51b81526004016104ec91906127a7565b5061013080546001600160a01b038381166001600160a01b0319831617909255167f1219962e3ba0a26ae37520e06b4c5702e1060aba93ef6af115033985c6ae1c01610c053390565b604080516001600160a01b0392831681528285166020820152918516908201526060015b60405180910390a15050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610cc25760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b60648201526084016104ec565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610d1d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610d885760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b60648201526084016104ec565b610d9182611ab4565b610d9d82826001611abc565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e415760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016104ec565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b610e6e6118ea565b610b646000611cae565b61012f546040516370a0823160e01b81523060048201526000916001600160a01b031690610fdb9082906370a0823190602401602060405180830381865afa158015610ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eec919061284b565b826001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4e919061284b565b610f58919061289d565b61012e60009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd09190612864565b61088590600a6129a0565b91505090565b610fe96118ea565b610b64611d00565b60008061012f60009054906101000a90046001600160a01b03166001600160a01b031663ae9d70b06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c919061284b565b90506101335481610fdb919061289d565b6000611087611897565b610130546001600160a01b0316336001600160a01b0316146040518060400160405280600881526020016749504f525f35303160c01b815250906110de5760405162461bcd60e51b81526004016104ec91906127a7565b5061012e546040805163313ce56760e01b815290516001600160a01b0390921691600091839163313ce567916004808201926020929091908290030181865afa15801561112f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111539190612864565b60ff16905060006111648583611d3d565b905061117b6001600160a01b038416333084611d71565b61012f5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d68906024016020604051808303816000875af11580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb919061284b565b506111f68183611a68565b95945050505050565b61012d5460408051808201909152600881527f49504f525f3030370000000000000000000000000000000000000000000000006020820152906001600160a01b031633146112605760405162461bcd60e51b81526004016104ec91906127a7565b5061012d80546001600160a01b0319169055610b6433611cae565b611283611897565b61128b6118ea565b60408051808201909152600881527f49504f525f3030340000000000000000000000000000000000000000000000006020820152816112dd5760405162461bcd60e51b81526004016104ec91906127a7565b5061013380549082905560408051338152602081018390529081018390527ff69c6fc4919ea997508cd130ba11bf16f4a188ce7000f7b19c27e630a0a3bd8b90606001610c29565b61132d611897565b610132546001600160a01b0316336001600160a01b0316146040518060400160405280600881526020017f49504f525f353035000000000000000000000000000000000000000000000000815250906113995760405162461bcd60e51b81526004016104ec91906127a7565b5060408051808201909152600881527f49504f525f35303200000000000000000000000000000000000000000000000060208201526001600160a01b0382166113f55760405162461bcd60e51b81526004016104ec91906127a7565b5061013180546001600160a01b038381166001600160a01b0319831617909255167f749a8050935feb73a55ab4641c867c4dacc84430990fcaada1d12ba9072ad02e610c053390565b6114466118ea565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b03821661148c5760405162461bcd60e51b81526004016104ec91906127a7565b5061012d80546001600160a01b0319166001600160a01b0383169081179091556040517f3ec7bb1d452f3c36260fa8ef678a597fd97574d8ec42f6dc98ffce3dbc91228f90600090a250565b600054610100900460ff16158080156114f85750600054600160ff909116105b806115125750303b158015611512575060005460ff166001145b6115845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104ec565b6000805460ff1916600117905580156115a7576000805461ff0019166101001790555b6002606554036115f95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104ec565b6002606555611606611daf565b61160e611e22565b611616611e95565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b03861661165c5760405162461bcd60e51b81526004016104ec91906127a7565b50604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b0385166116a35760405162461bcd60e51b81526004016104ec91906127a7565b50604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b0384166116ea5760405162461bcd60e51b81526004016104ec91906127a7565b50604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b0383166117315760405162461bcd60e51b81526004016104ec91906127a7565b5061012e80546001600160a01b038088166001600160a01b0319928316811790935561012f8054888316908416179055610134805487831690841617905561013580549186169190921617905561178b9085600019611f00565b622014806101335561013280546001600160a01b03191633179055600160655580156117f1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b611800611897565b6118086118ea565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b03821661184e5760405162461bcd60e51b81526004016104ec91906127a7565b5061013280546001600160a01b038381166001600160a01b0319831617909255167f0c019cd887119337acf3a77622903f875f0526de48372228e820f01f9345fdf5610c053390565b60335460ff1615610b645760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016104ec565b60fb546001600160a01b03163314610b645760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b6040516001600160a01b0383166024820152604481018290526119d490849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261201c565b505050565b6000816012036119ea575081611a39565b6012821115611a1a576119fe6012836129af565b611a0990600a6129c2565b611a13908461289d565b9050611a39565b611a1383611a298460126129af565b611a3490600a6129c2565b612101565b92915050565b600081611a4d6002826129ce565b611a5790856129f0565b611a6191906129ce565b9392505050565b60008215611aad5781601203611a7f575081611a39565b6012821115611aa257611a1383611a976012856129af565b61088590600a6129c2565b6119fe8260126129af565b5081611a39565b610b516118ea565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611aef576119d48361210d565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611b49575060408051601f3d908101601f19168201909252611b469181019061284b565b60015b611bbb5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f74205555505300000000000000000000000000000000000060648201526084016104ec565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611c505760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c6555554944000000000000000000000000000000000000000000000060648201526084016104ec565b506119d48383836121cb565b611c646121f0565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60fb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611d08611897565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611c913390565b600081601203611d4e575081611a39565b6012821115611d62576119fe6012836129af565b611a1383611a978460126129af565b6040516001600160a01b0380851660248301528316604482015260648101829052611da99085906323b872dd60e01b90608401611970565b50505050565b600054610100900460ff16611e1a5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b610b64612242565b600054610100900460ff16611e8d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b610b646122b9565b600054610100900460ff16610b645760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b801580611f7a5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f78919061284b565b155b611fec5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016104ec565b6040516001600160a01b0383166024820152604481018290526119d490849063095ea7b360e01b90606401611970565b6000612071826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661232d9092919063ffffffff16565b8051909150156119d4578080602001905181019061208f9190612a03565b6119d45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104ec565b6000611a6182846129ce565b6001600160a01b0381163b61218a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016104ec565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6121d483612344565b6000825111806121e15750805b156119d457611da98383612384565b60335460ff16610b645760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016104ec565b600054610100900460ff166122ad5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b6033805460ff19169055565b600054610100900460ff166123245760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b610b6433611cae565b606061233c8484600085612486565b949350505050565b61234d8161210d565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6124035760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016104ec565b600080846001600160a01b03168460405161241e9190612a25565b600060405180830381855af49150503d8060008114612459576040519150601f19603f3d011682016040523d82523d6000602084013e61245e565b606091505b50915091506111f68282604051806060016040528060278152602001612a42602791396125ce565b6060824710156124fe5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104ec565b6001600160a01b0385163b6125555760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104ec565b600080866001600160a01b031685876040516125719190612a25565b60006040518083038185875af1925050503d80600081146125ae576040519150601f19603f3d011682016040523d82523d6000602084013e6125b3565b606091505b50915091506125c38282866125ce565b979650505050505050565b606083156125dd575081611a61565b8251156125ed5782518084602001fd5b8160405162461bcd60e51b81526004016104ec91906127a7565b60006020828403121561261957600080fd5b5035919050565b80356001600160a01b038116811461263757600080fd5b919050565b60006020828403121561264e57600080fd5b611a6182612620565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561268057600080fd5b61268983612620565b9150602083013567ffffffffffffffff808211156126a657600080fd5b818501915085601f8301126126ba57600080fd5b8135818111156126cc576126cc612657565b604051601f8201601f19908116603f011681019083821181831017156126f4576126f4612657565b8160405282815288602084870101111561270d57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000806000806080858703121561274557600080fd5b61274e85612620565b935061275c60208601612620565b925061276a60408601612620565b915061277860608601612620565b905092959194509250565b60005b8381101561279e578181015183820152602001612786565b50506000910152565b60208152600082518060208401526127c6816040850160208701612783565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b6000604082016001600160a01b0380861684526020604081860152828651808552606087019150828801945060005b8181101561283d57855185168352948301949183019160010161281f565b509098975050505050505050565b60006020828403121561285d57600080fd5b5051919050565b60006020828403121561287657600080fd5b815160ff81168114611a6157600080fd5b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156128b7576128b7612887565b500290565b600181815b808511156128f75781600019048211156128dd576128dd612887565b808516156128ea57918102915b93841c93908002906128c1565b509250929050565b60008261290e57506001611a39565b8161291b57506000611a39565b8160018114612931576002811461293b57612957565b6001915050611a39565b60ff84111561294c5761294c612887565b50506001821b611a39565b5060208310610133831016604e8410600b841016171561297a575081810a611a39565b61298483836128bc565b806000190482111561299857612998612887565b029392505050565b6000611a6160ff8416836128ff565b81810381811115611a3957611a39612887565b6000611a6183836128ff565b6000826129eb57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115611a3957611a39612887565b600060208284031215612a1557600080fd5b81518015158114611a6157600080fd5b60008251612a37818460208701612783565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122018f23da5dd2544f4d5b528b2112b82c4482dfe9fa3b7bf731903ed75bc873cfe64736f6c63430008100033
Deployed Bytecode
0x6080604052600436106101a15760003560e01c8063722713f7116100e1578063cc29516a1161008a578063f0f4426011610064578063f0f4426014610416578063f2fde38b14610436578063f8c8765e14610456578063fe47a9f21461047657600080fd5b8063cc29516a146103c2578063e4c56260146103d7578063e5fa2b70146103f657600080fd5b80638da5cb5b116100bb5780638da5cb5b146103655780639c4e89f414610383578063b6b55f25146103a257600080fd5b8063722713f7146103265780638456cb591461033b578063845bc8041461035057600080fd5b80633f4ba83a1161014e57806352d1902d1161012857806352d1902d146102ba5780635c222bad146102cf5780635c975abb146102ee578063715018a61461031157600080fd5b80633f4ba83a14610272578063407c359d146102875780634f1ef286146102a757600080fd5b80632e1a7d4d1161017f5780632e1a7d4d146102135780633659cfe6146102335780633b19e84a1461025357600080fd5b80630d8e6e2c146101a6578063209e84ee146101c95780632bdb0d92146101e0575b600080fd5b3480156101b257600080fd5b5060025b6040519081526020015b60405180910390f35b3480156101d557600080fd5b506101de610496565b005b3480156101ec57600080fd5b5061012f546001600160a01b03165b6040516001600160a01b0390911681526020016101c0565b34801561021f57600080fd5b506101b661022e366004612607565b61070f565b34801561023f57600080fd5b506101de61024e36600461263c565b6109d9565b34801561025f57600080fd5b50610131546001600160a01b03166101fb565b34801561027e57600080fd5b506101de610b54565b34801561029357600080fd5b506101de6102a236600461263c565b610b66565b6101de6102b536600461266d565b610c35565b3480156102c657600080fd5b506101b6610da1565b3480156102db57600080fd5b5061012e546001600160a01b03166101fb565b3480156102fa57600080fd5b5060335460ff1660405190151581526020016101c0565b34801561031d57600080fd5b506101de610e66565b34801561033257600080fd5b506101b6610e78565b34801561034757600080fd5b506101de610fe1565b34801561035c57600080fd5b506101b6610ff1565b34801561037157600080fd5b5060fb546001600160a01b03166101fb565b34801561038f57600080fd5b50610132546001600160a01b03166101fb565b3480156103ae57600080fd5b506101b66103bd366004612607565b61107d565b3480156103ce57600080fd5b506101de6111ff565b3480156103e357600080fd5b50610130546001600160a01b03166101fb565b34801561040257600080fd5b506101de610411366004612607565b61127b565b34801561042257600080fd5b506101de61043136600461263c565b611325565b34801561044257600080fd5b506101de61045136600461263c565b61143e565b34801561046257600080fd5b506101de61047136600461272f565b6114d8565b34801561048257600080fd5b506101de61049136600461263c565b6117f8565b61049e611897565b6002606554036104f55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026065556105026118ea565b6101315461013554604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b039283169290911690826105575760405162461bcd60e51b81526004016104ec91906127a7565b5060408051600180825281830190925260009160208083019080368337505061012f5482519293506001600160a01b03169183915060009061059b5761059b6127da565b6001600160a01b0392831660209182029290920101526101345460405162e1ed9760e51b8152911690631c3db2e0906105da90309085906004016127f0565b600060405180830381600087803b1580156105f457600080fd5b505af1158015610608573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03851691506370a0823190602401602060405180830381865afa158015610653573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610677919061284b565b905061068d6001600160a01b0384168583611944565b836001600160a01b0316826000815181106106aa576106aa6127da565b60200260200101516001600160a01b03166106c23390565b6001600160a01b03167fd6e7c12127e6e6ff4ddf62f42bcc614dcaabdff3322b838b26aeb662404fbb77846040516106fc91815260200190565b60405180910390a4505060016065555050565b6000610719611897565b610130546001600160a01b0316336001600160a01b0316146040518060400160405280600881526020016749504f525f35303160c01b815250906107705760405162461bcd60e51b81526004016104ec91906127a7565b5061012e546040805163313ce56760e01b815290516001600160a01b0390921691600091839163313ce567916004808201926020929091908290030181865afa1580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e59190612864565b60ff16905060006107f685836119d9565b61012f549091506001600160a01b031660008163db006a7561088a610823670de0b6b3a76400008761289d565b856001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610885919061284b565b611a3f565b6040518263ffffffff1660e01b81526004016108a891815260200190565b6020604051808303816000875af11580156108c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108eb919061284b565b60408051808201909152600881527f49504f525f353036000000000000000000000000000000000000000000000000602082015290915081156109415760405162461bcd60e51b81526004016104ec91906127a7565b506040516370a0823160e01b81523060048201526000906001600160a01b038716906370a0823190602401602060405180830381865afa158015610989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ad919061284b565b90506109c36001600160a01b0387163383611944565b6109cd8186611a68565b98975050505050505050565b6001600160a01b037f000000000000000000000000708c35d27e2637c7b5b87d2a423e626eb99c11a9163003610a665760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b60648201526084016104ec565b7f000000000000000000000000708c35d27e2637c7b5b87d2a423e626eb99c11a96001600160a01b0316610ac17f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610b2c5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b60648201526084016104ec565b610b3581611ab4565b60408051600080825260208201909252610b5191839190611abc565b50565b610b5c6118ea565b610b64611c5c565b565b610b6e611897565b610b766118ea565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b038216610bbc5760405162461bcd60e51b81526004016104ec91906127a7565b5061013080546001600160a01b038381166001600160a01b0319831617909255167f1219962e3ba0a26ae37520e06b4c5702e1060aba93ef6af115033985c6ae1c01610c053390565b604080516001600160a01b0392831681528285166020820152918516908201526060015b60405180910390a15050565b6001600160a01b037f000000000000000000000000708c35d27e2637c7b5b87d2a423e626eb99c11a9163003610cc25760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b60648201526084016104ec565b7f000000000000000000000000708c35d27e2637c7b5b87d2a423e626eb99c11a96001600160a01b0316610d1d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610d885760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b60648201526084016104ec565b610d9182611ab4565b610d9d82826001611abc565b5050565b6000306001600160a01b037f000000000000000000000000708c35d27e2637c7b5b87d2a423e626eb99c11a91614610e415760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016104ec565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b610e6e6118ea565b610b646000611cae565b61012f546040516370a0823160e01b81523060048201526000916001600160a01b031690610fdb9082906370a0823190602401602060405180830381865afa158015610ec8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eec919061284b565b826001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4e919061284b565b610f58919061289d565b61012e60009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd09190612864565b61088590600a6129a0565b91505090565b610fe96118ea565b610b64611d00565b60008061012f60009054906101000a90046001600160a01b03166001600160a01b031663ae9d70b06040518163ffffffff1660e01b8152600401602060405180830381865afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c919061284b565b90506101335481610fdb919061289d565b6000611087611897565b610130546001600160a01b0316336001600160a01b0316146040518060400160405280600881526020016749504f525f35303160c01b815250906110de5760405162461bcd60e51b81526004016104ec91906127a7565b5061012e546040805163313ce56760e01b815290516001600160a01b0390921691600091839163313ce567916004808201926020929091908290030181865afa15801561112f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111539190612864565b60ff16905060006111648583611d3d565b905061117b6001600160a01b038416333084611d71565b61012f5460405163140e25ad60e31b8152600481018390526001600160a01b039091169063a0712d68906024016020604051808303816000875af11580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb919061284b565b506111f68183611a68565b95945050505050565b61012d5460408051808201909152600881527f49504f525f3030370000000000000000000000000000000000000000000000006020820152906001600160a01b031633146112605760405162461bcd60e51b81526004016104ec91906127a7565b5061012d80546001600160a01b0319169055610b6433611cae565b611283611897565b61128b6118ea565b60408051808201909152600881527f49504f525f3030340000000000000000000000000000000000000000000000006020820152816112dd5760405162461bcd60e51b81526004016104ec91906127a7565b5061013380549082905560408051338152602081018390529081018390527ff69c6fc4919ea997508cd130ba11bf16f4a188ce7000f7b19c27e630a0a3bd8b90606001610c29565b61132d611897565b610132546001600160a01b0316336001600160a01b0316146040518060400160405280600881526020017f49504f525f353035000000000000000000000000000000000000000000000000815250906113995760405162461bcd60e51b81526004016104ec91906127a7565b5060408051808201909152600881527f49504f525f35303200000000000000000000000000000000000000000000000060208201526001600160a01b0382166113f55760405162461bcd60e51b81526004016104ec91906127a7565b5061013180546001600160a01b038381166001600160a01b0319831617909255167f749a8050935feb73a55ab4641c867c4dacc84430990fcaada1d12ba9072ad02e610c053390565b6114466118ea565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b03821661148c5760405162461bcd60e51b81526004016104ec91906127a7565b5061012d80546001600160a01b0319166001600160a01b0383169081179091556040517f3ec7bb1d452f3c36260fa8ef678a597fd97574d8ec42f6dc98ffce3dbc91228f90600090a250565b600054610100900460ff16158080156114f85750600054600160ff909116105b806115125750303b158015611512575060005460ff166001145b6115845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104ec565b6000805460ff1916600117905580156115a7576000805461ff0019166101001790555b6002606554036115f95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104ec565b6002606555611606611daf565b61160e611e22565b611616611e95565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b03861661165c5760405162461bcd60e51b81526004016104ec91906127a7565b50604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b0385166116a35760405162461bcd60e51b81526004016104ec91906127a7565b50604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b0384166116ea5760405162461bcd60e51b81526004016104ec91906127a7565b50604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b0383166117315760405162461bcd60e51b81526004016104ec91906127a7565b5061012e80546001600160a01b038088166001600160a01b0319928316811790935561012f8054888316908416179055610134805487831690841617905561013580549186169190921617905561178b9085600019611f00565b622014806101335561013280546001600160a01b03191633179055600160655580156117f1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b611800611897565b6118086118ea565b604080518082019091526008815267049504f525f3030360c41b60208201526001600160a01b03821661184e5760405162461bcd60e51b81526004016104ec91906127a7565b5061013280546001600160a01b038381166001600160a01b0319831617909255167f0c019cd887119337acf3a77622903f875f0526de48372228e820f01f9345fdf5610c053390565b60335460ff1615610b645760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016104ec565b60fb546001600160a01b03163314610b645760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b6040516001600160a01b0383166024820152604481018290526119d490849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261201c565b505050565b6000816012036119ea575081611a39565b6012821115611a1a576119fe6012836129af565b611a0990600a6129c2565b611a13908461289d565b9050611a39565b611a1383611a298460126129af565b611a3490600a6129c2565b612101565b92915050565b600081611a4d6002826129ce565b611a5790856129f0565b611a6191906129ce565b9392505050565b60008215611aad5781601203611a7f575081611a39565b6012821115611aa257611a1383611a976012856129af565b61088590600a6129c2565b6119fe8260126129af565b5081611a39565b610b516118ea565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611aef576119d48361210d565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611b49575060408051601f3d908101601f19168201909252611b469181019061284b565b60015b611bbb5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f74205555505300000000000000000000000000000000000060648201526084016104ec565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611c505760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c6555554944000000000000000000000000000000000000000000000060648201526084016104ec565b506119d48383836121cb565b611c646121f0565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60fb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611d08611897565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611c913390565b600081601203611d4e575081611a39565b6012821115611d62576119fe6012836129af565b611a1383611a978460126129af565b6040516001600160a01b0380851660248301528316604482015260648101829052611da99085906323b872dd60e01b90608401611970565b50505050565b600054610100900460ff16611e1a5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b610b64612242565b600054610100900460ff16611e8d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b610b646122b9565b600054610100900460ff16610b645760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b801580611f7a5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f78919061284b565b155b611fec5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016104ec565b6040516001600160a01b0383166024820152604481018290526119d490849063095ea7b360e01b90606401611970565b6000612071826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661232d9092919063ffffffff16565b8051909150156119d4578080602001905181019061208f9190612a03565b6119d45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016104ec565b6000611a6182846129ce565b6001600160a01b0381163b61218a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016104ec565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6121d483612344565b6000825111806121e15750805b156119d457611da98383612384565b60335460ff16610b645760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016104ec565b600054610100900460ff166122ad5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b6033805460ff19169055565b600054610100900460ff166123245760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016104ec565b610b6433611cae565b606061233c8484600085612486565b949350505050565b61234d8161210d565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6124035760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016104ec565b600080846001600160a01b03168460405161241e9190612a25565b600060405180830381855af49150503d8060008114612459576040519150601f19603f3d011682016040523d82523d6000602084013e61245e565b606091505b50915091506111f68282604051806060016040528060278152602001612a42602791396125ce565b6060824710156124fe5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016104ec565b6001600160a01b0385163b6125555760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104ec565b600080866001600160a01b031685876040516125719190612a25565b60006040518083038185875af1925050503d80600081146125ae576040519150601f19603f3d011682016040523d82523d6000602084013e6125b3565b606091505b50915091506125c38282866125ce565b979650505050505050565b606083156125dd575081611a61565b8251156125ed5782518084602001fd5b8160405162461bcd60e51b81526004016104ec91906127a7565b60006020828403121561261957600080fd5b5035919050565b80356001600160a01b038116811461263757600080fd5b919050565b60006020828403121561264e57600080fd5b611a6182612620565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561268057600080fd5b61268983612620565b9150602083013567ffffffffffffffff808211156126a657600080fd5b818501915085601f8301126126ba57600080fd5b8135818111156126cc576126cc612657565b604051601f8201601f19908116603f011681019083821181831017156126f4576126f4612657565b8160405282815288602084870101111561270d57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000806000806080858703121561274557600080fd5b61274e85612620565b935061275c60208601612620565b925061276a60408601612620565b915061277860608601612620565b905092959194509250565b60005b8381101561279e578181015183820152602001612786565b50506000910152565b60208152600082518060208401526127c6816040850160208701612783565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b6000604082016001600160a01b0380861684526020604081860152828651808552606087019150828801945060005b8181101561283d57855185168352948301949183019160010161281f565b509098975050505050505050565b60006020828403121561285d57600080fd5b5051919050565b60006020828403121561287657600080fd5b815160ff81168114611a6157600080fd5b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156128b7576128b7612887565b500290565b600181815b808511156128f75781600019048211156128dd576128dd612887565b808516156128ea57918102915b93841c93908002906128c1565b509250929050565b60008261290e57506001611a39565b8161291b57506000611a39565b8160018114612931576002811461293b57612957565b6001915050611a39565b60ff84111561294c5761294c612887565b50506001821b611a39565b5060208310610133831016604e8410600b841016171561297a575081810a611a39565b61298483836128bc565b806000190482111561299857612998612887565b029392505050565b6000611a6160ff8416836128ff565b81810381811115611a3957611a39612887565b6000611a6183836128ff565b6000826129eb57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115611a3957611a39612887565b600060208284031215612a1557600080fd5b81518015158114611a6157600080fd5b60008251612a37818460208701612783565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122018f23da5dd2544f4d5b528b2112b82c4482dfe9fa3b7bf731903ed75bc873cfe64736f6c63430008100033
Deployed Bytecode Sourcemap
70895:6032:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55275:90;;;;;;;;;;-1:-1:-1;55356:1:0;55275:90;;;160:25:1;;;148:2;133:18;55275:90:0;;;;;;;;75984:577;;;;;;;;;;;;;:::i;:::-;;55547:103;;;;;;;;;;-1:-1:-1;55631:11:0;;-1:-1:-1;;;;;55631:11:0;55547:103;;;-1:-1:-1;;;;;360:55:1;;;342:74;;330:2;315:18;55547:103:0;196:226:1;74854:1046:0;;;;;;;;;;-1:-1:-1;74854:1046:0;;;;;:::i;:::-;;:::i;41149:200::-;;;;;;;;;;-1:-1:-1;41149:200:0;;;;;:::i;:::-;;:::i;56518:99::-;;;;;;;;;;-1:-1:-1;56600:9:0;;-1:-1:-1;;;;;56600:9:0;56518:99;;57040:76;;;;;;;;;;;;;:::i;55763:291::-;;;;;;;;;;-1:-1:-1;55763:291:0;;;;;:::i;:::-;;:::i;41608:225::-;;;;;;:::i;:::-;;:::i;40827:133::-;;;;;;;;;;;;;:::i;55373:93::-;;;;;;;;;;-1:-1:-1;55452:6:0;;-1:-1:-1;;;;;55452:6:0;55373:93;;53252:86;;;;;;;;;;-1:-1:-1;53323:7:0;;;;53252:86;;2483:14:1;;2476:22;2458:41;;2446:2;2431:18;53252:86:0;2318:187:1;49402:103:0;;;;;;;;;;;;;:::i;73491:346::-;;;;;;;;;;;;;:::i;56960:72::-;;;;;;;;;;;;;:::i;72516:201::-;;;;;;;;;;;;;:::i;48754:87::-;;;;;;;;;;-1:-1:-1;48827:6:0;;-1:-1:-1;;;;;48827:6:0;48754:87;;56062:113;;;;;;;;;;-1:-1:-1;56151:16:0;;-1:-1:-1;;;;;56151:16:0;56062:113;;74056:565;;;;;;;;;;-1:-1:-1;74056:565:0;;;;;:::i;:::-;;:::i;51054:152::-;;;;;;;;;;;;;:::i;55658:97::-;;;;;;;;;;-1:-1:-1;55739:8:0;;-1:-1:-1;;;;;55739:8:0;55658:97;;76569:355;;;;;;;;;;-1:-1:-1;76569:355:0;;;;;:::i;:::-;;:::i;56625:327::-;;;;;;;;;;-1:-1:-1;56625:327:0;;;;;:::i;:::-;;:::i;50784:262::-;;;;;;;;;;-1:-1:-1;50784:262:0;;;;;:::i;:::-;;:::i;71561:874::-;;;;;;;;;;-1:-1:-1;71561:874:0;;;;;:::i;:::-;;:::i;56183:327::-;;;;;;;;;;-1:-1:-1;56183:327:0;;;;;:::i;:::-;;:::i;75984:577::-;52857:19;:17;:19::i;:::-;44494:1:::1;45269:7;;:19:::0;45261:63:::1;;;::::0;-1:-1:-1;;;45261:63:0;;3126:2:1;45261:63:0::1;::::0;::::1;3108:21:1::0;3165:2;3145:18;;;3138:30;3204:33;3184:18;;;3177:61;3255:18;;45261:63:0::1;;;;;;;;;44494:1;45402:7;:18:::0;48640:13:::2;:11;:13::i;:::-;76088:9:::3;::::0;76138:10:::3;::::0;76193:24:::3;::::0;;;;::::3;::::0;;;::::3;::::0;;-1:-1:-1;;;76193:24:0::3;::::0;::::3;::::0;-1:-1:-1;;;;;76088:9:0;;::::3;::::0;76138:10;;::::3;::::0;76088:9;76161:57:::3;;;;-1:-1:-1::0;;;76161:57:0::3;;;;;;;;:::i;:::-;-1:-1:-1::0;76257:16:0::3;::::0;;76271:1:::3;76257:16:::0;;;;;::::3;::::0;;;76231:23:::3;::::0;76257:16:::3;::::0;;::::3;::::0;;::::3;::::0;::::3;-1:-1:-1::0;;76296:11:0::3;::::0;76284:9;;;;-1:-1:-1;;;;;;76296:11:0::3;::::0;76284:9;;-1:-1:-1;76296:11:0::3;::::0;76284:9:::3;;;;:::i;:::-;-1:-1:-1::0;;;;;76284:23:0;;::::3;:9;::::0;;::::3;::::0;;;;;:23;76320:12:::3;::::0;:45:::3;::::0;-1:-1:-1;;;76320:45:0;;:12;::::3;::::0;:22:::3;::::0;:45:::3;::::0;76351:4:::3;::::0;76358:6;;76320:45:::3;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;-1:-1:-1::0;;76396:34:0::3;::::0;-1:-1:-1;;;76396:34:0;;76424:4:::3;76396:34;::::0;::::3;342:74:1::0;76378:15:0::3;::::0;-1:-1:-1;;;;;;76396:19:0;::::3;::::0;-1:-1:-1;76396:19:0::3;::::0;315:18:1;;76396:34:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76378:52:::0;-1:-1:-1;76443:41:0::3;-1:-1:-1::0;;;;;76443:22:0;::::3;76466:8:::0;76378:52;76443:22:::3;:41::i;:::-;76535:8;-1:-1:-1::0;;;;;76502:51:0::3;76524:6;76531:1;76524:9;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;76502:51:0::3;76510:12;46872:10:::0;;46792:98;76510:12:::3;-1:-1:-1::0;;;;;76502:51:0::3;;76545:7;76502:51;;;;160:25:1::0;;148:2;133:18;;14:177;76502:51:0::3;;;;;;;;-1:-1:-1::0;;44450:1:0::1;45581:7;:22:::0;-1:-1:-1;;75984:577:0:o;74854:1046::-;74989:23;52857:19;:17;:19::i;:::-;55050:8:::1;::::0;-1:-1:-1;;;;;55050:8:0::1;46872:10:::0;-1:-1:-1;;;;;55034:24:0::1;;55060:32;;;;;;;;;;;;;-1:-1:-1::0;;;55060:32:0::1;;::::0;55026:67:::1;;;;;-1:-1:-1::0;;;55026:67:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;75046:6:0::2;::::0;75087:32:::2;::::0;;-1:-1:-1;;;75087:32:0;;;;-1:-1:-1;;;;;75046:6:0;;::::2;::::0;75030:13:::2;::::0;75046:6;;75087:30:::2;::::0;:32:::2;::::0;;::::2;::::0;::::2;::::0;;;;;;;;;75046:6;75087:32:::2;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75063:56;;;;75130:14;75147:72;75194:9;75205:13;75147:46;:72::i;:::-;75259:11;::::0;75130:89;;-1:-1:-1;;;;;;75259:11:0::2;75232:17;75259:11:::0;75361:17:::2;75393:74;75411:22;15792:4;75130:89:::0;75411:22:::2;:::i;:::-;75435:10;-1:-1:-1::0;;;;;75435:29:0::2;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75393:17;:74::i;:::-;75361:117;;;;;;;;;;;;;160:25:1::0;;148:2;133:18;;14:177;75361:117:0::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75518:39;::::0;;;;::::2;::::0;;;::::2;::::0;;::::2;;::::0;::::2;::::0;75338:140;;-1:-1:-1;75499:17:0;;75491:67:::2;;;;-1:-1:-1::0;;;75491:67:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;75605:49:0::2;::::0;-1:-1:-1;;;75605:49:0;;75648:4:::2;75605:49;::::0;::::2;342:74:1::0;75571:31:0::2;::::0;-1:-1:-1;;;;;75605:34:0;::::2;::::0;::::2;::::0;315:18:1;;75605:49:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75571:83:::0;-1:-1:-1;75724:76:0::2;-1:-1:-1::0;;;;;75724:37:0;::::2;46872:10:::0;75571:83;75724:37:::2;:76::i;:::-;75831:61;75853:23;75878:13;75831:21;:61::i;:::-;75813:79:::0;74854:1046;-1:-1:-1;;;;;;;;74854:1046:0:o;41149:200::-;-1:-1:-1;;;;;39699:6:0;39682:23;39690:4;39682:23;39674:80;;;;-1:-1:-1;;;39674:80:0;;5833:2:1;39674:80:0;;;5815:21:1;5872:2;5852:18;;;5845:30;5911:34;5891:18;;;5884:62;-1:-1:-1;;;5962:18:1;;;5955:42;6014:19;;39674:80:0;5631:408:1;39674:80:0;39797:6;-1:-1:-1;;;;;39773:30:0;:20;31125:66;31486:65;-1:-1:-1;;;;;31486:65:0;;31406:153;39773:20;-1:-1:-1;;;;;39773:30:0;;39765:87;;;;-1:-1:-1;;;39765:87:0;;6246:2:1;39765:87:0;;;6228:21:1;6285:2;6265:18;;;6258:30;6324:34;6304:18;;;6297:62;-1:-1:-1;;;6375:18:1;;;6368:42;6427:19;;39765:87:0;6044:408:1;39765:87:0;41233:36:::1;41251:17;41233;:36::i;:::-;41321:12;::::0;;41331:1:::1;41321:12:::0;;;::::1;::::0;::::1;::::0;;;41280:61:::1;::::0;41302:17;;41321:12;41280:21:::1;:61::i;:::-;41149:200:::0;:::o;57040:76::-;48640:13;:11;:13::i;:::-;57098:10:::1;:8;:10::i;:::-;57040:76::o:0;55763:291::-;52857:19;:17;:19::i;:::-;48640:13:::1;:11;:13::i;:::-;55881:24:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;55881:24:0::2;::::0;::::2;::::0;-1:-1:-1;;;;;55855:24:0;::::2;55847:59;;;;-1:-1:-1::0;;;55847:59:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;55938:8:0::2;::::0;;-1:-1:-1;;;;;55957:21:0;;::::2;-1:-1:-1::0;;;;;;55957:21:0;::::2;;::::0;;;55938:8:::2;55994:52;56009:12;46872:10:::0;;46792:98;56009:12:::2;55994:52;::::0;;-1:-1:-1;;;;;6738:15:1;;;6720:34;;6790:15;;;6785:2;6770:18;;6763:43;6842:15;;;6822:18;;;6815:43;6647:2;6632:18;55994:52:0::2;;;;;;;;55836:218;55763:291:::0;:::o;41608:225::-;-1:-1:-1;;;;;39699:6:0;39682:23;39690:4;39682:23;39674:80;;;;-1:-1:-1;;;39674:80:0;;5833:2:1;39674:80:0;;;5815:21:1;5872:2;5852:18;;;5845:30;5911:34;5891:18;;;5884:62;-1:-1:-1;;;5962:18:1;;;5955:42;6014:19;;39674:80:0;5631:408:1;39674:80:0;39797:6;-1:-1:-1;;;;;39773:30:0;:20;31125:66;31486:65;-1:-1:-1;;;;;31486:65:0;;31406:153;39773:20;-1:-1:-1;;;;;39773:30:0;;39765:87;;;;-1:-1:-1;;;39765:87:0;;6246:2:1;39765:87:0;;;6228:21:1;6285:2;6265:18;;;6258:30;6324:34;6304:18;;;6297:62;-1:-1:-1;;;6375:18:1;;;6368:42;6427:19;;39765:87:0;6044:408:1;39765:87:0;41726:36:::1;41744:17;41726;:36::i;:::-;41773:52;41795:17;41814:4;41820;41773:21;:52::i;:::-;41608:225:::0;;:::o;40827:133::-;40905:7;40135:4;-1:-1:-1;;;;;40144:6:0;40127:23;;40119:92;;;;-1:-1:-1;;;40119:92:0;;7071:2:1;40119:92:0;;;7053:21:1;7110:2;7090:18;;;7083:30;7149:34;7129:18;;;7122:62;7220:26;7200:18;;;7193:54;7264:19;;40119:92:0;6869:420:1;40119:92:0;-1:-1:-1;31125:66:0::1;40827:133:::0;:::o;49402:103::-;48640:13;:11;:13::i;:::-;49467:30:::1;49494:1;49467:18;:30::i;73491:346::-:0;73591:11;;73709:35;;-1:-1:-1;;;73709:35:0;;73738:4;73709:35;;;342:74:1;73544:7:0;;-1:-1:-1;;;;;73591:11:0;;73638:180;;73591:11;;73709:20;;315:18:1;;73709:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73675:10;-1:-1:-1;;;;;73675:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:69;;;;:::i;:::-;73784:6;;;;;;;;;-1:-1:-1;;;;;73784:6:0;-1:-1:-1;;;;;73769:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73765:37;;:2;:37;:::i;73638:180::-;73616:213;;;73491:346;:::o;56960:72::-;48640:13;:11;:13::i;:::-;57016:8:::1;:6;:8::i;72516:201::-:0;72566:11;72590:13;72613:11;;;;;;;;;-1:-1:-1;;;;;72613:11:0;-1:-1:-1;;;;;72606:38:0;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72590:56;;72695:14;;72687:5;:22;;;;:::i;74056:565::-;74190:23;52857:19;:17;:19::i;:::-;55050:8:::1;::::0;-1:-1:-1;;;;;55050:8:0::1;46872:10:::0;-1:-1:-1;;;;;55034:24:0::1;;55060:32;;;;;;;;;;;;;-1:-1:-1::0;;;55060:32:0::1;;::::0;55026:67:::1;;;;;-1:-1:-1::0;;;55026:67:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;74247:6:0::2;::::0;74288:32:::2;::::0;;-1:-1:-1;;;74288:32:0;;;;-1:-1:-1;;;;;74247:6:0;;::::2;::::0;74231:13:::2;::::0;74247:6;;74288:30:::2;::::0;:32:::2;::::0;;::::2;::::0;::::2;::::0;;;;;;;;;74247:6;74288:32:::2;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74264:56;;;;74331:14;74348:60;74383:9;74394:13;74348:34;:60::i;:::-;74331:77:::0;-1:-1:-1;74419:78:0::2;-1:-1:-1::0;;;;;74419:41:0;::::2;46872:10:::0;74483:4:::2;74331:77:::0;74419:41:::2;:78::i;:::-;74515:11;::::0;74508:32:::2;::::0;-1:-1:-1;;;74508:32:0;;::::2;::::0;::::2;160:25:1::0;;;-1:-1:-1;;;;;74515:11:0;;::::2;::::0;74508:24:::2;::::0;133:18:1;;74508:32:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;74569:44;74591:6;74599:13;74569:21;:44::i;:::-;74551:62:::0;74056:565;-1:-1:-1;;;;;74056:565:0:o;51054:152::-;51263:15;;51296:37;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51263:15:0;46872:10;51263:31;51255:79;;;;-1:-1:-1;;;51255:79:0;;;;;;;;:::i;:::-;-1:-1:-1;51127:15:0::1;:28:::0;;-1:-1:-1;;;;;;51127:28:0::1;::::0;;51166:32:::1;46872:10:::0;51166:18:::1;:32::i;76569:355::-:0;52857:19;:17;:19::i;:::-;48640:13:::1;:11;:13::i;:::-;76695:38:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;::::2;;::::0;::::2;::::0;76673:20;76665:69:::2;;;;-1:-1:-1::0;;;76665:69:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;76772:14:0::2;::::0;;76797:33;;;;76846:70:::2;::::0;;46872:10;8879:74:1;;8984:2;8969:18;;8962:34;;;9012:18;;;9005:34;;;76846:70:0::2;::::0;8867:2:1;8852:18;76846:70:0::2;8677:368:1::0;56625:327:0;52857:19;:17;:19::i;:::-;55187:16:::1;::::0;-1:-1:-1;;;;;55187:16:0::1;46872:10:::0;-1:-1:-1;;;;;55171:32:0::1;;55205:41;;;;;;;;;;;;;;;;::::0;55163:84:::1;;;;;-1:-1:-1::0;;;55163:84:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;56756:40:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;;::::2;;::::0;::::2;::::0;-1:-1:-1;;;;;56729:25:0;::::2;56721:76;;;;-1:-1:-1::0;;;56721:76:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;56830:9:0::2;::::0;;-1:-1:-1;;;;;56850:23:0;;::::2;-1:-1:-1::0;;;;;;56850:23:0;::::2;;::::0;;;56830:9:::2;56889:55;56905:12;46872:10:::0;;46792:98;50784:262;48640:13;:11;:13::i;:::-;50910:24:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;50910:24:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;50880:28:0;::::1;50872:63;;;;-1:-1:-1::0;;;50872:63:0::1;;;;;;;;:::i;:::-;-1:-1:-1::0;50946:15:0::1;:32:::0;;-1:-1:-1;;;;;;50946:32:0::1;-1:-1:-1::0;;;;;50946:32:0;::::1;::::0;;::::1;::::0;;;50994:44:::1;::::0;::::1;::::0;-1:-1:-1;;50994:44:0::1;50784:262:::0;:::o;71561:874::-;27346:19;27369:13;;;;;;27368:14;;27416:34;;;;-1:-1:-1;27434:12:0;;27449:1;27434:12;;;;:16;27416:34;27415:108;;;-1:-1:-1;27495:4:0;18108:19;:23;;;27456:66;;-1:-1:-1;27505:12:0;;;;;:17;27456:66;27393:204;;;;-1:-1:-1;;;27393:204:0;;9252:2:1;27393:204:0;;;9234:21:1;9291:2;9271:18;;;9264:30;9330:34;9310:18;;;9303:62;9401:16;9381:18;;;9374:44;9435:19;;27393:204:0;9050:410:1;27393:204:0;27608:12;:16;;-1:-1:-1;;27608:16:0;27623:1;27608:16;;;27635:67;;;;27670:13;:20;;-1:-1:-1;;27670:20:0;;;;;27635:67;44494:1:::1;45269:7;;:19:::0;45261:63:::1;;;::::0;-1:-1:-1;;;45261:63:0;;3126:2:1;45261:63:0::1;::::0;::::1;3108:21:1::0;3165:2;3145:18;;;3138:30;3204:33;3184:18;;;3177:61;3255:18;;45261:63:0::1;2924:355:1::0;45261:63:0::1;44494:1;45402:7;:18:::0;71742:17:::2;:15;:17::i;:::-;71770:16;:14;:16::i;:::-;71797:24;:22;:24::i;:::-;71863;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;71863:24:0::2;::::0;::::2;::::0;-1:-1:-1;;;;;71842:19:0;::::2;71834:54;;;;-1:-1:-1::0;;;71834:54:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;71933:24:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;71933:24:0::2;::::0;::::2;::::0;-1:-1:-1;;;;;71907:24:0;::::2;71899:59;;;;-1:-1:-1::0;;;71899:59:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;72004:24:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;72004:24:0::2;::::0;::::2;::::0;-1:-1:-1;;;;;71977:25:0;::::2;71969:60;;;;-1:-1:-1::0;;;71969:60:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;72073:24:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;72073:24:0::2;::::0;::::2;::::0;-1:-1:-1;;;;;72048:23:0;::::2;72040:58;;;;-1:-1:-1::0;;;72040:58:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;72111:6:0::2;:14:::0;;-1:-1:-1;;;;;72111:14:0;;::::2;-1:-1:-1::0;;;;;;72111:14:0;;::::2;::::0;::::2;::::0;;;72136:11:::2;:24:::0;;;;::::2;::::0;;::::2;;::::0;;72171:12:::2;:48:::0;;;;::::2;::::0;;::::2;;::::0;;72230:10:::2;:41:::0;;;;::::2;::::0;;;::::2;;::::0;;72282:68:::2;::::0;72150:10;-1:-1:-1;;72282:37:0::2;:68::i;:::-;72378:7;72361:14;:24:::0;72396:16:::2;:31:::0;;-1:-1:-1;;;;;;72396:31:0::2;46872:10:::0;72396:31:::2;::::0;;-1:-1:-1;45581:7:0::1;:22:::0;27724:102;;;;27775:5;27759:21;;-1:-1:-1;;27759:21:0;;;27800:14;;-1:-1:-1;9617:36:1;;27800:14:0;;9605:2:1;9590:18;27800:14:0;;;;;;;27724:102;27335:498;71561:874;;;;:::o;56183:327::-;52857:19;:17;:19::i;:::-;48640:13:::1;:11;:13::i;:::-;56303:24:::2;::::0;;;;::::2;::::0;;;::::2;::::0;;-1:-1:-1;;;56303:24:0::2;::::0;::::2;::::0;-1:-1:-1;;;;;56280:21:0;::::2;56272:56;;;;-1:-1:-1::0;;;56272:56:0::2;;;;;;;;:::i;:::-;-1:-1:-1::0;56368:16:0::2;::::0;;-1:-1:-1;;;;;56395:26:0;;::::2;-1:-1:-1::0;;;;;;56395:26:0;::::2;;::::0;;;56368:16:::2;56437:65;56460:12;46872:10:::0;;46792:98;53411:108;53323:7;;;;53481:9;53473:38;;;;-1:-1:-1;;;53473:38:0;;9866:2:1;53473:38:0;;;9848:21:1;9905:2;9885:18;;;9878:30;9944:18;9924;;;9917:46;9980:18;;53473:38:0;9664:340:1;48919:132:0;48827:6;;-1:-1:-1;;;;;48827:6:0;46872:10;48983:23;48975:68;;;;-1:-1:-1;;;48975:68:0;;10211:2:1;48975:68:0;;;10193:21:1;;;10230:18;;;10223:30;10289:34;10269:18;;;10262:62;10341:18;;48975:68:0;10009:356:1;63307:222:0;63462:58;;-1:-1:-1;;;;;10562:55:1;;63462:58:0;;;10544:74:1;10634:18;;;10627:34;;;63435:86:0;;63455:5;;-1:-1:-1;;;63485:23:0;10517:18:1;;63462:58:0;;;;-1:-1:-1;;63462:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;63435:19;:86::i;:::-;63307:222;;;:::o;14352:420::-;14487:7;14516:13;14533:2;14516:19;14512:253;;-1:-1:-1;14559:5:0;14552:12;;14512:253;14602:2;14586:13;:18;14582:183;;;14641:18;14657:2;14641:13;:18;:::i;:::-;14636:24;;:2;:24;:::i;:::-;14628:32;;:5;:32;:::i;:::-;14621:39;;;;14582:183;14700:53;14721:5;14733:18;14738:13;14733:2;:18;:::i;:::-;14728:24;;:2;:24;:::i;:::-;14700:20;:53::i;14582:183::-;14352:420;;;;:::o;13582:114::-;13645:9;13687:1;13677:5;13681:1;13687;13677:5;:::i;:::-;13672:11;;:1;:11;:::i;:::-;13671:17;;;;:::i;:::-;13667:21;13582:114;-1:-1:-1;;;13582:114:0:o;14780:461::-;14863:7;14887:9;;14883:351;;14917:13;14934:2;14917:19;14913:265;;-1:-1:-1;14964:5:0;14957:12;;14913:265;15011:2;14995:13;:18;14991:187;;;15041:41;15050:5;15062:18;15078:2;15062:13;:18;:::i;:::-;15057:24;;:2;:24;:::i;14991:187::-;15143:18;15148:13;15143:2;:18;:::i;14883:351::-;-1:-1:-1;15217:5:0;15210:12;;57163:66;48640:13;:11;:13::i;32824:992::-;30777:66;33278:59;;;33274:535;;;33354:37;33373:17;33354:18;:37::i;33274:535::-;33457:17;-1:-1:-1;;;;;33428:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33428:63:0;;;;;;;;-1:-1:-1;;33428:63:0;;;;;;;;;;;;:::i;:::-;;;33424:306;;33658:56;;-1:-1:-1;;;33658:56:0;;11684:2:1;33658:56:0;;;11666:21:1;11723:2;11703:18;;;11696:30;11762:34;11742:18;;;11735:62;11833:16;11813:18;;;11806:44;11867:19;;33658:56:0;11482:410:1;33424:306:0;31125:66;33542:28;;33534:82;;;;-1:-1:-1;;;33534:82:0;;12099:2:1;33534:82:0;;;12081:21:1;12138:2;12118:18;;;12111:30;12177:34;12157:18;;;12150:62;12248:11;12228:18;;;12221:39;12277:19;;33534:82:0;11897:405:1;33534:82:0;33492:140;33744:53;33762:17;33781:4;33787:9;33744:17;:53::i;54107:120::-;53116:16;:14;:16::i;:::-;54166:7:::1;:15:::0;;-1:-1:-1;;54166:15:0::1;::::0;;54197:22:::1;46872:10:::0;54206:12:::1;54197:22;::::0;-1:-1:-1;;;;;360:55:1;;;342:74;;330:2;315:18;54197:22:0::1;;;;;;;54107:120::o:0;50021:191::-;50114:6;;;-1:-1:-1;;;;;50131:17:0;;;-1:-1:-1;;;;;;50131:17:0;;;;;;;50164:40;;50114:6;;;50131:17;50114:6;;50164:40;;50095:16;;50164:40;50084:128;50021:191;:::o;53848:118::-;52857:19;:17;:19::i;:::-;53908:7:::1;:14:::0;;-1:-1:-1;;53908:14:0::1;53918:4;53908:14;::::0;;53938:20:::1;53945:12;46872:10:::0;;46792:98;13948:396;14071:7;14100:13;14117:2;14100:19;14096:241;;-1:-1:-1;14143:5:0;14136:12;;14096:241;14186:2;14170:13;:18;14166:171;;;14225:18;14241:2;14225:13;:18;:::i;14166:171::-;14284:41;14293:5;14305:18;14310:13;14305:2;:18;:::i;63537:259::-;63719:68;;-1:-1:-1;;;;;12588:15:1;;;63719:68:0;;;12570:34:1;12640:15;;12620:18;;;12613:43;12672:18;;;12665:34;;;63692:96:0;;63712:5;;-1:-1:-1;;;63742:27:0;12482:18:1;;63719:68:0;12307:398:1;63692:96:0;63537:259;;;;:::o;52422:99::-;29187:13;;;;;;;29179:69;;;;-1:-1:-1;;;29179:69:0;;12912:2:1;29179:69:0;;;12894:21:1;12951:2;12931:18;;;12924:30;12990:34;12970:18;;;12963:62;-1:-1:-1;;;13041:18:1;;;13034:41;13092:19;;29179:69:0;12710:407:1;29179:69:0;52486:27:::1;:25;:27::i;48297:97::-:0;29187:13;;;;;;;29179:69;;;;-1:-1:-1;;;29179:69:0;;12912:2:1;29179:69:0;;;12894:21:1;12951:2;12931:18;;;12924:30;12990:34;12970:18;;;12963:62;-1:-1:-1;;;13041:18:1;;;13034:41;13092:19;;29179:69:0;12710:407:1;29179:69:0;48360:26:::1;:24;:26::i;38827:68::-:0;29187:13;;;;;;;29179:69;;;;-1:-1:-1;;;29179:69:0;;12912:2:1;29179:69:0;;;12894:21:1;12951:2;12931:18;;;12924:30;12990:34;12970:18;;;12963:62;-1:-1:-1;;;13041:18:1;;;13034:41;13092:19;;29179:69:0;12710:407:1;64065:627:0;64440:10;;;64439:62;;-1:-1:-1;64456:39:0;;-1:-1:-1;;;64456:39:0;;64480:4;64456:39;;;13357:34:1;-1:-1:-1;;;;;13427:15:1;;;13407:18;;;13400:43;64456:15:0;;;;;13269:18:1;;64456:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;64439:62;64417:166;;;;-1:-1:-1;;;64417:166:0;;13656:2:1;64417:166:0;;;13638:21:1;13695:2;13675:18;;;13668:30;13734:34;13714:18;;;13707:62;13805:24;13785:18;;;13778:52;13847:19;;64417:166:0;13454:418:1;64417:166:0;64621:62;;-1:-1:-1;;;;;10562:55:1;;64621:62:0;;;10544:74:1;10634:18;;;10627:34;;;64594:90:0;;64614:5;;-1:-1:-1;;;64644:22:0;10517:18:1;;64621:62:0;10370:297:1;66440:727:0;66875:23;66901:69;66929:4;66901:69;;;;;;;;;;;;;;;;;66909:5;-1:-1:-1;;;;;66901:27:0;;;:69;;;;;:::i;:::-;66985:17;;66875:95;;-1:-1:-1;66985:21:0;66981:179;;67082:10;67071:30;;;;;;;;;;;;:::i;:::-;67063:85;;;;-1:-1:-1;;;67063:85:0;;14361:2:1;67063:85:0;;;14343:21:1;14400:2;14380:18;;;14373:30;14439:34;14419:18;;;14412:62;14510:12;14490:18;;;14483:40;14540:19;;67063:85:0;14159:406:1;13826:114:0;13901:9;13927:5;13931:1;13927;:5;:::i;31655:284::-;-1:-1:-1;;;;;18108:19:0;;;31729:106;;;;-1:-1:-1;;;31729:106:0;;14772:2:1;31729:106:0;;;14754:21:1;14811:2;14791:18;;;14784:30;14850:34;14830:18;;;14823:62;14921:15;14901:18;;;14894:43;14954:19;;31729:106:0;14570:409:1;31729:106:0;31125:66;31846:85;;-1:-1:-1;;;;;;31846:85:0;-1:-1:-1;;;;;31846:85:0;;;;;;;;;;31655:284::o;32348:297::-;32491:29;32502:17;32491:10;:29::i;:::-;32549:1;32535:4;:11;:15;:28;;;;32554:9;32535:28;32531:107;;;32580:46;32602:17;32621:4;32580:21;:46::i;53596:108::-;53323:7;;;;53655:41;;;;-1:-1:-1;;;53655:41:0;;15186:2:1;53655:41:0;;;15168:21:1;15225:2;15205:18;;;15198:30;15264:22;15244:18;;;15237:50;15304:18;;53655:41:0;14984:344:1;52529:97:0;29187:13;;;;;;;29179:69;;;;-1:-1:-1;;;29179:69:0;;12912:2:1;29179:69:0;;;12894:21:1;12951:2;12931:18;;;12924:30;12990:34;12970:18;;;12963:62;-1:-1:-1;;;13041:18:1;;;13034:41;13092:19;;29179:69:0;12710:407:1;29179:69:0;52603:7:::1;:15:::0;;-1:-1:-1;;52603:15:0::1;::::0;;52529:97::o;48402:113::-;29187:13;;;;;;;29179:69;;;;-1:-1:-1;;;29179:69:0;;12912:2:1;29179:69:0;;;12894:21:1;12951:2;12931:18;;;12924:30;12990:34;12970:18;;;12963:62;-1:-1:-1;;;13041:18:1;;;13034:41;13092:19;;29179:69:0;12710:407:1;29179:69:0;48475:32:::1;46872:10:::0;51166:18:::1;:32::i;20558:229::-:0;20695:12;20727:52;20749:6;20757:4;20763:1;20766:12;20727:21;:52::i;:::-;20720:59;20558:229;-1:-1:-1;;;;20558:229:0:o;32052:155::-;32119:37;32138:17;32119:18;:37::i;:::-;32172:27;;-1:-1:-1;;;;;32172:27:0;;;;;;;;32052:155;:::o;37085:461::-;37168:12;-1:-1:-1;;;;;18108:19:0;;;37193:88;;;;-1:-1:-1;;;37193:88:0;;15535:2:1;37193:88:0;;;15517:21:1;15574:2;15554:18;;;15547:30;15613:34;15593:18;;;15586:62;15684:8;15664:18;;;15657:36;15710:19;;37193:88:0;15333:402:1;37193:88:0;37355:12;37369:23;37396:6;-1:-1:-1;;;;;37396:19:0;37416:4;37396:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37354:67;;;;37439:99;37475:7;37484:10;37439:99;;;;;;;;;;;;;;;;;:35;:99::i;21678:510::-;21848:12;21906:5;21881:21;:30;;21873:81;;;;-1:-1:-1;;;21873:81:0;;16234:2:1;21873:81:0;;;16216:21:1;16273:2;16253:18;;;16246:30;16312:34;16292:18;;;16285:62;16383:8;16363:18;;;16356:36;16409:19;;21873:81:0;16032:402:1;21873:81:0;-1:-1:-1;;;;;18108:19:0;;;21965:60;;;;-1:-1:-1;;;21965:60:0;;16641:2:1;21965:60:0;;;16623:21:1;16680:2;16660:18;;;16653:30;16719:31;16699:18;;;16692:59;16768:18;;21965:60:0;16439:353:1;21965:60:0;22039:12;22053:23;22080:6;-1:-1:-1;;;;;22080:11:0;22099:5;22106:4;22080:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22038:73;;;;22129:51;22146:7;22155:10;22167:12;22129:16;:51::i;:::-;22122:58;21678:510;-1:-1:-1;;;;;;;21678:510:0:o;23387:762::-;23537:12;23566:7;23562:580;;;-1:-1:-1;23597:10:0;23590:17;;23562:580;23711:17;;:21;23707:424;;23959:10;23953:17;24020:15;24007:10;24003:2;23999:19;23992:44;23707:424;24102:12;24095:20;;-1:-1:-1;;;24095:20:0;;;;;;;;:::i;427:180:1:-;486:6;539:2;527:9;518:7;514:23;510:32;507:52;;;555:1;552;545:12;507:52;-1:-1:-1;578:23:1;;427:180;-1:-1:-1;427:180:1:o;612:196::-;680:20;;-1:-1:-1;;;;;729:54:1;;719:65;;709:93;;798:1;795;788:12;709:93;612:196;;;:::o;813:186::-;872:6;925:2;913:9;904:7;900:23;896:32;893:52;;;941:1;938;931:12;893:52;964:29;983:9;964:29;:::i;1004:127::-;1065:10;1060:3;1056:20;1053:1;1046:31;1096:4;1093:1;1086:15;1120:4;1117:1;1110:15;1136:995;1213:6;1221;1274:2;1262:9;1253:7;1249:23;1245:32;1242:52;;;1290:1;1287;1280:12;1242:52;1313:29;1332:9;1313:29;:::i;:::-;1303:39;;1393:2;1382:9;1378:18;1365:32;1416:18;1457:2;1449:6;1446:14;1443:34;;;1473:1;1470;1463:12;1443:34;1511:6;1500:9;1496:22;1486:32;;1556:7;1549:4;1545:2;1541:13;1537:27;1527:55;;1578:1;1575;1568:12;1527:55;1614:2;1601:16;1636:2;1632;1629:10;1626:36;;;1642:18;;:::i;:::-;1717:2;1711:9;1685:2;1771:13;;-1:-1:-1;;1767:22:1;;;1791:2;1763:31;1759:40;1747:53;;;1815:18;;;1835:22;;;1812:46;1809:72;;;1861:18;;:::i;:::-;1901:10;1897:2;1890:22;1936:2;1928:6;1921:18;1976:7;1971:2;1966;1962;1958:11;1954:20;1951:33;1948:53;;;1997:1;1994;1987:12;1948:53;2053:2;2048;2044;2040:11;2035:2;2027:6;2023:15;2010:46;2098:1;2093:2;2088;2080:6;2076:15;2072:24;2065:35;2119:6;2109:16;;;;;;;1136:995;;;;;:::o;2510:409::-;2596:6;2604;2612;2620;2673:3;2661:9;2652:7;2648:23;2644:33;2641:53;;;2690:1;2687;2680:12;2641:53;2713:29;2732:9;2713:29;:::i;:::-;2703:39;;2761:38;2795:2;2784:9;2780:18;2761:38;:::i;:::-;2751:48;;2818:38;2852:2;2841:9;2837:18;2818:38;:::i;:::-;2808:48;;2875:38;2909:2;2898:9;2894:18;2875:38;:::i;:::-;2865:48;;2510:409;;;;;;;:::o;3284:250::-;3369:1;3379:113;3393:6;3390:1;3387:13;3379:113;;;3469:11;;;3463:18;3450:11;;;3443:39;3415:2;3408:10;3379:113;;;-1:-1:-1;;3526:1:1;3508:16;;3501:27;3284:250::o;3539:396::-;3688:2;3677:9;3670:21;3651:4;3720:6;3714:13;3763:6;3758:2;3747:9;3743:18;3736:34;3779:79;3851:6;3846:2;3835:9;3831:18;3826:2;3818:6;3814:15;3779:79;:::i;:::-;3919:2;3898:15;-1:-1:-1;;3894:29:1;3879:45;;;;3926:2;3875:54;;3539:396;-1:-1:-1;;3539:396:1:o;3940:127::-;4001:10;3996:3;3992:20;3989:1;3982:31;4032:4;4029:1;4022:15;4056:4;4053:1;4046:15;4072:782;4242:4;4290:2;4279:9;4275:18;-1:-1:-1;;;;;4393:2:1;4385:6;4381:15;4370:9;4363:34;4416:2;4454;4449;4438:9;4434:18;4427:30;4477:6;4512;4506:13;4543:6;4535;4528:22;4581:2;4570:9;4566:18;4559:25;;4619:2;4611:6;4607:15;4593:29;;4640:1;4650:178;4664:6;4661:1;4658:13;4650:178;;;4729:13;;4725:22;;4713:35;;4803:15;;;;4768:12;;;;4686:1;4679:9;4650:178;;;-1:-1:-1;4845:3:1;;4072:782;-1:-1:-1;;;;;;;;4072:782:1:o;4859:184::-;4929:6;4982:2;4970:9;4961:7;4957:23;4953:32;4950:52;;;4998:1;4995;4988:12;4950:52;-1:-1:-1;5021:16:1;;4859:184;-1:-1:-1;4859:184:1:o;5048:273::-;5116:6;5169:2;5157:9;5148:7;5144:23;5140:32;5137:52;;;5185:1;5182;5175:12;5137:52;5217:9;5211:16;5267:4;5260:5;5256:16;5249:5;5246:27;5236:55;;5287:1;5284;5277:12;5326:127;5387:10;5382:3;5378:20;5375:1;5368:31;5418:4;5415:1;5408:15;5442:4;5439:1;5432:15;5458:168;5498:7;5564:1;5560;5556:6;5552:14;5549:1;5546:21;5541:1;5534:9;5527:17;5523:45;5520:71;;;5571:18;;:::i;:::-;-1:-1:-1;5611:9:1;;5458:168::o;7294:422::-;7383:1;7426:5;7383:1;7440:270;7461:7;7451:8;7448:21;7440:270;;;7520:4;7516:1;7512:6;7508:17;7502:4;7499:27;7496:53;;;7529:18;;:::i;:::-;7579:7;7569:8;7565:22;7562:55;;;7599:16;;;;7562:55;7678:22;;;;7638:15;;;;7440:270;;;7444:3;7294:422;;;;;:::o;7721:806::-;7770:5;7800:8;7790:80;;-1:-1:-1;7841:1:1;7855:5;;7790:80;7889:4;7879:76;;-1:-1:-1;7926:1:1;7940:5;;7879:76;7971:4;7989:1;7984:59;;;;8057:1;8052:130;;;;7964:218;;7984:59;8014:1;8005:10;;8028:5;;;8052:130;8089:3;8079:8;8076:17;8073:43;;;8096:18;;:::i;:::-;-1:-1:-1;;8152:1:1;8138:16;;8167:5;;7964:218;;8266:2;8256:8;8253:16;8247:3;8241:4;8238:13;8234:36;8228:2;8218:8;8215:16;8210:2;8204:4;8201:12;8197:35;8194:77;8191:159;;;-1:-1:-1;8303:19:1;;;8335:5;;8191:159;8382:34;8407:8;8401:4;8382:34;:::i;:::-;8452:6;8448:1;8444:6;8440:19;8431:7;8428:32;8425:58;;;8463:18;;:::i;:::-;8501:20;;7721:806;-1:-1:-1;;;7721:806:1:o;8532:140::-;8590:5;8619:47;8660:4;8650:8;8646:19;8640:4;8619:47;:::i;10672:128::-;10739:9;;;10760:11;;;10757:37;;;10774:18;;:::i;10805:131::-;10865:5;10894:36;10921:8;10915:4;10894:36;:::i;10941:217::-;10981:1;11007;10997:132;;11051:10;11046:3;11042:20;11039:1;11032:31;11086:4;11083:1;11076:15;11114:4;11111:1;11104:15;10997:132;-1:-1:-1;11143:9:1;;10941:217::o;11163:125::-;11228:9;;;11249:10;;;11246:36;;;11262:18;;:::i;13877:277::-;13944:6;13997:2;13985:9;13976:7;13972:23;13968:32;13965:52;;;14013:1;14010;14003:12;13965:52;14045:9;14039:16;14098:5;14091:13;14084:21;14077:5;14074:32;14064:60;;14120:1;14117;14110:12;15740:287;15869:3;15907:6;15901:13;15923:66;15982:6;15977:3;15970:4;15962:6;15958:17;15923:66;:::i;:::-;16005:16;;;;;15740:287;-1:-1:-1;;15740:287:1:o
Swarm Source
ipfs://18f23da5dd2544f4d5b528b2112b82c4482dfe9fa3b7bf731903ed75bc873cfe
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.