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 Name:
DepositsManager
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-01-24 */ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.18; // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol) // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) /** * @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); } // OpenZeppelin Contracts (last updated v4.8.3) (proxy/ERC1967/ERC1967Upgrade.sol) // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) /** * @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); } // OpenZeppelin Contracts (last updated v4.8.3) (interfaces/IERC1967.sol) /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.9._ */ interface IERC1967Upgradeable { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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); } } } // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) /** * @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 } } } // OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since 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. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ 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. * * 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. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * 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. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ 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. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } } /** * @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, IERC1967Upgradeable { 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 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 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 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; } /** * @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 the implementation's compatibility when performing 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; } // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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; } /** * @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; } // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ 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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // 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; } // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) /** * @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); } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) /** * @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); } /** * @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"); } } } interface IDepositsManager { /// @notice Status of orders at strategy enum Status { Unbonding, Claimable, Claimed } /// @notice WithdrawOrder struct /// @param token - Address liquid token /// @param owner - Address owner of the order and tokens /// @param id - Unique id on the underlying protocol /// @param amount - Total amount of liquid token on order /// @param amountCsETH - Total amount of csETH claimed /// @param startTime - Timestamp when unbonding has started /// @param isClaimed - already claimed from owner struct WithdrawOrder { address token; address owner; uint256 id; uint256 amount; uint256 amountCsETH; uint256 startTime; bool isClaimed; } /// @notice Struct used on when returning user withdraw order /// @param token - Address liquid token /// @param orderId : Withdraw order id. /// @param amount - Total amount of liquid token on order /// @param amountCsETH - Total amount of csETH claimed /// @param startTime - Timestamp when unbonding has started /// @param status - Status of order struct UserWithdrawOrderInfo { address token; uint256 orderId; uint256 amount; uint256 amountCsETH; uint256 startTime; Status status; } /// @notice Event for new withdraw request. /// @param user : Address of user withdrawing. /// @param token : Address liquid token. /// @param orderId : Withdraw order id. /// @param id : Unique id at strategy to be used at claim. /// @param amount : Amount of liquid token withdrawn. /// @param amountCsETH : Amount of csETH tokens received. /// @param startTime : Unstake start time. event LogWithdraw( address indexed user, address indexed token, uint256 indexed orderId, uint256 id, uint256 amount, uint256 amountCsETH, uint256 startTime ); /// @notice Event for claim a withdraw order. /// @param user : Address of user. /// @param orderId : Claiming order id. /// @param amount : Amount of liquid tokens received. /// @param amountCsETH : Amount of csETH tokens received. event LogClaim(address indexed user, uint256 indexed orderId, uint256 amount, uint256 amountCsETH); /// @notice Starts withdraw order of liquid token triggering strategy. function withdraw(address token, uint256 amount, address delegateTo) external returns (uint256); /// @notice Starts withdraw order of all given liquid token triggering strategy. function withdrawAll( address[] calldata token, uint256[] calldata amount, address delegateTo ) external returns (bool); } interface IRoleManager { /// @dev Returns a boolean value indicating whether `_account` has role `_roleName` or not. function checkRole(bytes32 _roleName, address _account) external view returns (bool); } interface ICSToken { /// @notice Returns the amount of tokens in existence. function totalSupply() external view returns (uint256); /// @notice Returns the amount of tokens owned by `_account`. function balanceOf(address _account) external view returns (uint256); /// @notice Mints `_amount` of tokens `_to` user. function mint(address _to, uint256 _amount) external returns (bool); /// @notice Burns `_amount` of tokens `_from` user. function burn(address _from, uint256 _amount) external returns (bool); /// @notice Transfers `_amount` of tokens `_to` user. function transfer(address _to, uint256 _amount) external returns (bool); } interface IClayMain { /// @notice Supported fee types. Matches fees ordering. enum SetFee { DepositFee, WithdrawFee, InstantWithdrawFee } /// @notice Struct used on ClayMatic fees struct Fees { uint256 depositFee; uint256 withdrawFee; uint256 instantWithdrawFee; } /// @notice Struct used on ClayMatic for returning user withdraw order struct UserWithdrawOrderInfo { uint256 orderId; uint256 amount; uint256 fee; uint256 claimableAt; bool isClaimable; } /// @notice Struct to track internal funds accounting /// @param currentDeposit : Total user deposits backing csETH /// @param withdrawQueue : Current amount of ETH waiting in the queue to be withdrawn by users /// @param stakedDeposit : Amount of ETH currently staked with validators without including exit requests /// @param unstakeExternal : Amount of ETH staked, yet in the process to be withdrawn due user withdraw requests /// @param unstakeInternal : Amount of ETH staked, yet in the process to be withdrawn due to protocol balancing /// @param withdrawQueueOpen : Amount of ETH to be claimed from withdrawals on open batches /// @param claimablePool : ETH balance reserved on contract for claims. struct Funds { uint256 currentDeposit; uint256 withdrawQueue; uint256 stakedDeposit; uint256 unstakeExternal; uint256 unstakeInternal; uint256 withdrawQueueOpen; uint256 claimablePool; } /// @notice WithdrawOrder struct /// @param amount : Total amount unstaked from from ethereum. /// @param fee : Fee percentage to be paid by the user at claim time. /// @param claimableAt timestamp when batch claims can be processed /// @param batchId : Id of the batch process to be sent to ethereum. struct WithdrawOrder { uint256 amount; uint256 fee; uint256 claimableAt; uint256 batchId; } /// @notice Information on batches for withdraws /// @param claimableAt timestamp when batch claims can be processed /// @param amount : Total amount unstaked from from ethereum. /// @param amountCs : Total amount of csToken burned on batch. /// @param multiplier : Multiplier for batch accounting for slashing struct BatchWithdraw { uint256 claimableAt; uint256 amount; uint256 amountCs; uint256 multiplier; } /// @notice Exchange rate allowed percentage deviation. /// @param exchangeDecreaseLimit - Max allowed rate decrease percentage based on last valid exchange rate /// @param exchangeIncreaseLimit - Max allowed rate increase percentage based on last valid exchange rate struct ExchangeDeviation { uint256 exchangeDecreaseLimit; uint256 exchangeIncreaseLimit; } /// @notice Event for new deposit. /// @param user : Address of depositor. /// @param amount : Amount of Token deposited. /// @param amountCs : Amount of csToken minted. /// @param fee : Fee paid by user on deposit in Token event LogDeposit(address indexed user, uint256 amount, uint256 amountCs, uint256 fee); /// @notice Event for new withdraw request. /// @param user : Address of user withdrawing. /// @param orderId : Withdraw order id. /// @param amountCs : Amount of csToken burned. /// @param amount : Amount of Token withdrawn. /// @param fee : Fee percentage to be paid by the user /// @param timestamp : Epoch at the moment of request event LogWithdraw( address indexed user, uint256 orderId, uint256 amountCs, uint256 amount, uint256 fee, uint256 timestamp ); /// @notice Event for withdraw claims by user. /// @param user : Address of user. /// @param orderId : Withdraw order id. /// @param amount : Amount of Token unstaked in order. /// @param received : Amount of Token received in order. /// @param fee : Fee paid by user. event LogClaim(address indexed user, uint256 orderId, uint256 amount, uint256 received, uint256 fee); /// @notice Event for instant withdraw. /// @param user : Address of user. /// @param amountCs : Amount of csToken burned. /// @param amount : Amount of Token withdrawn. /// @param fee : Fee paid by user on instant withdraw in Token event LogInstantWithdraw(address indexed user, uint256 amountCs, uint256 amount, uint256 fee); /// @notice Event for new deposit. /// @param updatedBy : Address of Updating entity. /// @param feeType : Fee type being updated. /// @param oldFee : Existing fee percent for given fee type. /// @param newFee : New fee percent for given fee type. event LogFeeUpdate(address indexed updatedBy, SetFee feeType, uint256 oldFee, uint256 newFee); /// @notice Event emitted when AutoBalance is run. /// @param batchId : Id of the current processed batch. /// @param isNetStaking : Flag denoting net tx type of batch. /// @param amount : Amount of Token to be deposited or expected at claim. event LogAutoBalance(uint256 indexed batchId, bool indexed isNetStaking, uint256 amount); /// @notice Event for rewards recognized. /// @param rewards : Amount of rewards recognized. event LogRewards(uint256 rewards); /// @notice Event for Donations recognized. /// @param amount : Amount of donations recognized. event LogDonation(uint256 amount); /// @notice Event for batch closed. /// @param batchId : Id of the current processed batch. /// @param amount : Amount of Token to be deposited or expected at claim. /// @param amountCs : Amount of csToken burned on batch. /// @param multiplier : Multiplier for batch accounting for slashing event LogBatchClosed(uint256 indexed batchId, uint256 amount, uint256 amountCs, uint256 multiplier); /// @notice Event for imposed penalties. /// @param penaltiesToHolders : Amount of penalties to cs holders. /// @param penaltiesToClaims : Amount of penalties to be claimed. event LogPenalties(uint256 indexed penaltiesToHolders, uint256 indexed penaltiesToClaims); /// @notice Event for updated value of exchange rate /// @param rate : Updated rate value. /// @param time : Timestamp on which info is updated. event LogUpdateExchangeRate(uint256 rate, uint256 time); /// @notice Event for updating minimum claim delay. /// @param newMinClaimSeconds : New claim delay. event LogSetMinClaimTime(uint256 indexed newMinClaimSeconds); /// @notice Event for updating withdrawals. /// @param flag : bool for enabling/disabling withdrawals. event LogSetWithdrawalsDisabled(bool indexed flag); /// @notice Event for updating change update limits. /// @param newDecreaseLimit : New fx change limit floor. /// @param newIncreaseLimit : New fx change limit ceil. event LogSetExchangeDeviation(uint256 indexed newDecreaseLimit, uint256 indexed newIncreaseLimit); /// @notice Sends msg.value Token to ClayMain contract and mints csToken to msg.sender. function deposit() external payable returns (uint256); /// @notice Sends msg.value Token to ClayMain contract and mints csToken to `_delegatedTo`. function depositDelegate(address _delegatedTo) external payable returns (uint256); /// @notice Burns `_amountCs` csToken tokens from user and unstake respective amounts of Token tokens from node. function withdraw(uint256 _amountCs) external returns (uint256); /// @notice Allows user to claim unstaked tokens. function claim(uint256[] calldata _orderIds) external returns (bool); /// @notice Performs claiming of rewards & staking of Token tokens for ClayStack. function autoBalance( uint256 validatorCapacity ) external returns (uint256 currentBatchId, bool netStaking, uint256 validatorCount); /// @notice Exchange rate from csETH to ETH. function getExchangeRate() external view returns (uint256); /// @notice Returns amount of csTokens for given `_amountToken`. function exchangeToken(uint256 _amountToken) external view returns (uint256); /// @notice Returns amount of Tokens for given `_amountCsToken`. function exchangeCsToken(uint256 amountCsToken) external view returns (uint256); /// @notice Receives confirmation from NodeManager on batch finalization function closeBatches(uint256[] calldata _batchIds) external; /// @notice Receives liquidity from NodeManager for exits and rewards function receiveLiquidity(uint256 rewards, uint256 exited) external payable; /// @notice Returns instance of csToken function csToken() external returns (ICSToken); /// @notice enforceAndUpdateBalance public call function updateBalances() external; /// @notice Whether withdrawals & claims are disabled given slashing protection or other reasons function withdrawalsDisabled() external view returns (bool); /// @notice Disables withdrawals and claims function setWithdrawalsDisabled(bool _disabled) external; } interface IStrategy { struct Strategy { address strategy; bool isActive; } /// @notice Returns id of the withdraw order processed, and amount immediately minted function withdraw(uint256 amount, address token, address owner) external returns (uint256, uint256); /// @notice Returns csETH mining after user claims past unbonding period function claim(uint256 id, address owner, bytes memory data) external returns (uint256); /// @notice Whether the strategy supports withdraws function isUnstakingActive() external view returns (bool); /// @notice Whether the strategy supports claiming the provided token function isValidToken(address token) external view returns (bool); /// @notice Returns the claimable status of a given unstake order, true if claimable, false if not function getClaimableStatus(uint256 id) external view returns (bool); /// @notice Returns the amount of base tokens on a given order /// @dev If order is claimed, but return zero function getAmountTokenOrder(uint256 id) external view returns (uint256); /// @notice Exchanges amount of liquid tokens to ETH at current exchange rate /// @dev Assumed 1e18 precision otherwise the strategy must account for it function exchangeLiquidTokens(uint256 amount) external view returns (uint256); } contract DepositsManager is IDepositsManager, UUPSUpgradeable, PausableUpgradeable, ReentrancyGuardUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; /// @notice ClayStack's default list of access-control roles. bytes32 private constant TIMELOCK_ROLE = keccak256("TIMELOCK_ROLE"); bytes32 private constant TIMELOCK_UPGRADES_ROLE = keccak256("TIMELOCK_UPGRADES_ROLE"); bytes32 private constant CS_SERVICE_ROLE = keccak256("CS_SERVICE_ROLE"); uint256 private constant MAX_DECIMALS = 1e18; /// @notice RoleManager instance. IRoleManager private roleManager; /// @notice instance of clayMain contract. IClayMain private clayMain; /// @notice Maps liquid token to strategy struct mapping(address => IStrategy.Strategy) public strategies; /// @notice Mapping of unstaking withdraw order id to struct. mapping(uint256 => WithdrawOrder) public withdrawOrders; /// @notice maps user to the list of claims they have mapping(address => uint256[]) public userWithdrawIds; /// @notice Linear incremental order nonce. Increases by one after each withdraw request. uint256 public orderNonce; /// @notice Check if the msg.sender has permission. /// @param _roleName : bytes32 hash of the role. modifier onlyRole(bytes32 _roleName) { _onlyRole(_roleName); _; } /// @notice Initializes the contract's state vars. /// @param _roleManager : Address of ClayStack's role manager contract. /// @param _clayMain : Address of ClayStack's main contract. function initialize(address _roleManager, address _clayMain) external initializer onlyProxy { require(_roleManager != address(0), "Invalid roleManager address"); require(_clayMain != address(0), "Invalid clayMain address"); __Pausable_init(); __ReentrancyGuard_init(); __UUPSUpgradeable_init(); roleManager = IRoleManager(_roleManager); clayMain = IClayMain(_clayMain); } /** USER OPERATIONS **/ /// @notice Starts withdraw order of all given liquid token triggering strategy. /// @param _token - list of address of token to be deposited. /// @param _amount - list of amount of token to be deposited. /// @param _delegateTo - address of delegate to receive the tokens. /// @return bool on success. function withdrawAll( address[] calldata _token, uint256[] calldata _amount, address _delegateTo ) external whenNotPaused nonReentrant returns (bool) { require(_token.length != 0 && _token.length == _amount.length, "Invalid param lengths"); for (uint256 i = 0; i < _token.length; i++) { _withdraw(_token[i], _amount[i], _delegateTo); } return true; } /// @notice Starts withdraw order of liquid token triggering strategy /// @param _token - address of token to be deposited. /// @param _amount - amount of token to be deposited. /// @param _delegateTo - address of delegate to receive the tokens. /// @return deposit order id. function withdraw( address _token, uint256 _amount, address _delegateTo ) external whenNotPaused nonReentrant returns (uint256) { return _withdraw(_token, _amount, _delegateTo); } /// @notice Internal implementation to starts withdraw order of liquid token triggering strategy /// @param _token - address of token to be deposited. /// @param _amount - amount of token to be deposited. /// @param _delegateTo - address of delegate to receive the tokens. /// @return deposit order id. function _withdraw(address _token, uint256 _amount, address _delegateTo) internal returns (uint256) { require(_token != address(0), "Invalid token"); require(_amount != 0, "Zero amount"); require(strategies[_token].isActive, "Strategy inactive"); IStrategy strategy = IStrategy(strategies[_token].strategy); require(strategy.isUnstakingActive(), "Strategy withdrawals not enabled"); // Transfer tokens to strategy if (_delegateTo == address(0)) { _delegateTo = msg.sender; } IERC20Upgradeable token = IERC20Upgradeable(_token); require(token.balanceOf(msg.sender) >= _amount, "Insufficient balance"); token.safeTransferFrom(msg.sender, address(strategy), _amount); // Start withdraw (uint256 id, uint256 amountCsETH) = strategy.withdraw(_amount, _token, _delegateTo); // Create Order uint256 orderId = ++orderNonce; uint256 startTime = block.timestamp; withdrawOrders[orderId] = WithdrawOrder({ token: _token, owner: _delegateTo, id: id, amount: _amount, amountCsETH: amountCsETH, startTime: startTime, isClaimed: id == 0 // If id is 0, then it's a direct withdraw }); userWithdrawIds[_delegateTo].push(orderId); emit LogWithdraw(_delegateTo, _token, orderId, id, _amount, amountCsETH, startTime); return orderId; } /// @notice Allows the user to claim several orders at once. /// @param _orderIds - array of number of ids issued at withdraw() /// @param _data - metadata for claims. /// @return Bool confirmation of transaction function claim( uint256[] calldata _orderIds, bytes[] memory _data ) external whenNotPaused nonReentrant returns (bool) { require(_orderIds.length == _data.length, "Param length mismatch"); for (uint256 i = 0; i < _orderIds.length; i++) { uint256 id = _orderIds[i]; WithdrawOrder memory order = withdrawOrders[id]; require(!order.isClaimed, "Already claimed"); require(strategies[order.token].strategy != address(0), "Strategy does not exist for this order token"); // Claim from strategy IStrategy strategy = IStrategy(strategies[order.token].strategy); uint256 amountCsETH = strategy.claim(order.id, order.owner, _data[i]); require(amountCsETH != 0, "csETH mint failed"); withdrawOrders[id].amountCsETH = amountCsETH; withdrawOrders[id].isClaimed = true; emit LogClaim(order.owner, id, order.amount, amountCsETH); } return true; } /** VIEWS **/ /// @notice Returns order info with calculated values /// @param _orderId - id of the order. /// @return order UserWithdrawOrderInfo struct. function getOrder(uint256 _orderId) public view returns (UserWithdrawOrderInfo memory) { WithdrawOrder memory order = withdrawOrders[_orderId]; require(strategies[order.token].strategy != address(0), "Strategy does not exist for this order token"); // Determine status Status status; IStrategy strategy = IStrategy(strategies[order.token].strategy); uint256 amountCsETH = order.amountCsETH; if (order.isClaimed) { status = Status.Claimed; } else { bool isClaimable = strategy.getClaimableStatus(order.id); if (isClaimable) { status = Status.Claimable; } else { status = Status.Unbonding; } // Calculate csETH value uint256 ethValue = strategy.getAmountTokenOrder(order.id); amountCsETH = clayMain.exchangeToken(ethValue); } return UserWithdrawOrderInfo({ token: order.token, orderId: _orderId, amount: order.amount, amountCsETH: amountCsETH, startTime: order.startTime, status: status }); } /// @notice Returns the given page of the withdraw orders in descending order /// @dev Max 10 results starting at page 0 /// @param _user - Address of user. /// @param _page - Page to query. /// @return info Array for struct of user withdraw orders /// @return timeStamp current time of current chain /// @return totalPages supported for given user. function getUserOrders( address _user, uint256 _page ) external view returns (UserWithdrawOrderInfo[] memory, uint256, uint256) { UserWithdrawOrderInfo[] memory info = new UserWithdrawOrderInfo[](10); uint256 pageSize = 10; uint256 length = userWithdrawIds[_user].length; uint256 totalPages = length / pageSize; if (length > 0 && length % pageSize == 0) { totalPages--; } if (_page <= totalPages && length != 0) { for (uint256 i = 0; i < pageSize; i++) { uint256 index = length - _page * pageSize - i - 1; uint256 orderId = userWithdrawIds[_user][index]; info[i] = getOrder(orderId); if (index == 0) break; } } return (info, block.timestamp, totalPages); } /// @notice Returns the current exchange rate from strategy /// @param _token - Liquid token to be withdrawn. /// @return Exchange Rate token to ETH, Slashing occurred. function getExchangeRate(address _token) external view returns (uint256) { IStrategy strategy = IStrategy(strategies[_token].strategy); return strategy.exchangeLiquidTokens(MAX_DECIMALS); } /** ADMIN **/ /// @notice Adds new liquid strategy contract /// @dev Token address is required given strategies may have multiple tokens /// @param _strategy Contract address implementing IStrategy /// @param _token Address of token for which strategy is being added function addStrategy(address _strategy, address _token) external nonReentrant onlyRole(TIMELOCK_ROLE) { require(_strategy != address(0), "Invalid strategy"); require(strategies[_token].strategy == address(0), "Strategy already set"); IStrategy strategy = IStrategy(_strategy); require(strategy.isValidToken(_token), "Invalid token in strategy"); strategies[_token] = IStrategy.Strategy({strategy: _strategy, isActive: true}); } /// @notice Updates liquid strategy contract /// @param _token Address of token for which strategy is being updated /// @param _isActive whether to enable strategy function updateStrategy(address _token, bool _isActive) external nonReentrant onlyRole(TIMELOCK_ROLE) { require(_token != address(0), "Invalid token in strategy"); require(strategies[_token].strategy != address(0), "Strategy does not exist for this token"); strategies[_token].isActive = _isActive; } /** SUPPORT **/ /// @notice Triggers stopped state. function pause() external onlyRole(CS_SERVICE_ROLE) whenNotPaused { _pause(); } /// @notice Returns to normal state. function unpause() external onlyRole(CS_SERVICE_ROLE) whenPaused { _unpause(); } /// @notice Checks caller has the given `_roleName` or not. /// @param _roleName supported by RoleManager function _onlyRole(bytes32 _roleName) internal view { require(roleManager.checkRole(_roleName, msg.sender), "Auth Failed"); } /// @notice Upgrade the implementation of the proxy to `_newImplementation`. /// @param _newImplementation : Address of new implementation of the contract function upgradeTo( address _newImplementation ) external virtual override onlyRole(TIMELOCK_UPGRADES_ROLE) onlyProxy { _authorizeUpgrade(_newImplementation); _upgradeTo(_newImplementation); } /// @notice Function that should revert when `msg.sender` is not authorized to upgrade the contract or /// @param _newImplementation : Address of new implementation of the contract. function _authorizeUpgrade(address _newImplementation) internal virtual override onlyRole(TIMELOCK_UPGRADES_ROLE) { require(_newImplementation.code.length > 0, "!contract"); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","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":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountCsETH","type":"uint256"}],"name":"LogClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountCsETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"}],"name":"LogWithdraw","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":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"internalType":"address","name":"_strategy","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"addStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_orderIds","type":"uint256[]"},{"internalType":"bytes[]","name":"_data","type":"bytes[]"}],"name":"claim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"}],"name":"getOrder","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountCsETH","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"enum IDepositsManager.Status","name":"status","type":"uint8"}],"internalType":"struct IDepositsManager.UserWithdrawOrderInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_page","type":"uint256"}],"name":"getUserOrders","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountCsETH","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"enum IDepositsManager.Status","name":"status","type":"uint8"}],"internalType":"struct IDepositsManager.UserWithdrawOrderInfo[]","name":"","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_roleManager","type":"address"},{"internalType":"address","name":"_clayMain","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"orderNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"strategies","outputs":[{"internalType":"address","name":"strategy","type":"address"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_isActive","type":"bool"}],"name":"updateStrategy","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":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userWithdrawIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_delegateTo","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_token","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"},{"internalType":"address","name":"_delegateTo","type":"address"}],"name":"withdrawAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawOrders","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountCsETH","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"bool","name":"isClaimed","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523060805234801561001457600080fd5b50608051612d0861005a60003960008181610c0501528181610c4501528181610db401528181610df401528181610f9301528181610fd3015261104b0152612d086000f3fe6080604052600436106101145760003560e01c80633f4ba83a116100a057806369328dec1161006457806369328dec146103a757806374492894146103c75780638456cb59146103e7578063d09ef241146103fc578063efb7601d1461042957600080fd5b80633f4ba83a14610332578063485cc955146103475780634f1ef2861461036757806352d1902d1461037a5780635c975abb1461038f57600080fd5b806316f8de89116100e757806316f8de891461024a578063180669431461026f5780632b8bb70c146102915780633659cfe6146102b157806339ebf823146102d157600080fd5b8063020fdae214610119578063028743001461015157806304faa167146101fa5780631208cfc81461022a575b600080fd5b34801561012557600080fd5b506101396101343660046124e8565b610449565b6040516101489392919061258a565b60405180910390f35b34801561015d57600080fd5b506101b861016c3660046125e1565b60fe6020526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b0395861696959094169492939192909160ff1687565b604080516001600160a01b039889168152979096166020880152948601939093526060850191909152608084015260a0830152151560c082015260e001610148565b34801561020657600080fd5b5061021a6102153660046126fd565b6105bf565b6040519015158152602001610148565b34801561023657600080fd5b5061021a6102453660046127e9565b6108ca565b34801561025657600080fd5b506102616101005481565b604051908152602001610148565b34801561027b57600080fd5b5061028f61028a36600461286a565b6109ad565b005b34801561029d57600080fd5b506102616102ac3660046124e8565b610ba0565b3480156102bd57600080fd5b5061028f6102cc36600461289d565b610bd1565b3480156102dd57600080fd5b506103136102ec36600461289d565b60fd602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610148565b34801561033e57600080fd5b5061028f610cad565b34801561035357600080fd5b5061028f61036236600461286a565b610cea565b61028f6103753660046128b8565b610f89565b34801561038657600080fd5b5061026161103e565b34801561039b57600080fd5b5060975460ff1661021a565b3480156103b357600080fd5b506102616103c2366004612906565b6110f1565b3480156103d357600080fd5b5061028f6103e2366004612950565b61111a565b3480156103f357600080fd5b5061028f61124b565b34801561040857600080fd5b5061041c6104173660046125e1565b611285565b6040516101489190612987565b34801561043557600080fd5b5061026161044436600461289d565b611530565b60408051600a80825261016082019092526060916000918291829190816020015b61047261247d565b81526020019060019003908161046a5750506001600160a01b038716600090815260ff6020526040812054919250600a91906104ae83836129c1565b90506000821180156104c757506104c583836129d5565b155b156104da57806104d6816129e9565b9150505b8088111580156104e957508115155b156105ae5760005b838110156105ac576000600182610508878d612a00565b6105129087612a17565b61051c9190612a17565b6105269190612a17565b6001600160a01b038c16600090815260ff60205260408120805492935090918390811061055557610555612a2a565b9060005260206000200154905061056b81611285565b87848151811061057d5761057d612a2a565b6020026020010181905250816000036105975750506105ac565b505080806105a490612a40565b9150506104f1565b505b929842985092965091945050505050565b60006105c96115b5565b6105d16115fd565b8151831461061e5760405162461bcd60e51b81526020600482015260156024820152740a0c2e4c2da40d8cadccee8d040dad2e6dac2e8c6d605b1b60448201526064015b60405180910390fd5b60005b838110156108b457600085858381811061063d5761063d612a2a565b60209081029290920135600081815260fe8452604090819020815160e08101835281546001600160a01b039081168252600183015416958101959095526002810154918501919091526003810154606085015260048101546080850152600581015460a08501526006015460ff1615801560c085015290935090506106f65760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606401610615565b80516001600160a01b03908116600090815260fd60205260409020541661072f5760405162461bcd60e51b815260040161061590612a59565b80516001600160a01b03908116600090815260fd6020908152604080832054908501519185015189519190941693849263ecbd45af929091908b908a90811061077a5761077a612a2a565b60200260200101516040518463ffffffff1660e01b81526004016107a093929190612af5565b6020604051808303816000875af11580156107bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e39190612b1f565b9050806000036108295760405162461bcd60e51b815260206004820152601160248201527018dcd15512081b5a5b9d0819985a5b1959607a1b6044820152606401610615565b600084815260fe602090815260409182902060048101849055600601805460ff19166001179055848101516060860151835190815291820184905286926001600160a01b03909116917f24c74c1d14438a5ca477f564bcc66fd23d5a21e6773a14a0efbbe111b92090f9910160405180910390a35050505080806108ac90612a40565b915050610621565b50600190506108c3600160c955565b9392505050565b60006108d46115b5565b6108dc6115fd565b84158015906108ea57508483145b61092e5760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420706172616d206c656e6774687360581b6044820152606401610615565b60005b858110156109955761098287878381811061094e5761094e612a2a565b9050602002016020810190610963919061289d565b86868481811061097557610975612a2a565b905060200201358561165d565b508061098d81612a40565b915050610931565b50600190506109a4600160c955565b95945050505050565b6109b56115fd565b7ff66846415d2bf9eabda9e84793ff9c0ea96d87f50fc41e66aa16469c6a442f056109df81611b4b565b6001600160a01b038316610a285760405162461bcd60e51b815260206004820152601060248201526f496e76616c696420737472617465677960801b6044820152606401610615565b6001600160a01b03828116600090815260fd60205260409020541615610a875760405162461bcd60e51b815260206004820152601460248201527314dd1c985d1959de48185b1c9958591e481cd95d60621b6044820152606401610615565b60405163c187645360e01b81526001600160a01b03838116600483015284919082169063c187645390602401602060405180830381865afa158015610ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af49190612b38565b610b3c5760405162461bcd60e51b8152602060048201526019602482015278496e76616c696420746f6b656e20696e20737472617465677960381b6044820152606401610615565b50506040805180820182526001600160a01b03808516825260016020808401918252858316600090815260fd909152939093209151825493511515600160a01b026001600160a81b0319909416911617919091179055610b9c600160c955565b5050565b60ff6020528160005260406000208181548110610bbc57600080fd5b90600052602060002001600091509150505481565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b1610bfb81611b4b565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610c435760405162461bcd60e51b815260040161061590612b55565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610c75611bf8565b6001600160a01b031614610c9b5760405162461bcd60e51b815260040161061590612ba1565b610ca482611c14565b610b9c82611c84565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc8610cd781611b4b565b610cdf611cc4565b610ce7611d0d565b50565b600054610100900460ff1615808015610d0a5750600054600160ff909116105b80610d245750303b158015610d24575060005460ff166001145b610d875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610615565b6000805460ff191660011790558015610daa576000805461ff0019166101001790555b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610df25760405162461bcd60e51b815260040161061590612b55565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610e24611bf8565b6001600160a01b031614610e4a5760405162461bcd60e51b815260040161061590612ba1565b6001600160a01b038316610ea05760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726f6c654d616e61676572206164647265737300000000006044820152606401610615565b6001600160a01b038216610ef65760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420636c61794d61696e206164647265737300000000000000006044820152606401610615565b610efe611d5f565b610f06611d8e565b610f0e611dbd565b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc8054928516929091169190911790558015610f84576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fd15760405162461bcd60e51b815260040161061590612b55565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611003611bf8565b6001600160a01b0316146110295760405162461bcd60e51b815260040161061590612ba1565b61103282611c14565b610b9c82826001611de4565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146110de5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610615565b50600080516020612c8c83398151915290565b60006110fb6115b5565b6111036115fd565b61110e84848461165d565b90506108c3600160c955565b6111226115fd565b7ff66846415d2bf9eabda9e84793ff9c0ea96d87f50fc41e66aa16469c6a442f0561114c81611b4b565b6001600160a01b03831661119e5760405162461bcd60e51b8152602060048201526019602482015278496e76616c696420746f6b656e20696e20737472617465677960381b6044820152606401610615565b6001600160a01b03838116600090815260fd6020526040902054166112145760405162461bcd60e51b815260206004820152602660248201527f537472617465677920646f6573206e6f7420657869737420666f722074686973604482015265103a37b5b2b760d11b6064820152608401610615565b506001600160a01b038216600090815260fd60205260409020805460ff60a01b1916600160a01b83151502179055600160c9555050565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc861127581611b4b565b61127d6115b5565b610ce7611f4f565b61128d61247d565b600082815260fe60209081526040808320815160e08101835281546001600160a01b0390811680835260018401548216838701526002840154838601526003840154606084015260048401546080840152600584015460a084015260069093015460ff16151560c083015291855260fd9093529220549091166113225760405162461bcd60e51b815260040161061590612a59565b80516001600160a01b03908116600090815260fd6020526040812054608084015160c0850151929391909116911561135d57600292506114d4565b604080850151905163c21bba3960e01b81526000916001600160a01b0385169163c21bba39916113939160040190815260200190565b602060405180830381865afa1580156113b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d49190612b38565b905080156113e557600193506113ea565b600093505b604080860151905163e7397bed60e01b81526000916001600160a01b0386169163e7397bed916114209160040190815260200190565b602060405180830381865afa15801561143d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114619190612b1f565b60fc54604051638f78c31160e01b8152600481018390529192506001600160a01b031690638f78c31190602401602060405180830381865afa1580156114ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114cf9190612b1f565b925050505b6040518060c0016040528085600001516001600160a01b03168152602001878152602001856060015181526020018281526020018560a00151815260200184600281111561152457611524612512565b90529695505050505050565b6001600160a01b03818116600090815260fd60205260408082205490516304a68c7b60e21b8152670de0b6b3a7640000600482015291921690819063129a31ec90602401602060405180830381865afa158015611591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c39190612b1f565b60975460ff16156115fb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610615565b565b600260c9540361164f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610615565b600260c955565b600160c955565b60006001600160a01b0384166116a55760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610615565b826000036116e35760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b6044820152606401610615565b6001600160a01b038416600090815260fd6020526040902054600160a01b900460ff166117465760405162461bcd60e51b8152602060048201526011602482015270537472617465677920696e61637469766560781b6044820152606401610615565b6001600160a01b03808516600090815260fd6020908152604091829020548251631a5f777960e31b81529251931692839263d2fbbbc89260048083019391928290030181865afa15801561179e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c29190612b38565b61180e5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779207769746864726177616c73206e6f7420656e61626c65646044820152606401610615565b6001600160a01b038316611820573392505b6040516370a0823160e01b8152336004820152859085906001600160a01b038316906370a0823190602401602060405180830381865afa158015611868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188c9190612b1f565b10156118d15760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610615565b6118e66001600160a01b038216338488611f8c565b604051632d182be560e21b8152600481018690526001600160a01b0387811660248301528581166044830152600091829185169063b460af949060640160408051808303816000875af1158015611941573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119659190612bed565b9150915060006101006000815461197b90612a40565b919050819055905060004290506040518060e001604052808b6001600160a01b03168152602001896001600160a01b031681526020018581526020018a815260200184815260200182815260200185600014151581525060fe600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555090505060ff6000896001600160a01b03166001600160a01b03168152602001908152602001600020829080600181540180825580915050600190039060005260206000200160009091909190915055818a6001600160a01b0316896001600160a01b03167f0c298f29f5da07c8a72980563748767b071726d3b6ecedb161c057eda191516c878d8887604051611b36949392919093845260208401929092526040830152606082015260800190565b60405180910390a45098975050505050505050565b60fb546040516312d9a6ad60e01b8152600481018390523360248201526001600160a01b03909116906312d9a6ad90604401602060405180830381865afa158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe9190612b38565b610ce75760405162461bcd60e51b815260206004820152600b60248201526a105d5d1a0811985a5b195960aa1b6044820152606401610615565b600080516020612c8c833981519152546001600160a01b031690565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b1611c3e81611b4b565b6000826001600160a01b03163b11610b9c5760405162461bcd60e51b81526020600482015260096024820152680858dbdb9d1c9858dd60ba1b6044820152606401610615565b611c8d81611fec565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60975460ff166115fb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610615565b611d15611cc4565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600054610100900460ff16611d865760405162461bcd60e51b815260040161061590612c11565b6115fb612088565b600054610100900460ff16611db55760405162461bcd60e51b815260040161061590612c11565b6115fb6120bb565b600054610100900460ff166115fb5760405162461bcd60e51b815260040161061590612c11565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611e1757610f8483611fec565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e71575060408051601f3d908101601f19168201909252611e6e91810190612b1f565b60015b611ed45760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610615565b600080516020612c8c8339815191528114611f435760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610615565b50610f848383836120e2565b611f576115b5565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611d423390565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611fe6908590612107565b50505050565b6001600160a01b0381163b6120595760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610615565b600080516020612c8c83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166120af5760405162461bcd60e51b815260040161061590612c11565b6097805460ff19169055565b600054610100900460ff166116565760405162461bcd60e51b815260040161061590612c11565b6120eb83611c84565b6000825111806120f85750805b15610f8457611fe683836121d9565b600061215c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122cf9092919063ffffffff16565b805190915015610f84578080602001905181019061217a9190612b38565b610f845760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610615565b60606001600160a01b0383163b6122415760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610615565b600080846001600160a01b03168460405161225c9190612c5c565b600060405180830381855af49150503d8060008114612297576040519150601f19603f3d011682016040523d82523d6000602084013e61229c565b606091505b50915091506122c48282604051806060016040528060278152602001612cac602791396122e6565b925050505b92915050565b60606122de84846000856122ff565b949350505050565b606083156122f55750816108c3565b6108c383836123da565b6060824710156123605760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610615565b600080866001600160a01b0316858760405161237c9190612c5c565b60006040518083038185875af1925050503d80600081146123b9576040519150601f19603f3d011682016040523d82523d6000602084013e6123be565b606091505b50915091506123cf87838387612404565b979650505050505050565b8151156123ea5781518083602001fd5b8060405162461bcd60e51b81526004016106159190612c78565b6060831561247357825160000361246c576001600160a01b0385163b61246c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610615565b50816122de565b6122de83836123da565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600060028111156124c7576124c7612512565b905290565b80356001600160a01b03811681146124e357600080fd5b919050565b600080604083850312156124fb57600080fd5b612504836124cc565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0381511682526020810151602083015260408101516040830152606081015160608301526080810151608083015260a08101516003811061257f57634e487b7160e01b600052602160045260246000fd5b8060a0840152505050565b606080825284519082018190526000906020906080840190828801845b828110156125cd576125ba848351612528565b60c09390930192908401906001016125a7565b505050908301949094525060400152919050565b6000602082840312156125f357600080fd5b5035919050565b60008083601f84011261260c57600080fd5b50813567ffffffffffffffff81111561262457600080fd5b6020830191508360208260051b850101111561263f57600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561268557612685612646565b604052919050565b600082601f83011261269e57600080fd5b813567ffffffffffffffff8111156126b8576126b8612646565b6126cb601f8201601f191660200161265c565b8181528460208386010111156126e057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006040848603121561271257600080fd5b833567ffffffffffffffff8082111561272a57600080fd5b612736878388016125fa565b909550935060209150858201358181111561275057600080fd5b8601601f8101881361276157600080fd5b80358281111561277357612773612646565b8060051b61278285820161265c565b918252828101850191858101908b84111561279c57600080fd5b86850192505b838310156127d8578235868111156127ba5760008081fd5b6127c88d898389010161268d565b83525091860191908601906127a2565b809750505050505050509250925092565b60008060008060006060868803121561280157600080fd5b853567ffffffffffffffff8082111561281957600080fd5b61282589838a016125fa565b9097509550602088013591508082111561283e57600080fd5b5061284b888289016125fa565b909450925061285e9050604087016124cc565b90509295509295909350565b6000806040838503121561287d57600080fd5b612886836124cc565b9150612894602084016124cc565b90509250929050565b6000602082840312156128af57600080fd5b6108c3826124cc565b600080604083850312156128cb57600080fd5b6128d4836124cc565b9150602083013567ffffffffffffffff8111156128f057600080fd5b6128fc8582860161268d565b9150509250929050565b60008060006060848603121561291b57600080fd5b612924846124cc565b925060208401359150612939604085016124cc565b90509250925092565b8015158114610ce757600080fd5b6000806040838503121561296357600080fd5b61296c836124cc565b9150602083013561297c81612942565b809150509250929050565b60c081016122c98284612528565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000826129d0576129d0612995565b500490565b6000826129e4576129e4612995565b500690565b6000816129f8576129f86129ab565b506000190190565b80820281158282048414176122c9576122c96129ab565b818103818111156122c9576122c96129ab565b634e487b7160e01b600052603260045260246000fd5b600060018201612a5257612a526129ab565b5060010190565b6020808252602c908201527f537472617465677920646f6573206e6f7420657869737420666f72207468697360408201526b1037b93232b9103a37b5b2b760a11b606082015260800190565b60005b83811015612ac0578181015183820152602001612aa8565b50506000910152565b60008151808452612ae1816020860160208601612aa5565b601f01601f19169290920160200192915050565b8381526001600160a01b03831660208201526060604082018190526000906109a490830184612ac9565b600060208284031215612b3157600080fd5b5051919050565b600060208284031215612b4a57600080fd5b81516108c381612942565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b60008060408385031215612c0057600080fd5b505080516020909101519092909150565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008251612c6e818460208701612aa5565b9190910192915050565b6020815260006108c36020830184612ac956fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201b26359652ac3cac02e785727b59c67ed9e375db191c888c5ed820f18886304064736f6c63430008120033
Deployed Bytecode
0x6080604052600436106101145760003560e01c80633f4ba83a116100a057806369328dec1161006457806369328dec146103a757806374492894146103c75780638456cb59146103e7578063d09ef241146103fc578063efb7601d1461042957600080fd5b80633f4ba83a14610332578063485cc955146103475780634f1ef2861461036757806352d1902d1461037a5780635c975abb1461038f57600080fd5b806316f8de89116100e757806316f8de891461024a578063180669431461026f5780632b8bb70c146102915780633659cfe6146102b157806339ebf823146102d157600080fd5b8063020fdae214610119578063028743001461015157806304faa167146101fa5780631208cfc81461022a575b600080fd5b34801561012557600080fd5b506101396101343660046124e8565b610449565b6040516101489392919061258a565b60405180910390f35b34801561015d57600080fd5b506101b861016c3660046125e1565b60fe6020526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b0395861696959094169492939192909160ff1687565b604080516001600160a01b039889168152979096166020880152948601939093526060850191909152608084015260a0830152151560c082015260e001610148565b34801561020657600080fd5b5061021a6102153660046126fd565b6105bf565b6040519015158152602001610148565b34801561023657600080fd5b5061021a6102453660046127e9565b6108ca565b34801561025657600080fd5b506102616101005481565b604051908152602001610148565b34801561027b57600080fd5b5061028f61028a36600461286a565b6109ad565b005b34801561029d57600080fd5b506102616102ac3660046124e8565b610ba0565b3480156102bd57600080fd5b5061028f6102cc36600461289d565b610bd1565b3480156102dd57600080fd5b506103136102ec36600461289d565b60fd602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b039093168352901515602083015201610148565b34801561033e57600080fd5b5061028f610cad565b34801561035357600080fd5b5061028f61036236600461286a565b610cea565b61028f6103753660046128b8565b610f89565b34801561038657600080fd5b5061026161103e565b34801561039b57600080fd5b5060975460ff1661021a565b3480156103b357600080fd5b506102616103c2366004612906565b6110f1565b3480156103d357600080fd5b5061028f6103e2366004612950565b61111a565b3480156103f357600080fd5b5061028f61124b565b34801561040857600080fd5b5061041c6104173660046125e1565b611285565b6040516101489190612987565b34801561043557600080fd5b5061026161044436600461289d565b611530565b60408051600a80825261016082019092526060916000918291829190816020015b61047261247d565b81526020019060019003908161046a5750506001600160a01b038716600090815260ff6020526040812054919250600a91906104ae83836129c1565b90506000821180156104c757506104c583836129d5565b155b156104da57806104d6816129e9565b9150505b8088111580156104e957508115155b156105ae5760005b838110156105ac576000600182610508878d612a00565b6105129087612a17565b61051c9190612a17565b6105269190612a17565b6001600160a01b038c16600090815260ff60205260408120805492935090918390811061055557610555612a2a565b9060005260206000200154905061056b81611285565b87848151811061057d5761057d612a2a565b6020026020010181905250816000036105975750506105ac565b505080806105a490612a40565b9150506104f1565b505b929842985092965091945050505050565b60006105c96115b5565b6105d16115fd565b8151831461061e5760405162461bcd60e51b81526020600482015260156024820152740a0c2e4c2da40d8cadccee8d040dad2e6dac2e8c6d605b1b60448201526064015b60405180910390fd5b60005b838110156108b457600085858381811061063d5761063d612a2a565b60209081029290920135600081815260fe8452604090819020815160e08101835281546001600160a01b039081168252600183015416958101959095526002810154918501919091526003810154606085015260048101546080850152600581015460a08501526006015460ff1615801560c085015290935090506106f65760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606401610615565b80516001600160a01b03908116600090815260fd60205260409020541661072f5760405162461bcd60e51b815260040161061590612a59565b80516001600160a01b03908116600090815260fd6020908152604080832054908501519185015189519190941693849263ecbd45af929091908b908a90811061077a5761077a612a2a565b60200260200101516040518463ffffffff1660e01b81526004016107a093929190612af5565b6020604051808303816000875af11580156107bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e39190612b1f565b9050806000036108295760405162461bcd60e51b815260206004820152601160248201527018dcd15512081b5a5b9d0819985a5b1959607a1b6044820152606401610615565b600084815260fe602090815260409182902060048101849055600601805460ff19166001179055848101516060860151835190815291820184905286926001600160a01b03909116917f24c74c1d14438a5ca477f564bcc66fd23d5a21e6773a14a0efbbe111b92090f9910160405180910390a35050505080806108ac90612a40565b915050610621565b50600190506108c3600160c955565b9392505050565b60006108d46115b5565b6108dc6115fd565b84158015906108ea57508483145b61092e5760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420706172616d206c656e6774687360581b6044820152606401610615565b60005b858110156109955761098287878381811061094e5761094e612a2a565b9050602002016020810190610963919061289d565b86868481811061097557610975612a2a565b905060200201358561165d565b508061098d81612a40565b915050610931565b50600190506109a4600160c955565b95945050505050565b6109b56115fd565b7ff66846415d2bf9eabda9e84793ff9c0ea96d87f50fc41e66aa16469c6a442f056109df81611b4b565b6001600160a01b038316610a285760405162461bcd60e51b815260206004820152601060248201526f496e76616c696420737472617465677960801b6044820152606401610615565b6001600160a01b03828116600090815260fd60205260409020541615610a875760405162461bcd60e51b815260206004820152601460248201527314dd1c985d1959de48185b1c9958591e481cd95d60621b6044820152606401610615565b60405163c187645360e01b81526001600160a01b03838116600483015284919082169063c187645390602401602060405180830381865afa158015610ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af49190612b38565b610b3c5760405162461bcd60e51b8152602060048201526019602482015278496e76616c696420746f6b656e20696e20737472617465677960381b6044820152606401610615565b50506040805180820182526001600160a01b03808516825260016020808401918252858316600090815260fd909152939093209151825493511515600160a01b026001600160a81b0319909416911617919091179055610b9c600160c955565b5050565b60ff6020528160005260406000208181548110610bbc57600080fd5b90600052602060002001600091509150505481565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b1610bfb81611b4b565b6001600160a01b037f00000000000000000000000082e0707abd5f6e25c06af00d7dc7cf1939b19c92163003610c435760405162461bcd60e51b815260040161061590612b55565b7f00000000000000000000000082e0707abd5f6e25c06af00d7dc7cf1939b19c926001600160a01b0316610c75611bf8565b6001600160a01b031614610c9b5760405162461bcd60e51b815260040161061590612ba1565b610ca482611c14565b610b9c82611c84565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc8610cd781611b4b565b610cdf611cc4565b610ce7611d0d565b50565b600054610100900460ff1615808015610d0a5750600054600160ff909116105b80610d245750303b158015610d24575060005460ff166001145b610d875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610615565b6000805460ff191660011790558015610daa576000805461ff0019166101001790555b6001600160a01b037f00000000000000000000000082e0707abd5f6e25c06af00d7dc7cf1939b19c92163003610df25760405162461bcd60e51b815260040161061590612b55565b7f00000000000000000000000082e0707abd5f6e25c06af00d7dc7cf1939b19c926001600160a01b0316610e24611bf8565b6001600160a01b031614610e4a5760405162461bcd60e51b815260040161061590612ba1565b6001600160a01b038316610ea05760405162461bcd60e51b815260206004820152601b60248201527f496e76616c696420726f6c654d616e61676572206164647265737300000000006044820152606401610615565b6001600160a01b038216610ef65760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420636c61794d61696e206164647265737300000000000000006044820152606401610615565b610efe611d5f565b610f06611d8e565b610f0e611dbd565b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc8054928516929091169190911790558015610f84576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b037f00000000000000000000000082e0707abd5f6e25c06af00d7dc7cf1939b19c92163003610fd15760405162461bcd60e51b815260040161061590612b55565b7f00000000000000000000000082e0707abd5f6e25c06af00d7dc7cf1939b19c926001600160a01b0316611003611bf8565b6001600160a01b0316146110295760405162461bcd60e51b815260040161061590612ba1565b61103282611c14565b610b9c82826001611de4565b6000306001600160a01b037f00000000000000000000000082e0707abd5f6e25c06af00d7dc7cf1939b19c9216146110de5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610615565b50600080516020612c8c83398151915290565b60006110fb6115b5565b6111036115fd565b61110e84848461165d565b90506108c3600160c955565b6111226115fd565b7ff66846415d2bf9eabda9e84793ff9c0ea96d87f50fc41e66aa16469c6a442f0561114c81611b4b565b6001600160a01b03831661119e5760405162461bcd60e51b8152602060048201526019602482015278496e76616c696420746f6b656e20696e20737472617465677960381b6044820152606401610615565b6001600160a01b03838116600090815260fd6020526040902054166112145760405162461bcd60e51b815260206004820152602660248201527f537472617465677920646f6573206e6f7420657869737420666f722074686973604482015265103a37b5b2b760d11b6064820152608401610615565b506001600160a01b038216600090815260fd60205260409020805460ff60a01b1916600160a01b83151502179055600160c9555050565b7f70afc91226fba57efa6b459a2add00f29a9a7961e6eb3103074a44780ab8cdc861127581611b4b565b61127d6115b5565b610ce7611f4f565b61128d61247d565b600082815260fe60209081526040808320815160e08101835281546001600160a01b0390811680835260018401548216838701526002840154838601526003840154606084015260048401546080840152600584015460a084015260069093015460ff16151560c083015291855260fd9093529220549091166113225760405162461bcd60e51b815260040161061590612a59565b80516001600160a01b03908116600090815260fd6020526040812054608084015160c0850151929391909116911561135d57600292506114d4565b604080850151905163c21bba3960e01b81526000916001600160a01b0385169163c21bba39916113939160040190815260200190565b602060405180830381865afa1580156113b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d49190612b38565b905080156113e557600193506113ea565b600093505b604080860151905163e7397bed60e01b81526000916001600160a01b0386169163e7397bed916114209160040190815260200190565b602060405180830381865afa15801561143d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114619190612b1f565b60fc54604051638f78c31160e01b8152600481018390529192506001600160a01b031690638f78c31190602401602060405180830381865afa1580156114ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114cf9190612b1f565b925050505b6040518060c0016040528085600001516001600160a01b03168152602001878152602001856060015181526020018281526020018560a00151815260200184600281111561152457611524612512565b90529695505050505050565b6001600160a01b03818116600090815260fd60205260408082205490516304a68c7b60e21b8152670de0b6b3a7640000600482015291921690819063129a31ec90602401602060405180830381865afa158015611591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c39190612b1f565b60975460ff16156115fb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610615565b565b600260c9540361164f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610615565b600260c955565b600160c955565b60006001600160a01b0384166116a55760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b6044820152606401610615565b826000036116e35760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b6044820152606401610615565b6001600160a01b038416600090815260fd6020526040902054600160a01b900460ff166117465760405162461bcd60e51b8152602060048201526011602482015270537472617465677920696e61637469766560781b6044820152606401610615565b6001600160a01b03808516600090815260fd6020908152604091829020548251631a5f777960e31b81529251931692839263d2fbbbc89260048083019391928290030181865afa15801561179e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c29190612b38565b61180e5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779207769746864726177616c73206e6f7420656e61626c65646044820152606401610615565b6001600160a01b038316611820573392505b6040516370a0823160e01b8152336004820152859085906001600160a01b038316906370a0823190602401602060405180830381865afa158015611868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188c9190612b1f565b10156118d15760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610615565b6118e66001600160a01b038216338488611f8c565b604051632d182be560e21b8152600481018690526001600160a01b0387811660248301528581166044830152600091829185169063b460af949060640160408051808303816000875af1158015611941573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119659190612bed565b9150915060006101006000815461197b90612a40565b919050819055905060004290506040518060e001604052808b6001600160a01b03168152602001896001600160a01b031681526020018581526020018a815260200184815260200182815260200185600014151581525060fe600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555090505060ff6000896001600160a01b03166001600160a01b03168152602001908152602001600020829080600181540180825580915050600190039060005260206000200160009091909190915055818a6001600160a01b0316896001600160a01b03167f0c298f29f5da07c8a72980563748767b071726d3b6ecedb161c057eda191516c878d8887604051611b36949392919093845260208401929092526040830152606082015260800190565b60405180910390a45098975050505050505050565b60fb546040516312d9a6ad60e01b8152600481018390523360248201526001600160a01b03909116906312d9a6ad90604401602060405180830381865afa158015611b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bbe9190612b38565b610ce75760405162461bcd60e51b815260206004820152600b60248201526a105d5d1a0811985a5b195960aa1b6044820152606401610615565b600080516020612c8c833981519152546001600160a01b031690565b7fb8ea7c31de614c54f5b3938aa9732e87deb869a880ec52d4bb778c09789441b1611c3e81611b4b565b6000826001600160a01b03163b11610b9c5760405162461bcd60e51b81526020600482015260096024820152680858dbdb9d1c9858dd60ba1b6044820152606401610615565b611c8d81611fec565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60975460ff166115fb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610615565b611d15611cc4565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600054610100900460ff16611d865760405162461bcd60e51b815260040161061590612c11565b6115fb612088565b600054610100900460ff16611db55760405162461bcd60e51b815260040161061590612c11565b6115fb6120bb565b600054610100900460ff166115fb5760405162461bcd60e51b815260040161061590612c11565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611e1757610f8483611fec565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e71575060408051601f3d908101601f19168201909252611e6e91810190612b1f565b60015b611ed45760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610615565b600080516020612c8c8339815191528114611f435760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610615565b50610f848383836120e2565b611f576115b5565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611d423390565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611fe6908590612107565b50505050565b6001600160a01b0381163b6120595760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610615565b600080516020612c8c83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166120af5760405162461bcd60e51b815260040161061590612c11565b6097805460ff19169055565b600054610100900460ff166116565760405162461bcd60e51b815260040161061590612c11565b6120eb83611c84565b6000825111806120f85750805b15610f8457611fe683836121d9565b600061215c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122cf9092919063ffffffff16565b805190915015610f84578080602001905181019061217a9190612b38565b610f845760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610615565b60606001600160a01b0383163b6122415760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610615565b600080846001600160a01b03168460405161225c9190612c5c565b600060405180830381855af49150503d8060008114612297576040519150601f19603f3d011682016040523d82523d6000602084013e61229c565b606091505b50915091506122c48282604051806060016040528060278152602001612cac602791396122e6565b925050505b92915050565b60606122de84846000856122ff565b949350505050565b606083156122f55750816108c3565b6108c383836123da565b6060824710156123605760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610615565b600080866001600160a01b0316858760405161237c9190612c5c565b60006040518083038185875af1925050503d80600081146123b9576040519150601f19603f3d011682016040523d82523d6000602084013e6123be565b606091505b50915091506123cf87838387612404565b979650505050505050565b8151156123ea5781518083602001fd5b8060405162461bcd60e51b81526004016106159190612c78565b6060831561247357825160000361246c576001600160a01b0385163b61246c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610615565b50816122de565b6122de83836123da565b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600060028111156124c7576124c7612512565b905290565b80356001600160a01b03811681146124e357600080fd5b919050565b600080604083850312156124fb57600080fd5b612504836124cc565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0381511682526020810151602083015260408101516040830152606081015160608301526080810151608083015260a08101516003811061257f57634e487b7160e01b600052602160045260246000fd5b8060a0840152505050565b606080825284519082018190526000906020906080840190828801845b828110156125cd576125ba848351612528565b60c09390930192908401906001016125a7565b505050908301949094525060400152919050565b6000602082840312156125f357600080fd5b5035919050565b60008083601f84011261260c57600080fd5b50813567ffffffffffffffff81111561262457600080fd5b6020830191508360208260051b850101111561263f57600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561268557612685612646565b604052919050565b600082601f83011261269e57600080fd5b813567ffffffffffffffff8111156126b8576126b8612646565b6126cb601f8201601f191660200161265c565b8181528460208386010111156126e057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006040848603121561271257600080fd5b833567ffffffffffffffff8082111561272a57600080fd5b612736878388016125fa565b909550935060209150858201358181111561275057600080fd5b8601601f8101881361276157600080fd5b80358281111561277357612773612646565b8060051b61278285820161265c565b918252828101850191858101908b84111561279c57600080fd5b86850192505b838310156127d8578235868111156127ba5760008081fd5b6127c88d898389010161268d565b83525091860191908601906127a2565b809750505050505050509250925092565b60008060008060006060868803121561280157600080fd5b853567ffffffffffffffff8082111561281957600080fd5b61282589838a016125fa565b9097509550602088013591508082111561283e57600080fd5b5061284b888289016125fa565b909450925061285e9050604087016124cc565b90509295509295909350565b6000806040838503121561287d57600080fd5b612886836124cc565b9150612894602084016124cc565b90509250929050565b6000602082840312156128af57600080fd5b6108c3826124cc565b600080604083850312156128cb57600080fd5b6128d4836124cc565b9150602083013567ffffffffffffffff8111156128f057600080fd5b6128fc8582860161268d565b9150509250929050565b60008060006060848603121561291b57600080fd5b612924846124cc565b925060208401359150612939604085016124cc565b90509250925092565b8015158114610ce757600080fd5b6000806040838503121561296357600080fd5b61296c836124cc565b9150602083013561297c81612942565b809150509250929050565b60c081016122c98284612528565b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000826129d0576129d0612995565b500490565b6000826129e4576129e4612995565b500690565b6000816129f8576129f86129ab565b506000190190565b80820281158282048414176122c9576122c96129ab565b818103818111156122c9576122c96129ab565b634e487b7160e01b600052603260045260246000fd5b600060018201612a5257612a526129ab565b5060010190565b6020808252602c908201527f537472617465677920646f6573206e6f7420657869737420666f72207468697360408201526b1037b93232b9103a37b5b2b760a11b606082015260800190565b60005b83811015612ac0578181015183820152602001612aa8565b50506000910152565b60008151808452612ae1816020860160208601612aa5565b601f01601f19169290920160200192915050565b8381526001600160a01b03831660208201526060604082018190526000906109a490830184612ac9565b600060208284031215612b3157600080fd5b5051919050565b600060208284031215612b4a57600080fd5b81516108c381612942565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b60008060408385031215612c0057600080fd5b505080516020909101519092909150565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008251612c6e818460208701612aa5565b9190910192915050565b6020815260006108c36020830184612ac956fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201b26359652ac3cac02e785727b59c67ed9e375db191c888c5ed820f18886304064736f6c63430008120033
Deployed Bytecode Sourcemap
63661:12310:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72031:872;;;;;;;;;;-1:-1:-1;72031:872:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;64549:55;;;;;;;;;;-1:-1:-1;64549:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64549:55:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2645:15:1;;;2627:34;;2697:15;;;;2692:2;2677:18;;2670:43;2729:18;;;2722:34;;;;2787:2;2772:18;;2765:34;;;;2830:3;2815:19;;2808:35;2607:3;2859:19;;2852:35;2931:14;2924:22;2918:3;2903:19;;2896:51;2576:3;2561:19;64549:55:0;2280:673:1;69151:1043:0;;;;;;;;;;-1:-1:-1;69151:1043:0;;;;;:::i;:::-;;:::i;:::-;;;5927:14:1;;5920:22;5902:41;;5890:2;5875:18;69151:1043:0;5762:187:1;66077:438:0;;;;;;;;;;-1:-1:-1;66077:438:0;;;;;:::i;:::-;;:::i;64828:25::-;;;;;;;;;;;;;;;;;;;6952::1;;;6940:2;6925:18;64828:25:0;6806:177:1;73609:477:0;;;;;;;;;;-1:-1:-1;73609:477:0;;;;;:::i;:::-;;:::i;:::-;;64672:52;;;;;;;;;;-1:-1:-1;64672:52:0;;;;;:::i;:::-;;:::i;75350:229::-;;;;;;;;;;-1:-1:-1;75350:229:0;;;;;:::i;:::-;;:::i;64417:56::-;;;;;;;;;;-1:-1:-1;64417:56:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;64417:56:0;;;-1:-1:-1;;;64417:56:0;;;;;;;;;;-1:-1:-1;;;;;7630:32:1;;;7612:51;;7706:14;;7699:22;7694:2;7679:18;;7672:50;7585:18;64417:56:0;7444:284:1;74820:94:0;;;;;;;;;;;;;:::i;65268:443::-;;;;;;;;;;-1:-1:-1;65268:443:0;;;;;:::i;:::-;;:::i;30848:225::-;;;;;;:::i;:::-;;:::i;30067:133::-;;;;;;;;;;;;;:::i;34926:86::-;;;;;;;;;;-1:-1:-1;34997:7:0;;;;34926:86;;66824:225;;;;;;;;;;-1:-1:-1;66824:225:0;;;;;:::i;:::-;;:::i;74273:332::-;;;;;;;;;;-1:-1:-1;74273:332:0;;;;;:::i;:::-;;:::i;74677:93::-;;;;;;;;;;;;;:::i;70379:1257::-;;;;;;;;;;-1:-1:-1;70379:1257:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;73095:212::-;;;;;;;;;;-1:-1:-1;73095:212:0;;;;;:::i;:::-;;:::i;72031:872::-;72231:31;;;72259:2;72231:31;;;;;;;;;72132:30;;72164:7;;;;;;72231:31;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;;72322:22:0;;72273:16;72322:22;;;:15;:22;;;;;:29;72193:69;;-1:-1:-1;72292:2:0;;72322:29;72383:17;72292:2;72322:29;72383:17;:::i;:::-;72362:38;;72424:1;72415:6;:10;:36;;;;-1:-1:-1;72429:17:0;72438:8;72429:6;:17;:::i;:::-;:22;72415:36;72411:81;;;72468:12;;;;:::i;:::-;;;;72411:81;72515:10;72506:5;:19;;:34;;;;-1:-1:-1;72529:11:0;;;72506:34;72502:341;;;72562:9;72557:275;72581:8;72577:1;:12;72557:275;;;72615:13;72663:1;72659;72640:16;72648:8;72640:5;:16;:::i;:::-;72631:25;;:6;:25;:::i;:::-;:29;;;;:::i;:::-;:33;;;;:::i;:::-;-1:-1:-1;;;;;72701:22:0;;72683:15;72701:22;;;:15;:22;;;;;:29;;72615:49;;-1:-1:-1;72683:15:0;;72615:49;;72701:29;;;;;;:::i;:::-;;;;;;;;;72683:47;;72759:17;72768:7;72759:8;:17::i;:::-;72749:4;72754:1;72749:7;;;;;;;;:::i;:::-;;;;;;:27;;;;72799:5;72808:1;72799:10;72795:21;;72811:5;;;;72795:21;72596:236;;72591:3;;;;;:::i;:::-;;;;72557:275;;;;72502:341;72861:4;;72867:15;;-1:-1:-1;72861:4:0;;-1:-1:-1;72031:872:0;;-1:-1:-1;;;;;72031:872:0:o;69151:1043::-;69288:4;34531:19;:17;:19::i;:::-;38662:21:::1;:19;:21::i;:::-;69333:12:::0;;69313:32;::::2;69305:66;;;::::0;-1:-1:-1;;;69305:66:0;;10811:2:1;69305:66:0::2;::::0;::::2;10793:21:1::0;10850:2;10830:18;;;10823:30;-1:-1:-1;;;10869:18:1;;;10862:51;10930:18;;69305:66:0::2;;;;;;;;;69387:9;69382:783;69402:20:::0;;::::2;69382:783;;;69444:10;69457:9;;69467:1;69457:12;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;::::2;;69484:26;69513:18:::0;;;:14:::2;:18:::0;;;;;;;69484:47;;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;;;69484:47:0;;::::2;::::0;;;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;::::2;::::0;::::2;::::0;;;;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;::::2;::::0;;;;;::::2;;::::0;::::2;;;::::0;::::2;::::0;;;;69457:12;;-1:-1:-1;69484:47:0;-1:-1:-1;69546:44:0::2;;;::::0;-1:-1:-1;;;69546:44:0;;11161:2:1;69546:44:0::2;::::0;::::2;11143:21:1::0;11200:2;11180:18;;;11173:30;-1:-1:-1;;;11219:18:1;;;11212:45;11274:18;;69546:44:0::2;10959:339:1::0;69546:44:0::2;69624:11:::0;;-1:-1:-1;;;;;69613:23:0;;::::2;69657:1;69613:23:::0;;;:10:::2;:23;::::0;;;;:32;::::2;69605:103;;;;-1:-1:-1::0;;;69605:103:0::2;;;;;;;:::i;:::-;69803:11:::0;;-1:-1:-1;;;;;69792:23:0;;::::2;69761:18;69792:23:::0;;;:10:::2;:23;::::0;;;;;;;:32;69877:8;;::::2;::::0;69887:11;;::::2;::::0;69900:8;;69792:32;;;::::2;::::0;;;69862:14:::2;::::0;69877:8;;69887:11;69900:5;;69906:1;;69900:8;::::2;;;;;:::i;:::-;;;;;;;69862:47;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69840:69;;69932:11;69947:1;69932:16:::0;69924:46:::2;;;::::0;-1:-1:-1;;;69924:46:0;;13027:2:1;69924:46:0::2;::::0;::::2;13009:21:1::0;13066:2;13046:18;;;13039:30;-1:-1:-1;;;13085:18:1;;;13078:47;13142:18;;69924:46:0::2;12825:341:1::0;69924:46:0::2;69985:18;::::0;;;:14:::2;:18;::::0;;;;;;;;:30:::2;::::0;::::2;:44:::0;;;70044:28:::2;;:35:::0;;-1:-1:-1;;70044:35:0::2;70075:4;70044:35;::::0;;70110:11;;::::2;::::0;70127:12:::2;::::0;::::2;::::0;70101:52;;13345:25:1;;;13386:18;;;13379:34;;;69985:18:0;;-1:-1:-1;;;;;70101:52:0;;::::2;::::0;::::2;::::0;13318:18:1;70101:52:0::2;;;;;;;69429:736;;;;69424:3;;;;;:::i;:::-;;;;69382:783;;;;70182:4;70175:11;;38706:20:::1;37923:1:::0;39226:7;:22;39043:213;38706:20:::1;69151:1043:::0;;;;;:::o;66077:438::-;66253:4;34531:19;:17;:19::i;:::-;38662:21:::1;:19;:21::i;:::-;66278:18:::0;;;::::2;::::0;:53:::2;;-1:-1:-1::0;66300:31:0;;::::2;66278:53;66270:87;;;::::0;-1:-1:-1;;;66270:87:0;;13626:2:1;66270:87:0::2;::::0;::::2;13608:21:1::0;13665:2;13645:18;;;13638:30;-1:-1:-1;;;13684:18:1;;;13677:51;13745:18;;66270:87:0::2;13424:345:1::0;66270:87:0::2;66375:9;66370:116;66390:17:::0;;::::2;66370:116;;;66429:45;66439:6;;66446:1;66439:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;66450:7;;66458:1;66450:10;;;;;;;:::i;:::-;;;;;;;66462:11;66429:9;:45::i;:::-;-1:-1:-1::0;66409:3:0;::::2;::::0;::::2;:::i;:::-;;;;66370:116;;;;66503:4;66496:11;;38706:20:::1;37923:1:::0;39226:7;:22;39043:213;38706:20:::1;66077:438:::0;;;;;;;:::o;73609:477::-;38662:21;:19;:21::i;:::-;63944:26:::1;65021:20;65031:9;65021;:20::i;:::-;-1:-1:-1::0;;;;;73730:23:0;::::2;73722:52;;;::::0;-1:-1:-1;;;73722:52:0;;13976:2:1;73722:52:0::2;::::0;::::2;13958:21:1::0;14015:2;13995:18;;;13988:30;-1:-1:-1;;;14034:18:1;;;14027:46;14090:18;;73722:52:0::2;13774:340:1::0;73722:52:0::2;-1:-1:-1::0;;;;;73793:18:0;;::::2;73832:1;73793:18:::0;;;:10:::2;:18;::::0;;;;:27;::::2;:41:::0;73785:74:::2;;;::::0;-1:-1:-1;;;73785:74:0;;14321:2:1;73785:74:0::2;::::0;::::2;14303:21:1::0;14360:2;14340:18;;;14333:30;-1:-1:-1;;;14379:18:1;;;14372:50;14439:18;;73785:74:0::2;14119:344:1::0;73785:74:0::2;73930:29;::::0;-1:-1:-1;;;73930:29:0;;-1:-1:-1;;;;;14632:32:1;;;73930:29:0::2;::::0;::::2;14614:51:1::0;73901:9:0;;73930:21;;::::2;::::0;::::2;::::0;14587:18:1;;73930:29:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73922:67;;;::::0;-1:-1:-1;;;73922:67:0;;15128:2:1;73922:67:0::2;::::0;::::2;15110:21:1::0;15167:2;15147:18;;;15140:30;-1:-1:-1;;;15186:18:1;;;15179:55;15251:18;;73922:67:0::2;14926:349:1::0;73922:67:0::2;-1:-1:-1::0;;74021:57:0::2;::::0;;;;::::2;::::0;;-1:-1:-1;;;;;74021:57:0;;::::2;::::0;;74072:4:::2;74021:57;::::0;;::::2;::::0;;;74000:18;;::::2;-1:-1:-1::0;74000:18:0;;;:10:::2;:18:::0;;;;;;;:78;;;;;;::::2;;-1:-1:-1::0;;;74000:78:0::2;-1:-1:-1::0;;;;;;74000:78:0;;;;::::2;::::0;;;;::::2;::::0;;38706:20;37923:1;39226:7;:22;39043:213;38706:20;73609:477;;:::o;64672:52::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;75350:229::-;64027:35;65021:20;65031:9;65021;:20::i;:::-;-1:-1:-1;;;;;28937:6:0::1;28920:23;28928:4;28920:23:::0;28912:80:::1;;;;-1:-1:-1::0;;;28912:80:0::1;;;;;;;:::i;:::-;29035:6;-1:-1:-1::0;;;;;29011:30:0::1;:20;:18;:20::i;:::-;-1:-1:-1::0;;;;;29011:30:0::1;;29003:87;;;;-1:-1:-1::0;;;29003:87:0::1;;;;;;;:::i;:::-;75493:37:::2;75511:18;75493:17;:37::i;:::-;75541:30;75552:18;75541:10;:30::i;74820:94::-:0;64112:28;65021:20;65031:9;65021;:20::i;:::-;34790:16:::1;:14;:16::i;:::-;74896:10:::2;:8;:10::i;:::-;74820:94:::0;:::o;65268:443::-;16551:19;16574:13;;;;;;16573:14;;16621:34;;;;-1:-1:-1;16639:12:0;;16654:1;16639:12;;;;:16;16621:34;16620:108;;;-1:-1:-1;16700:4:0;3609:19;:23;;;16661:66;;-1:-1:-1;16710:12:0;;;;;:17;16661:66;16598:204;;;;-1:-1:-1;;;16598:204:0;;16308:2:1;16598:204:0;;;16290:21:1;16347:2;16327:18;;;16320:30;16386:34;16366:18;;;16359:62;-1:-1:-1;;;16437:18:1;;;16430:44;16491:19;;16598:204:0;16106:410:1;16598:204:0;16813:12;:16;;-1:-1:-1;;16813:16:0;16828:1;16813:16;;;16840:67;;;;16875:13;:20;;-1:-1:-1;;16875:20:0;;;;;16840:67;-1:-1:-1;;;;;28937:6:0::1;28920:23;28928:4;28920:23:::0;28912:80:::1;;;;-1:-1:-1::0;;;28912:80:0::1;;;;;;;:::i;:::-;29035:6;-1:-1:-1::0;;;;;29011:30:0::1;:20;:18;:20::i;:::-;-1:-1:-1::0;;;;;29011:30:0::1;;29003:87;;;;-1:-1:-1::0;;;29003:87:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;65379:26:0;::::2;65371:66;;;::::0;-1:-1:-1;;;65371:66:0;;16723:2:1;65371:66:0::2;::::0;::::2;16705:21:1::0;16762:2;16742:18;;;16735:30;16801:29;16781:18;;;16774:57;16848:18;;65371:66:0::2;16521:351:1::0;65371:66:0::2;-1:-1:-1::0;;;;;65456:23:0;::::2;65448:60;;;::::0;-1:-1:-1;;;65448:60:0;;17079:2:1;65448:60:0::2;::::0;::::2;17061:21:1::0;17118:2;17098:18;;;17091:30;17157:26;17137:18;;;17130:54;17201:18;;65448:60:0::2;16877:348:1::0;65448:60:0::2;65521:17;:15;:17::i;:::-;65549:24;:22;:24::i;:::-;65584;:22;:24::i;:::-;65621:11;:40:::0;;-1:-1:-1;;;;;65621:40:0;;::::2;-1:-1:-1::0;;;;;;65621:40:0;;::::2;;::::0;;;65672:8:::2;:31:::0;;;;::::2;::::0;;;::::2;::::0;;;::::2;::::0;;16929:102;;;;16980:5;16964:21;;-1:-1:-1;;16964:21:0;;;17005:14;;-1:-1:-1;17382:36:1;;17005:14:0;;17370:2:1;17355:18;17005:14:0;;;;;;;16929:102;16540:498;65268:443;;:::o;30848:225::-;-1:-1:-1;;;;;28937:6:0;28920:23;28928:4;28920:23;28912:80;;;;-1:-1:-1;;;28912:80:0;;;;;;;:::i;:::-;29035:6;-1:-1:-1;;;;;29011:30:0;:20;:18;:20::i;:::-;-1:-1:-1;;;;;29011:30:0;;29003:87;;;;-1:-1:-1;;;29003:87:0;;;;;;;:::i;:::-;30966:36:::1;30984:17;30966;:36::i;:::-;31013:52;31035:17;31054:4;31060;31013:21;:52::i;30067:133::-:0;30145:7;29373:4;-1:-1:-1;;;;;29382:6:0;29365:23;;29357:92;;;;-1:-1:-1;;;29357:92:0;;17631:2:1;29357:92:0;;;17613:21:1;17670:2;17650:18;;;17643:30;17709:34;17689:18;;;17682:62;17780:26;17760:18;;;17753:54;17824:19;;29357:92:0;17429:420:1;29357:92:0;-1:-1:-1;;;;;;;;;;;;30067:133:0;:::o;66824:225::-;66975:7;34531:19;:17;:19::i;:::-;38662:21:::1;:19;:21::i;:::-;67002:39:::2;67012:6;67020:7;67029:11;67002:9;:39::i;:::-;66995:46;;38706:20:::1;37923:1:::0;39226:7;:22;39043:213;74273:332;38662:21;:19;:21::i;:::-;63944:26:::1;65021:20;65031:9;65021;:20::i;:::-;-1:-1:-1::0;;;;;74394:20:0;::::2;74386:58;;;::::0;-1:-1:-1;;;74386:58:0;;15128:2:1;74386:58:0::2;::::0;::::2;15110:21:1::0;15167:2;15147:18;;;15140:30;-1:-1:-1;;;15186:18:1;;;15179:55;15251:18;;74386:58:0::2;14926:349:1::0;74386:58:0::2;-1:-1:-1::0;;;;;74463:18:0;;::::2;74502:1;74463:18:::0;;;:10:::2;:18;::::0;;;;:27;::::2;74455:92;;;::::0;-1:-1:-1;;;74455:92:0;;18056:2:1;74455:92:0::2;::::0;::::2;18038:21:1::0;18095:2;18075:18;;;18068:30;18134:34;18114:18;;;18107:62;-1:-1:-1;;;18185:18:1;;;18178:36;18231:19;;74455:92:0::2;17854:402:1::0;74455:92:0::2;-1:-1:-1::0;;;;;;74558:18:0;::::2;;::::0;;;:10:::2;:18;::::0;;;;:39;;-1:-1:-1;;;;74558:39:0::2;-1:-1:-1::0;;;74558:39:0;::::2;;;;::::0;;-1:-1:-1;39226:7:0;:22;73609:477;;:::o;74677:93::-;64112:28;65021:20;65031:9;65021;:20::i;:::-;34531:19:::1;:17;:19::i;:::-;74754:8:::2;:6;:8::i;70379:1257::-:0;70436:28;;:::i;:::-;70477:26;70506:24;;;:14;:24;;;;;;;;70477:53;;;;;;;;;-1:-1:-1;;;;;70477:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70549:23;;;:10;:23;;;;;:32;70477:53;;70549:32;70541:103;;;;-1:-1:-1;;;70541:103:0;;;;;;;:::i;:::-;70752:11;;-1:-1:-1;;;;;70741:23:0;;;70686:13;70741:23;;;:10;:23;;;;;:32;70807:17;;;;70839:15;;;;70686:13;;70741:32;;;;;70835:490;;;70880:14;70871:23;;70835:490;;;70974:8;;;;;70946:37;;-1:-1:-1;;;70946:37:0;;70927:16;;-1:-1:-1;;;;;70946:27:0;;;;;:37;;;;6952:25:1;;;6940:2;6925:18;;6806:177;70946:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70927:56;;71002:11;70998:143;;;71043:16;71034:25;;70998:143;;;71109:16;71100:25;;70998:143;71243:8;;;;;71214:38;;-1:-1:-1;;;71214:38:0;;71195:16;;-1:-1:-1;;;;;71214:28:0;;;;;:38;;;;6952:25:1;;;6940:2;6925:18;;6806:177;71214:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71281:8;;:32;;-1:-1:-1;;;71281:32:0;;;;;6952:25:1;;;71195:57:0;;-1:-1:-1;;;;;;71281:8:0;;:22;;6925:18:1;;71281:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71267:46;;70912:413;;70835:490;71357:271;;;;;;;;71405:5;:11;;;-1:-1:-1;;;;;71357:271:0;;;;;71444:8;71357:271;;;;71479:5;:12;;;71357:271;;;;71523:11;71357:271;;;;71564:5;:15;;;71357:271;;;;71606:6;71357:271;;;;;;;;:::i;:::-;;;71337:291;70379:1257;-1:-1:-1;;;;;;70379:1257:0:o;73095:212::-;-1:-1:-1;;;;;73210:18:0;;;73159:7;73210:18;;;:10;:18;;;;;;:27;73256:43;;-1:-1:-1;;;73256:43:0;;64187:4;73256:43;;;6952:25:1;73159:7:0;;73210:27;;;;73256:29;;6925:18:1;;73256:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;35085:108::-;34997:7;;;;35155:9;35147:38;;;;-1:-1:-1;;;35147:38:0;;18463:2:1;35147:38:0;;;18445:21:1;18502:2;18482:18;;;18475:30;-1:-1:-1;;;18521:18:1;;;18514:46;18577:18;;35147:38:0;18261:340:1;35147:38:0;35085:108::o;38742:293::-;37967:1;38876:7;;:19;38868:63;;;;-1:-1:-1;;;38868:63:0;;18808:2:1;38868:63:0;;;18790:21:1;18847:2;18827:18;;;18820:30;18886:33;18866:18;;;18859:61;18937:18;;38868:63:0;18606:355:1;38868:63:0;37967:1;39009:7;:18;38742:293::o;39043:213::-;37923:1;39226:7;:22;39043:213::o;67385:1525::-;67476:7;-1:-1:-1;;;;;67504:20:0;;67496:46;;;;-1:-1:-1;;;67496:46:0;;19168:2:1;67496:46:0;;;19150:21:1;19207:2;19187:18;;;19180:30;-1:-1:-1;;;19226:18:1;;;19219:43;19279:18;;67496:46:0;18966:337:1;67496:46:0;67561:7;67572:1;67561:12;67553:36;;;;-1:-1:-1;;;67553:36:0;;19510:2:1;67553:36:0;;;19492:21:1;19549:2;19529:18;;;19522:30;-1:-1:-1;;;19568:18:1;;;19561:41;19619:18;;67553:36:0;19308:335:1;67553:36:0;-1:-1:-1;;;;;67608:18:0;;;;;;:10;:18;;;;;:27;-1:-1:-1;;;67608:27:0;;;;67600:57;;;;-1:-1:-1;;;67600:57:0;;19850:2:1;67600:57:0;;;19832:21:1;19889:2;19869:18;;;19862:30;-1:-1:-1;;;19908:18:1;;;19901:47;19965:18;;67600:57:0;19648:341:1;67600:57:0;-1:-1:-1;;;;;67701:18:0;;;67670;67701;;;:10;:18;;;;;;;;;:27;67748:28;;-1:-1:-1;;;67748:28:0;;;;67701:27;;;;;67748:26;;:28;;;;;67701:18;;67748:28;;;;;67701:27;67748:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67740:73;;;;-1:-1:-1;;;67740:73:0;;20196:2:1;67740:73:0;;;20178:21:1;;;20215:18;;;20208:30;20274:34;20254:18;;;20247:62;20326:18;;67740:73:0;19994:356:1;67740:73:0;-1:-1:-1;;;;;67870:25:0;;67866:82;;67926:10;67912:24;;67866:82;68028:27;;-1:-1:-1;;;68028:27:0;;68044:10;68028:27;;;14614:51:1;68002:6:0;;68059:7;;-1:-1:-1;;;;;68028:15:0;;;;;14587:18:1;;68028:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38;;68020:71;;;;-1:-1:-1;;;68020:71:0;;20557:2:1;68020:71:0;;;20539:21:1;20596:2;20576:18;;;20569:30;-1:-1:-1;;;20615:18:1;;;20608:50;20675:18;;68020:71:0;20355:344:1;68020:71:0;68102:62;-1:-1:-1;;;;;68102:22:0;;68125:10;68145:8;68156:7;68102:22;:62::i;:::-;68240:47;;-1:-1:-1;;;68240:47:0;;;;;20906:25:1;;;-1:-1:-1;;;;;21005:15:1;;;20985:18;;;20978:43;21057:15;;;21037:18;;;21030:43;68205:10:0;;;;68240:17;;;;;20879:18:1;;68240:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68204:83;;;;68325:15;68345:10;;68343:12;;;;;:::i;:::-;;;;;;;68325:30;;68366:17;68386:15;68366:35;;68438:288;;;;;;;;68474:6;-1:-1:-1;;;;;68438:288:0;;;;;68502:11;-1:-1:-1;;;;;68438:288:0;;;;;68532:2;68438:288;;;;68557:7;68438:288;;;;68592:11;68438:288;;;;68629:9;68438:288;;;;68664:2;68670:1;68664:7;68438:288;;;;;68412:14;:23;68427:7;68412:23;;;;;;;;;;;:314;;;;;;;;;;;;;-1:-1:-1;;;;;68412:314:0;;;;;-1:-1:-1;;;;;68412:314:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68412:314:0;;;;;-1:-1:-1;;;;;68412:314:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68739:15;:28;68755:11;-1:-1:-1;;;;;68739:28:0;-1:-1:-1;;;;;68739:28:0;;;;;;;;;;;;68773:7;68739:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68832:7;68824:6;-1:-1:-1;;;;;68799:78:0;68811:11;-1:-1:-1;;;;;68799:78:0;;68841:2;68845:7;68854:11;68867:9;68799:78;;;;;;;;21565:25:1;;;21621:2;21606:18;;21599:34;;;;21664:2;21649:18;;21642:34;21707:2;21692:18;;21685:34;21552:3;21537:19;;21334:391;68799:78:0;;;;;;;;-1:-1:-1;68895:7:0;67385:1525;-1:-1:-1;;;;;;;;67385:1525:0:o;75038:139::-;75109:11;;:44;;-1:-1:-1;;;75109:44:0;;;;;21904:25:1;;;75142:10:0;21945:18:1;;;21938:60;-1:-1:-1;;;;;75109:11:0;;;;:21;;21877:18:1;;75109:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75101:68;;;;-1:-1:-1;;;75101:68:0;;22211:2:1;75101:68:0;;;22193:21:1;22250:2;22230:18;;;22223:30;-1:-1:-1;;;22269:18:1;;;22262:41;22320:18;;75101:68:0;22009:335:1;21108:153:0;-1:-1:-1;;;;;;;;;;;21188:65:0;-1:-1:-1;;;;;21188:65:0;;21108:153::o;75779:189::-;64027:35;65021:20;65031:9;65021;:20::i;:::-;75945:1:::1;75912:18;-1:-1:-1::0;;;;;75912:30:0::1;;:34;75904:56;;;::::0;-1:-1:-1;;;75904:56:0;;22551:2:1;75904:56:0::1;::::0;::::1;22533:21:1::0;22590:1;22570:18;;;22563:29;-1:-1:-1;;;22608:18:1;;;22601:39;22657:18;;75904:56:0::1;22349:332:1::0;21754:155:0;21821:37;21840:17;21821:18;:37::i;:::-;21874:27;;-1:-1:-1;;;;;21874:27:0;;;;;;;;21754:155;:::o;35270:108::-;34997:7;;;;35329:41;;;;-1:-1:-1;;;35329:41:0;;22888:2:1;35329:41:0;;;22870:21:1;22927:2;22907:18;;;22900:30;-1:-1:-1;;;22946:18:1;;;22939:50;23006:18;;35329:41:0;22686:344:1;35781:120:0;34790:16;:14;:16::i;:::-;35840:7:::1;:15:::0;;-1:-1:-1;;35840:15:0::1;::::0;;35871:22:::1;32792:10:::0;35880:12:::1;35871:22;::::0;-1:-1:-1;;;;;14632:32:1;;;14614:51;;14602:2;14587:18;35871:22:0::1;;;;;;;35781:120::o:0;34096:99::-;18694:13;;;;;;;18686:69;;;;-1:-1:-1;;;18686:69:0;;;;;;;:::i;:::-;34160:27:::1;:25;:27::i;38009:113::-:0;18694:13;;;;;;;18686:69;;;;-1:-1:-1;;;18686:69:0;;;;;;;:::i;:::-;38080:34:::1;:32;:34::i;28065:68::-:0;18694:13;;;;;;;18686:69;;;;-1:-1:-1;;;18686:69:0;;;;;;;:::i;22526:992::-;20610:66;22980:59;;;22976:535;;;23056:37;23075:17;23056:18;:37::i;22976:535::-;23159:17;-1:-1:-1;;;;;23130:61:0;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23130:63:0;;;;;;;;-1:-1:-1;;23130:63:0;;;;;;;;;;;;:::i;:::-;;;23126:306;;23360:56;;-1:-1:-1;;;23360:56:0;;23838:2:1;23360:56:0;;;23820:21:1;23877:2;23857:18;;;23850:30;23916:34;23896:18;;;23889:62;-1:-1:-1;;;23967:18:1;;;23960:44;24021:19;;23360:56:0;23636:410:1;23126:306:0;-1:-1:-1;;;;;;;;;;;23244:28:0;;23236:82;;;;-1:-1:-1;;;23236:82:0;;24253:2:1;23236:82:0;;;24235:21:1;24292:2;24272:18;;;24265:30;24331:34;24311:18;;;24304:62;-1:-1:-1;;;24382:18:1;;;24375:39;24431:19;;23236:82:0;24051:405:1;23236:82:0;23194:140;23446:53;23464:17;23483:4;23489:9;23446:17;:53::i;35522:118::-;34531:19;:17;:19::i;:::-;35582:7:::1;:14:::0;;-1:-1:-1;;35582:14:0::1;35592:4;35582:14;::::0;;35612:20:::1;35619:12;32792:10:::0;;32712:98;45491:259;45673:68;;;-1:-1:-1;;;;;24719:15:1;;;45673:68:0;;;24701:34:1;24771:15;;24751:18;;;24744:43;24803:18;;;;24796:34;;;45673:68:0;;;;;;;;;;24636:18:1;;;;45673:68:0;;;;;;;;-1:-1:-1;;;;;45673:68:0;-1:-1:-1;;;45673:68:0;;;45646:96;;45666:5;;45646:19;:96::i;:::-;45491:259;;;;:::o;21357:284::-;-1:-1:-1;;;;;3609:19:0;;;21431:106;;;;-1:-1:-1;;;21431:106:0;;25043:2:1;21431:106:0;;;25025:21:1;25082:2;25062:18;;;25055:30;25121:34;25101:18;;;25094:62;-1:-1:-1;;;25172:18:1;;;25165:43;25225:19;;21431:106:0;24841:409:1;21431:106:0;-1:-1:-1;;;;;;;;;;;21548:85:0;;-1:-1:-1;;;;;;21548:85:0;-1:-1:-1;;;;;21548:85:0;;;;;;;;;;21357:284::o;34203:97::-;18694:13;;;;;;;18686:69;;;;-1:-1:-1;;;18686:69:0;;;;;;;:::i;:::-;34277:7:::1;:15:::0;;-1:-1:-1;;34277:15:0::1;::::0;;34203:97::o;38130:111::-;18694:13;;;;;;;18686:69;;;;-1:-1:-1;;;18686:69:0;;;;;;;:::i;22050:297::-;22193:29;22204:17;22193:10;:29::i;:::-;22251:1;22237:4;:11;:15;:28;;;;22256:9;22237:28;22233:107;;;22282:46;22304:17;22323:4;22282:21;:46::i;48394:727::-;48829:23;48855:69;48883:4;48855:69;;;;;;;;;;;;;;;;;48863:5;-1:-1:-1;;;;;48855:27:0;;;:69;;;;;:::i;:::-;48939:17;;48829:95;;-1:-1:-1;48939:21:0;48935:179;;49036:10;49025:30;;;;;;;;;;;;:::i;:::-;49017:85;;;;-1:-1:-1;;;49017:85:0;;25457:2:1;49017:85:0;;;25439:21:1;25496:2;25476:18;;;25469:30;25535:34;25515:18;;;25508:62;-1:-1:-1;;;25586:18:1;;;25579:40;25636:19;;49017:85:0;25255:406:1;26523:461:0;26606:12;-1:-1:-1;;;;;3609:19:0;;;26631:88;;;;-1:-1:-1;;;26631:88:0;;25868:2:1;26631:88:0;;;25850:21:1;25907:2;25887:18;;;25880:30;25946:34;25926:18;;;25919:62;-1:-1:-1;;;25997:18:1;;;25990:36;26043:19;;26631:88:0;25666:402:1;26631:88:0;26793:12;26807:23;26834:6;-1:-1:-1;;;;;26834:19:0;26854:4;26834:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26792:67;;;;26877:99;26913:7;26922:10;26877:99;;;;;;;;;;;;;;;;;:35;:99::i;:::-;26870:106;;;;26523:461;;;;;:::o;6071:229::-;6208:12;6240:52;6262:6;6270:4;6276:1;6279:12;6240:21;:52::i;:::-;6233:59;6071:229;-1:-1:-1;;;;6071:229:0:o;9724:305::-;9874:12;9903:7;9899:123;;;-1:-1:-1;9934:10:0;9927:17;;9899:123;9977:33;9985:10;9997:12;9977:7;:33::i;7191:455::-;7361:12;7419:5;7394:21;:30;;7386:81;;;;-1:-1:-1;;;7386:81:0;;26567:2:1;7386:81:0;;;26549:21:1;26606:2;26586:18;;;26579:30;26645:34;26625:18;;;26618:62;-1:-1:-1;;;26696:18:1;;;26689:36;26742:19;;7386:81:0;26365:402:1;7386:81:0;7479:12;7493:23;7520:6;-1:-1:-1;;;;;7520:11:0;7539:5;7546:4;7520:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7478:73;;;;7569:69;7596:6;7604:7;7613:10;7625:12;7569:26;:69::i;:::-;7562:76;7191:455;-1:-1:-1;;;;;;;7191:455:0:o;10037:552::-;10198:17;;:21;10194:388;;10430:10;10424:17;10487:15;10474:10;10470:2;10466:19;10459:44;10194:388;10557:12;10550:20;;-1:-1:-1;;;10550:20:0;;;;;;;;:::i;8851:644::-;9036:12;9065:7;9061:427;;;9093:10;:17;9114:1;9093:22;9089:290;;-1:-1:-1;;;;;3609:19:0;;;9303:60;;;;-1:-1:-1;;;9303:60:0;;27198:2:1;9303:60:0;;;27180:21:1;27237:2;27217:18;;;27210:30;27276:31;27256:18;;;27249:59;27325:18;;9303:60:0;26996:353:1;9303:60:0;-1:-1:-1;9400:10:0;9393:17;;9061:427;9443:33;9451:10;9463:12;9443:7;:33::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:254::-;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;436:2;421:18;;;;408:32;;-1:-1:-1;;;192:254:1:o;451:127::-;512:10;507:3;503:20;500:1;493:31;543:4;540:1;533:15;567:4;564:1;557:15;583:612;705:1;701;696:3;692:11;688:19;680:5;674:12;670:38;665:3;658:51;758:4;751:5;747:16;741:23;734:4;729:3;725:14;718:47;814:4;807:5;803:16;797:23;790:4;785:3;781:14;774:47;870:4;863:5;859:16;853:23;846:4;841:3;837:14;830:47;926:4;919:5;915:16;909:23;902:4;897:3;893:14;886:47;979:4;972:5;968:16;962:23;1021:1;1007:12;1004:19;994:150;;1066:10;1061:3;1057:20;1054:1;1047:31;1101:4;1098:1;1091:15;1129:4;1126:1;1119:15;994:150;1176:12;1169:4;1164:3;1160:14;1153:36;;583:612;;:::o;1200:890::-;1524:2;1536:21;;;1606:13;;1509:18;;;1628:22;;;1476:4;;1704;;1681:3;1666:19;;;1731:15;;;1476:4;1774:204;1788:6;1785:1;1782:13;1774:204;;;1837:59;1892:3;1883:6;1877:13;1837:59;:::i;:::-;1925:4;1916:14;;;;;1953:15;;;;1810:1;1803:9;1774:204;;;-1:-1:-1;;;2014:18:1;;;2007:34;;;;-1:-1:-1;2072:2:1;2057:18;2050:34;1995:3;1200:890;-1:-1:-1;1200:890:1:o;2095:180::-;2154:6;2207:2;2195:9;2186:7;2182:23;2178:32;2175:52;;;2223:1;2220;2213:12;2175:52;-1:-1:-1;2246:23:1;;2095:180;-1:-1:-1;2095:180:1:o;2958:367::-;3021:8;3031:6;3085:3;3078:4;3070:6;3066:17;3062:27;3052:55;;3103:1;3100;3093:12;3052:55;-1:-1:-1;3126:20:1;;3169:18;3158:30;;3155:50;;;3201:1;3198;3191:12;3155:50;3238:4;3230:6;3226:17;3214:29;;3298:3;3291:4;3281:6;3278:1;3274:14;3266:6;3262:27;3258:38;3255:47;3252:67;;;3315:1;3312;3305:12;3252:67;2958:367;;;;;:::o;3330:127::-;3391:10;3386:3;3382:20;3379:1;3372:31;3422:4;3419:1;3412:15;3446:4;3443:1;3436:15;3462:275;3533:2;3527:9;3598:2;3579:13;;-1:-1:-1;;3575:27:1;3563:40;;3633:18;3618:34;;3654:22;;;3615:62;3612:88;;;3680:18;;:::i;:::-;3716:2;3709:22;3462:275;;-1:-1:-1;3462:275:1:o;3742:530::-;3784:5;3837:3;3830:4;3822:6;3818:17;3814:27;3804:55;;3855:1;3852;3845:12;3804:55;3891:6;3878:20;3917:18;3913:2;3910:26;3907:52;;;3939:18;;:::i;:::-;3983:55;4026:2;4007:13;;-1:-1:-1;;4003:27:1;4032:4;3999:38;3983:55;:::i;:::-;4063:2;4054:7;4047:19;4109:3;4102:4;4097:2;4089:6;4085:15;4081:26;4078:35;4075:55;;;4126:1;4123;4116:12;4075:55;4191:2;4184:4;4176:6;4172:17;4165:4;4156:7;4152:18;4139:55;4239:1;4214:16;;;4232:4;4210:27;4203:38;;;;4218:7;3742:530;-1:-1:-1;;;3742:530:1:o;4277:1480::-;4406:6;4414;4422;4475:2;4463:9;4454:7;4450:23;4446:32;4443:52;;;4491:1;4488;4481:12;4443:52;4531:9;4518:23;4560:18;4601:2;4593:6;4590:14;4587:34;;;4617:1;4614;4607:12;4587:34;4656:70;4718:7;4709:6;4698:9;4694:22;4656:70;:::i;:::-;4745:8;;-1:-1:-1;4630:96:1;-1:-1:-1;4799:2:1;;-1:-1:-1;4839:18:1;;;4826:32;4870:16;;;4867:36;;;4899:1;4896;4889:12;4867:36;4922:24;;4977:4;4969:13;;4965:27;-1:-1:-1;4955:55:1;;5006:1;5003;4996:12;4955:55;5042:2;5029:16;5064:2;5060;5057:10;5054:36;;;5070:18;;:::i;:::-;5116:2;5113:1;5109:10;5139:28;5163:2;5159;5155:11;5139:28;:::i;:::-;5201:15;;;5271:11;;;5267:20;;;5232:12;;;;5299:19;;;5296:39;;;5331:1;5328;5321:12;5296:39;5363:2;5359;5355:11;5344:22;;5375:352;5391:6;5386:3;5383:15;5375:352;;;5477:3;5464:17;5513:2;5500:11;5497:19;5494:109;;;5557:1;5586:2;5582;5575:14;5494:109;5628:56;5676:7;5671:2;5657:11;5653:2;5649:20;5645:29;5628:56;:::i;:::-;5616:69;;-1:-1:-1;5408:12:1;;;;5705;;;;5375:352;;;5746:5;5736:15;;;;;;;;;4277:1480;;;;;:::o;5954:847::-;6085:6;6093;6101;6109;6117;6170:2;6158:9;6149:7;6145:23;6141:32;6138:52;;;6186:1;6183;6176:12;6138:52;6226:9;6213:23;6255:18;6296:2;6288:6;6285:14;6282:34;;;6312:1;6309;6302:12;6282:34;6351:70;6413:7;6404:6;6393:9;6389:22;6351:70;:::i;:::-;6440:8;;-1:-1:-1;6325:96:1;-1:-1:-1;6528:2:1;6513:18;;6500:32;;-1:-1:-1;6544:16:1;;;6541:36;;;6573:1;6570;6563:12;6541:36;;6612:72;6676:7;6665:8;6654:9;6650:24;6612:72;:::i;:::-;6703:8;;-1:-1:-1;6586:98:1;-1:-1:-1;6757:38:1;;-1:-1:-1;6791:2:1;6776:18;;6757:38;:::i;:::-;6747:48;;5954:847;;;;;;;;:::o;6988:260::-;7056:6;7064;7117:2;7105:9;7096:7;7092:23;7088:32;7085:52;;;7133:1;7130;7123:12;7085:52;7156:29;7175:9;7156:29;:::i;:::-;7146:39;;7204:38;7238:2;7227:9;7223:18;7204:38;:::i;:::-;7194:48;;6988:260;;;;;:::o;7253:186::-;7312:6;7365:2;7353:9;7344:7;7340:23;7336:32;7333:52;;;7381:1;7378;7371:12;7333:52;7404:29;7423:9;7404:29;:::i;7733:394::-;7810:6;7818;7871:2;7859:9;7850:7;7846:23;7842:32;7839:52;;;7887:1;7884;7877:12;7839:52;7910:29;7929:9;7910:29;:::i;:::-;7900:39;;7990:2;7979:9;7975:18;7962:32;8017:18;8009:6;8006:30;8003:50;;;8049:1;8046;8039:12;8003:50;8072:49;8113:7;8104:6;8093:9;8089:22;8072:49;:::i;:::-;8062:59;;;7733:394;;;;;:::o;8314:328::-;8391:6;8399;8407;8460:2;8448:9;8439:7;8435:23;8431:32;8428:52;;;8476:1;8473;8466:12;8428:52;8499:29;8518:9;8499:29;:::i;:::-;8489:39;;8575:2;8564:9;8560:18;8547:32;8537:42;;8598:38;8632:2;8621:9;8617:18;8598:38;:::i;:::-;8588:48;;8314:328;;;;;:::o;8647:118::-;8733:5;8726:13;8719:21;8712:5;8709:32;8699:60;;8755:1;8752;8745:12;8770:315;8835:6;8843;8896:2;8884:9;8875:7;8871:23;8867:32;8864:52;;;8912:1;8909;8902:12;8864:52;8935:29;8954:9;8935:29;:::i;:::-;8925:39;;9014:2;9003:9;8999:18;8986:32;9027:28;9049:5;9027:28;:::i;:::-;9074:5;9064:15;;;8770:315;;;;;:::o;9090:289::-;9302:3;9287:19;;9315:58;9291:9;9355:6;9315:58;:::i;9384:127::-;9445:10;9440:3;9436:20;9433:1;9426:31;9476:4;9473:1;9466:15;9500:4;9497:1;9490:15;9516:127;9577:10;9572:3;9568:20;9565:1;9558:31;9608:4;9605:1;9598:15;9632:4;9629:1;9622:15;9648:120;9688:1;9714;9704:35;;9719:18;;:::i;:::-;-1:-1:-1;9753:9:1;;9648:120::o;9773:112::-;9805:1;9831;9821:35;;9836:18;;:::i;:::-;-1:-1:-1;9870:9:1;;9773:112::o;9890:136::-;9929:3;9957:5;9947:39;;9966:18;;:::i;:::-;-1:-1:-1;;;10002:18:1;;9890:136::o;10031:168::-;10104:9;;;10135;;10152:15;;;10146:22;;10132:37;10122:71;;10173:18;;:::i;10204:128::-;10271:9;;;10292:11;;;10289:37;;;10306:18;;:::i;10337:127::-;10398:10;10393:3;10389:20;10386:1;10379:31;10429:4;10426:1;10419:15;10453:4;10450:1;10443:15;10469:135;10508:3;10529:17;;;10526:43;;10549:18;;:::i;:::-;-1:-1:-1;10596:1:1;10585:13;;10469:135::o;11303:408::-;11505:2;11487:21;;;11544:2;11524:18;;;11517:30;11583:34;11578:2;11563:18;;11556:62;-1:-1:-1;;;11649:2:1;11634:18;;11627:42;11701:3;11686:19;;11303:408::o;11716:250::-;11801:1;11811:113;11825:6;11822:1;11819:13;11811:113;;;11901:11;;;11895:18;11882:11;;;11875:39;11847:2;11840:10;11811:113;;;-1:-1:-1;;11958:1:1;11940:16;;11933:27;11716:250::o;11971:270::-;12012:3;12050:5;12044:12;12077:6;12072:3;12065:19;12093:76;12162:6;12155:4;12150:3;12146:14;12139:4;12132:5;12128:16;12093:76;:::i;:::-;12223:2;12202:15;-1:-1:-1;;12198:29:1;12189:39;;;;12230:4;12185:50;;11971:270;-1:-1:-1;;11971:270:1:o;12246:385::-;12431:25;;;-1:-1:-1;;;;;12492:32:1;;12487:2;12472:18;;12465:60;12561:2;12556;12541:18;;12534:30;;;-1:-1:-1;;12581:44:1;;12606:18;;12598:6;12581:44;:::i;12636:184::-;12706:6;12759:2;12747:9;12738:7;12734:23;12730:32;12727:52;;;12775:1;12772;12765:12;12727:52;-1:-1:-1;12798:16:1;;12636:184;-1:-1:-1;12636:184:1:o;14676:245::-;14743:6;14796:2;14784:9;14775:7;14771:23;14767:32;14764:52;;;14812:1;14809;14802:12;14764:52;14844:9;14838:16;14863:28;14885:5;14863:28;:::i;15280:408::-;15482:2;15464:21;;;15521:2;15501:18;;;15494:30;15560:34;15555:2;15540:18;;15533:62;-1:-1:-1;;;15626:2:1;15611:18;;15604:42;15678:3;15663:19;;15280:408::o;15693:::-;15895:2;15877:21;;;15934:2;15914:18;;;15907:30;15973:34;15968:2;15953:18;;15946:62;-1:-1:-1;;;16039:2:1;16024:18;;16017:42;16091:3;16076:19;;15693:408::o;21084:245::-;21163:6;21171;21224:2;21212:9;21203:7;21199:23;21195:32;21192:52;;;21240:1;21237;21230:12;21192:52;-1:-1:-1;;21263:16:1;;21319:2;21304:18;;;21298:25;21263:16;;21298:25;;-1:-1:-1;21084:245:1:o;23035:407::-;23237:2;23219:21;;;23276:2;23256:18;;;23249:30;23315:34;23310:2;23295:18;;23288:62;-1:-1:-1;;;23381:2:1;23366:18;;23359:41;23432:3;23417:19;;23035:407::o;26073:287::-;26202:3;26240:6;26234:13;26256:66;26315:6;26310:3;26303:4;26295:6;26291:17;26256:66;:::i;:::-;26338:16;;;;;26073:287;-1:-1:-1;;26073:287:1:o;26772:219::-;26921:2;26910:9;26903:21;26884:4;26941:44;26981:2;26970:9;26966:18;26958:6;26941:44;:::i
Swarm Source
ipfs://1b26359652ac3cac02e785727b59c67ed9e375db191c888c5ed820f188863040
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.