Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 19890260 | 59 days ago | IN | Create: InVault_E1 | 0 ETH | 0.03071042 |
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:
InVault_E1
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../InceptionVault.sol"; import "../../../interfaces/IStEth.sol"; /// @author The InceptionLRT team contract InVault_E1 is InceptionVault { /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( string memory vaultName, address operatorAddress, IStrategyManager _strategyManager, IInceptionToken _inceptionToken, IStrategy _assetStrategy ) external initializer { __InceptionVault_init( vaultName, operatorAddress, _strategyManager, _inceptionToken, _assetStrategy ); } function _getAssetWithdrawAmount( uint256 amount ) internal pure override returns (uint256) { return amount + 1; } function _getAssetReceivedAmount( uint256 amount ) internal pure override returns (uint256) { return amount - 1; } function _getAssetRedeemAmount( uint256 amount ) internal pure override returns (uint256) { return amount + 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.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] * ```solidity * 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.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 Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @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, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(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); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol) pragma solidity ^0.8.0; import "./IBeacon.sol"; import "../Proxy.sol"; import "../ERC1967/ERC1967Upgrade.sol"; /** * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}. * * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't * conflict with the storage layout of the implementation behind the proxy. * * _Available since v3.4._ */ contract BeaconProxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the proxy with `beacon`. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity * constructor. * * Requirements: * * - `beacon` must be a contract with the interface {IBeacon}. */ constructor(address beacon, bytes memory data) payable { _upgradeBeaconToAndCall(beacon, data, false); } /** * @dev Returns the current beacon address. */ function _beacon() internal view virtual returns (address) { return _getBeacon(); } /** * @dev Returns the current implementation address of the associated beacon. */ function _implementation() internal view virtual override returns (address) { return IBeacon(_getBeacon()).implementation(); } /** * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. * * Requirements: * * - `beacon` must be a contract. * - The implementation returned by `beacon` must be a contract. */ function _setBeacon(address beacon, bytes memory data) internal virtual { _upgradeBeaconToAndCall(beacon, data, false); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/IERC1967.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @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._ */ abstract contract ERC1967Upgrade is IERC1967 { // 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 StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.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) { Address.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 (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(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 StorageSlot.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"); StorageSlot.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 StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.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) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overridden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @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]. * * CAUTION: See Security Considerations above. */ 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 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(IERC20 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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit 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(IERC20 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"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation 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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @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, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(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); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * 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`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes 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 } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../../interfaces/IInceptionAssetHandler.sol"; import "../../interfaces/IInceptionVaultErrors.sol"; import "../lib/Convert.sol"; /// @author The InceptionLRT team /// @title The InceptionAssetsHandler contract /// @dev Handles operations with the corresponding asset contract InceptionAssetsHandler is PausableUpgradeable, ReentrancyGuardUpgradeable, OwnableUpgradeable, IInceptionVaultErrors, IInceptionAssetHandler { using SafeERC20 for IERC20; IERC20 internal _asset; uint256[49] private __reserver; function __InceptionAssetsHandler_init( IERC20 assetAddress ) internal onlyInitializing { __Pausable_init(); __ReentrancyGuard_init(); _asset = assetAddress; } /// @dev returns the balance of iVault in the asset function totalAssets() public view override returns (uint256) { return _asset.balanceOf(address(this)); } function _transferAssetFrom(address staker, uint256 amount) internal { if (!_asset.transferFrom(staker, address(this), amount)) { revert TransferAssetFromFailed(address(_asset)); } } function _transferAssetTo(address receiver, uint256 amount) internal { if (!_asset.transfer(receiver, amount)) { revert TransferAssetFailed(address(_asset)); } } /// @dev The functions below serve the proper withdrawal and claiming operations /// @notice Since a particular LST loses some wei on each transfer, /// this needs to be taken into account function _getAssetWithdrawAmount( uint256 amount ) internal view virtual returns (uint256) { return amount; } function _getAssetReceivedAmount( uint256 amount ) internal view virtual returns (uint256) { return amount; } function _getAssetRedeemAmount( uint256 amount ) internal view virtual returns (uint256) { return amount; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../assets-handler/InceptionAssetsHandler.sol"; import "../../interfaces/IStrategyManager.sol"; import "../../interfaces/IDelegationManager.sol"; import "../../interfaces/IEigenLayerHandler.sol"; import "../../interfaces/IInceptionRestaker.sol"; /// @author The InceptionLRT team /// @title The EigenLayerHandler contract /// @dev Serves communication with external EigenLayer protocol /// @dev Specifically, this includes depositing, and handling withdrawal requests contract EigenLayerHandler is InceptionAssetsHandler, IEigenLayerHandler { IStrategyManager public strategyManager; IStrategy public strategy; uint256 public epoch; /// @dev inception operator address internal _operator; /// @dev represents the pending amount to be redeemed by claimers, /// @notice + amount to undelegate from EigenLayer uint256 public totalAmountToWithdraw; /// @dev represents the amount pending processing until it is claimed /// @dev amount measured in asset uint256 internal _pendingWithdrawalAmount; IDelegationManager public delegationManager; Withdrawal[] public claimerWithdrawalsQueue; address internal constant _MOCK_ADDRESS = 0x0000000000000000000000000012345000000000; /// @dev heap reserved for the claimers uint256 public redeemReservedAmount; /// @dev EigenLayer operator -> inception staker mapping(address => address) internal _operatorRestakers; address[] public restakers; /// @dev constants are not stored in the storage uint256[50 - 11] private __reserver; modifier onlyOperator() { require( msg.sender == _operator, "EigenLayerHandler: only operator allowed" ); _; } function __EigenLayerHandler_init( IStrategyManager _strategyManager, IStrategy _assetStrategy ) internal onlyInitializing { strategyManager = _strategyManager; strategy = _assetStrategy; __InceptionAssetsHandler_init(_assetStrategy.underlyingToken()); // approve spending by strategyManager require( _asset.approve(address(strategyManager), type(uint256).max), "EigenLayerHandler: approve failed" ); } /*////////////////////////////// ////// Deposit functions ////// ////////////////////////////*/ /// @dev checks whether it's still possible to deposit into the strategy function _beforeDepositAssetIntoStrategy(uint256 amount) internal view { if (amount > totalAssets() - redeemReservedAmount) { revert InsufficientCapacity(totalAssets()); } (uint256 maxPerDeposit, uint256 maxTotalDeposits) = strategy .getTVLLimits(); if (amount > maxPerDeposit) { revert ExceedsMaxPerDeposit(maxPerDeposit, amount); } uint256 currentBalance = _asset.balanceOf(address(strategy)); if (currentBalance + amount > maxTotalDeposits) { revert ExceedsMaxTotalDeposited(maxTotalDeposits, currentBalance); } } /// @dev deposits asset to the corresponding strategy function _depositAssetIntoStrategy( address restaker, uint256 amount ) internal { _asset.approve(restaker, amount); IInceptionRestaker(restaker).depositAssetIntoStrategy(amount); emit DepositedToEL(restaker, amount); } function depositAssetIntoStrategyFromVault( uint256 amount ) external nonReentrant onlyOperator { _beforeDepositAssetIntoStrategy(amount); strategyManager.depositIntoStrategy(strategy, _asset, amount); emit DepositedToEL(address(this), amount); } /// @dev deposits asset to the corresponding strategy function _depositAssetIntoStrategyFromVault(uint256 amount) internal { strategyManager.depositIntoStrategy(strategy, _asset, amount); } /// @dev delegates assets held in the strategy to the EL operator. function _delegateToOperator( address restaker, address elOperator, bytes32 approverSalt, IDelegationManager.SignatureWithExpiry memory approverSignatureAndExpiry ) internal { IInceptionRestaker(restaker).delegateToOperator( elOperator, approverSalt, approverSignatureAndExpiry ); } function _delegateToOperatorFromVault( address elOperator, bytes32 approverSalt, IDelegationManager.SignatureWithExpiry memory approverSignatureAndExpiry ) internal { delegationManager.delegateTo( elOperator, approverSignatureAndExpiry, approverSalt ); } /*///////////////////////////////// ////// Withdrawal functions ////// ///////////////////////////////*/ /// @dev performs creating a withdrawal request from EigenLayer /// @dev requires a specific amount to withdraw function undelegateFrom( address elOperatorAddress, uint256 amount ) external whenNotPaused nonReentrant onlyOperator { address stakerAddress = _operatorRestakers[elOperatorAddress]; if (stakerAddress == address(0)) { revert OperatorNotRegistered(); } if (stakerAddress == _MOCK_ADDRESS) { revert NullParams(); } uint256 nonce = delegationManager.cumulativeWithdrawalsQueued( stakerAddress ); uint256 totalAssetSharesInEL = strategyManager.stakerStrategyShares( stakerAddress, strategy ); uint256 shares = strategy.underlyingToSharesView(amount); // we need to withdraw the remaining dust from EigenLayer if (totalAssetSharesInEL < shares + 5) { shares = totalAssetSharesInEL; } amount = strategy.sharesToUnderlyingView(shares); emit StartWithdrawal( stakerAddress, strategy, shares, uint32(block.number), elOperatorAddress, nonce ); _pendingWithdrawalAmount += amount; IInceptionRestaker(stakerAddress).withdrawFromEL(shares); } /// @dev performs creating a withdrawal request from EigenLayer /// @dev requires a specific amount to withdraw function undelegateVault( uint256 amount ) external whenNotPaused nonReentrant onlyOperator { address staker = address(this); uint256 nonce = delegationManager.cumulativeWithdrawalsQueued(staker); uint256 totalAssetSharesInEL = strategyManager.stakerStrategyShares( staker, strategy ); uint256 shares = strategy.underlyingToSharesView(amount); // we need to withdraw the remaining dust from EigenLayer if (totalAssetSharesInEL < shares + 5) { shares = totalAssetSharesInEL; } amount = strategy.sharesToUnderlyingView(shares); uint256[] memory sharesToWithdraw = new uint256[](1); IStrategy[] memory strategies = new IStrategy[](1); strategies[0] = strategy; sharesToWithdraw[0] = shares; IDelegationManager.QueuedWithdrawalParams[] memory withdrawals = new IDelegationManager.QueuedWithdrawalParams[]( 1 ); withdrawals[0] = IDelegationManager.QueuedWithdrawalParams({ strategies: strategies, shares: sharesToWithdraw, withdrawer: address(this) }); _pendingWithdrawalAmount += amount; delegationManager.queueWithdrawals(withdrawals); emit StartWithdrawal( staker, strategy, shares, uint32(block.number), delegationManager.delegatedTo(staker), nonce ); } /// @dev claims completed withdrawals from EigenLayer, if they exist function claimCompletedWithdrawals( address restaker, IDelegationManager.Withdrawal[] calldata withdrawals ) public whenNotPaused nonReentrant { uint256 withdrawalsNum = withdrawals.length; IERC20[][] memory tokens = new IERC20[][](withdrawalsNum); uint256[] memory middlewareTimesIndexes = new uint256[](withdrawalsNum); bool[] memory receiveAsTokens = new bool[](withdrawalsNum); for (uint256 i = 0; i < withdrawalsNum; ) { tokens[i] = new IERC20[](1); tokens[i][0] = _asset; receiveAsTokens[i] = true; unchecked { i++; } } uint256 withdrawnAmount; if (restaker == address(this)) { withdrawnAmount = _claimCompletedWithdrawalsForVault( withdrawals, tokens, middlewareTimesIndexes, receiveAsTokens ); } else { if (!_restakerExists(restaker)) revert RestakerNotRegistered(); withdrawnAmount = IInceptionRestaker(restaker).claimWithdrawals( withdrawals, tokens, middlewareTimesIndexes, receiveAsTokens ); } emit WithdrawalClaimed(withdrawnAmount); _pendingWithdrawalAmount = _pendingWithdrawalAmount < withdrawnAmount ? 0 : _pendingWithdrawalAmount - withdrawnAmount; if (_pendingWithdrawalAmount < 7) { _pendingWithdrawalAmount = 0; } _updateEpoch(); } function _claimCompletedWithdrawalsForVault( IDelegationManager.Withdrawal[] memory withdrawals, IERC20[][] memory tokens, uint256[] memory middlewareTimesIndexes, bool[] memory receiveAsTokens ) internal returns (uint256) { uint256 balanceBefore = _asset.balanceOf(address(this)); delegationManager.completeQueuedWithdrawals( withdrawals, tokens, middlewareTimesIndexes, receiveAsTokens ); // send tokens to the vault uint256 withdrawnAmount = _asset.balanceOf(address(this)) - balanceBefore; return withdrawnAmount; } function updateEpoch() external whenNotPaused { _updateEpoch(); } /** * @dev let's calculate how many withdrawals we can cover with the withdrawnAmount * @dev #init state: * - balance of the vault: X * - epoch: means that the vault can handle the withdrawal queue up to the epoch index * withdrawalQueue[... : epoch]; * * @dev #new state: * - balance of the vault: X + withdrawnAmount * - we need to recalculate a new value for epoch, new_epoch, to cover withdrawals: * withdrawalQueue[epoch : new_epoch]; */ function _updateEpoch() internal { uint256 withdrawalsNum = claimerWithdrawalsQueue.length; uint256 availableBalance = totalAssets() - redeemReservedAmount; for (uint256 i = epoch; i < withdrawalsNum; ) { uint256 amount = claimerWithdrawalsQueue[i].amount; unchecked { if (amount > availableBalance) { break; } redeemReservedAmount += amount; availableBalance -= amount; epoch++; i++; } } } function _restakerExists( address restakerAddress ) internal view returns (bool) { uint256 numOfRestakers = restakers.length; for (uint256 i = 0; i < numOfRestakers; ) { if (restakerAddress == restakers[i]) return true; unchecked { ++i; } } return false; } /*////////////////////////// ////// GET functions ////// ////////////////////////*/ function getPendingWithdrawalAmountFromEL() public view returns (uint256 total) { return _pendingWithdrawalAmount; } /*////////////////////////// ////// SET functions ////// ////////////////////////*/ function setDelegationManager( IDelegationManager newDelegationManager ) external onlyOwner { if (address(delegationManager) != address(0)) revert DelegationManagerImmutable(); emit DelegationManagerChanged( address(delegationManager), address(newDelegationManager) ); delegationManager = newDelegationManager; } function forceUndelegateRecovery( uint256 amount, address restaker ) external onlyOperator { if (restaker == address(0)) revert NullParams(); for (uint256 i = 0; i < restakers.length; ) { if ( restakers[i] == restaker && !delegationManager.isDelegated(restakers[i]) ) { restakers[i] == _MOCK_ADDRESS; break; } unchecked { ++i; } } _pendingWithdrawalAmount += amount; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; library Convert { function saturatingMultiply( uint256 a, uint256 b ) internal pure returns (uint256) { unchecked { if (a == 0) return 0; uint256 c = a * b; if (c / a != b) return type(uint256).max; return c; } } function saturatingAdd( uint256 a, uint256 b ) internal pure returns (uint256) { unchecked { uint256 c = a + b; if (c < a) return type(uint256).max; return c; } } // Preconditions: // 1. a may be arbitrary (up to 2 ** 256 - 1) // 2. b * c < 2 ** 256 // Returned value: min(floor((a * b) / c), 2 ** 256 - 1) function multiplyAndDivideFloor( uint256 a, uint256 b, uint256 c ) internal pure returns (uint256) { return saturatingAdd( saturatingMultiply(a / c, b), ((a % c) * b) / c // can't fail because of assumption 2. ); } // Preconditions: // 1. a may be arbitrary (up to 2 ** 256 - 1) // 2. b * c < 2 ** 256 // Returned value: min(ceil((a * b) / c), 2 ** 256 - 1) function multiplyAndDivideCeil( uint256 a, uint256 b, uint256 c ) internal pure returns (uint256) { require(c != 0, "c == 0"); return saturatingAdd( saturatingMultiply(a / c, b), ((a % c) * b + (c - 1)) / c // can't fail because of assumption 2. ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; import "../eigenlayer-handler/EigenLayerHandler.sol"; import "../../interfaces/IOwnable.sol"; import "../../interfaces/IInceptionVault.sol"; import "../../interfaces/IInceptionToken.sol"; import "../../interfaces/IRebalanceStrategy.sol"; import "../../interfaces/IDelegationManager.sol"; /// @author The InceptionLRT team /// @title The InceptionVault contract /// @notice Aims to maximize the profit of EigenLayer for a certain asset. contract InceptionVault is IInceptionVault, EigenLayerHandler { /// @dev Inception restaking token IInceptionToken public inceptionToken; /// @dev Reduces rounding issues uint256 public minAmount; mapping(address => Withdrawal) private _claimerWithdrawals; /// @dev the unique InceptionVault name string public name; /// @dev Factory variables address private _stakerImplementation; function __InceptionVault_init( string memory vaultName, address operatorAddress, IStrategyManager _strategyManager, IInceptionToken _inceptionToken, IStrategy _assetStrategy ) internal { __Ownable_init(); __EigenLayerHandler_init(_strategyManager, _assetStrategy); name = vaultName; _operator = operatorAddress; inceptionToken = _inceptionToken; minAmount = 100; } /*////////////////////////////// ////// Deposit functions ////// ////////////////////////////*/ function __beforeDeposit(address receiver, uint256 amount) internal view { if (receiver == address(0)) revert NullParams(); require( amount >= minAmount, "InceptionVault: deposited less than min amount" ); if (!_verifyDelegated()) revert InceptionOnPause(); } function __afterDeposit(uint256 iShares) internal pure { require(iShares > 0, "InceptionVault: result iShares 0"); } /// @dev Transfers the msg.sender's assets to the vault. /// @dev Mints Inception tokens in accordance with the current ratio. /// @dev Issues the tokens to the specified receiver address. function deposit( uint256 amount, address receiver ) public nonReentrant whenNotPaused returns (uint256) { return _deposit(amount, msg.sender, receiver); } /// @notice The deposit function but with a referral code function depositWithReferral( uint256 amount, address receiver, bytes32 code ) public nonReentrant whenNotPaused returns (uint256) { emit ReferralCode(code); return _deposit(amount, msg.sender, receiver); } function _deposit( uint256 amount, address sender, address receiver ) internal returns (uint256) { uint256 currentRatio = ratio(); // transfers assets from the sender and returns the received amount // the actual received amount might slightly differ from the specified amount, // approximately by -2 wei __beforeDeposit(receiver, amount); uint256 depositedBefore = totalAssets(); // get the amount from the sender _transferAssetFrom(sender, amount); amount = totalAssets() - depositedBefore; uint256 iShares = Convert.multiplyAndDivideFloor( amount, currentRatio, 1e18 ); inceptionToken.mint(receiver, iShares); __afterDeposit(iShares); emit Deposit(sender, receiver, amount, iShares); return iShares; } /*///////////////////////////////// ////// Delegation functions ////// ///////////////////////////////*/ function delegateToOperator( uint256 amount, address elOperator, bytes32 approverSalt, IDelegationManager.SignatureWithExpiry memory approverSignatureAndExpiry ) external nonReentrant whenNotPaused onlyOperator { if (elOperator == address(0)) { revert NullParams(); } _beforeDepositAssetIntoStrategy(amount); // try to find a restaker for the specific EL operator address restaker = _operatorRestakers[elOperator]; if (restaker == address(0)) { revert OperatorNotRegistered(); } bool delegate = false; if (restaker == _MOCK_ADDRESS) { delegate = true; // deploy a new restaker restaker = _deployNewStub(); _operatorRestakers[elOperator] = restaker; restakers.push(restaker); } _depositAssetIntoStrategy(restaker, amount); if (delegate) _delegateToOperator( restaker, elOperator, approverSalt, approverSignatureAndExpiry ); emit DelegatedTo(restaker, elOperator); } function delegateToOperatorFromVault( address elOperator, bytes32 approverSalt, IDelegationManager.SignatureWithExpiry memory approverSignatureAndExpiry ) external nonReentrant whenNotPaused onlyOperator { if (elOperator == address(0)) { revert NullParams(); } if (delegationManager.delegatedTo(address(this)) != address(0)) revert AlreadyDelegated(); _delegateToOperatorFromVault( elOperator, approverSalt, approverSignatureAndExpiry ); emit DelegatedTo(address(this), elOperator); } /*/////////////////////////////////////// ///////// Withdrawal functions ///////// /////////////////////////////////////*/ function __beforeWithdraw(address receiver, uint256 iShares) internal view { if (iShares == 0) { revert NullParams(); } if (receiver == address(0)) { revert NullParams(); } if (!_verifyDelegated()) revert InceptionOnPause(); } /// @dev Performs burning iToken from mgs.sender /// @dev Creates a withdrawal requests based on the current ratio /// @param iShares is measured in Inception token(shares) function withdraw( uint256 iShares, address receiver ) external whenNotPaused nonReentrant { __beforeWithdraw(receiver, iShares); address claimer = msg.sender; uint256 amount = Convert.multiplyAndDivideFloor(iShares, 1e18, ratio()); require( amount >= minAmount, "InceptionVault: amount is less than the minimum withdrawal" ); // burn Inception token in view of the current ratio inceptionToken.burn(claimer, iShares); // update global state and claimer's state totalAmountToWithdraw += amount; Withdrawal storage genRequest = _claimerWithdrawals[receiver]; genRequest.amount += _getAssetReceivedAmount(amount); claimerWithdrawalsQueue.push( Withdrawal({ epoch: claimerWithdrawalsQueue.length, receiver: receiver, amount: _getAssetReceivedAmount(amount) }) ); emit Withdraw(claimer, receiver, claimer, amount, iShares); } function redeem(address receiver) public whenNotPaused nonReentrant { (bool isAble, uint256[] memory availableWithdrawals) = isAbleToRedeem( receiver ); require(isAble, "InceptionVault: redeem can not be proceed"); uint256 numOfWithdrawals = availableWithdrawals.length; uint256[] memory redeemedWithdrawals = new uint256[](numOfWithdrawals); Withdrawal storage genRequest = _claimerWithdrawals[receiver]; uint256 redeemedAmount; for (uint256 i = 0; i < numOfWithdrawals; ) { uint256 withdrawalNum = availableWithdrawals[i]; Withdrawal memory request = claimerWithdrawalsQueue[withdrawalNum]; uint256 amount = request.amount; // update the genRequest and the global state genRequest.amount -= amount; totalAmountToWithdraw -= _getAssetWithdrawAmount(amount); redeemReservedAmount -= amount; redeemedAmount += amount; redeemedWithdrawals[i] = withdrawalNum; delete claimerWithdrawalsQueue[availableWithdrawals[i]]; unchecked { ++i; } } // let's update the lowest epoch associated with the claimer genRequest.epoch = availableWithdrawals[numOfWithdrawals - 1]; _transferAssetTo(receiver, redeemedAmount); emit RedeemedRequests(redeemedWithdrawals); emit Redeem(msg.sender, receiver, redeemedAmount); } /*////////////////////////////// ////// Factory functions ////// ////////////////////////////*/ function _deployNewStub() internal returns (address) { if (_stakerImplementation == address(0)) { revert ImplementationNotSet(); } // deploy new beacon proxy and do init call bytes memory data = abi.encodeWithSignature( "initialize(address,address,address,address)", delegationManager, strategyManager, strategy, _operator ); address deployedAddress = address(new BeaconProxy(address(this), data)); IOwnable asOwnable = IOwnable(deployedAddress); asOwnable.transferOwnership(owner()); emit RestakerDeployed(deployedAddress); return deployedAddress; } function implementation() external view returns (address) { return _stakerImplementation; } function upgradeTo( address newImplementation ) external whenNotPaused onlyOwner { require( Address.isContract(newImplementation), "InceptionVault: implementation is not a contract" ); emit ImplementationUpgraded(_stakerImplementation, newImplementation); _stakerImplementation = newImplementation; } function isAbleToRedeem( address claimer ) public view returns (bool able, uint256[] memory) { // get the general request uint256 index; Withdrawal memory genRequest = _claimerWithdrawals[claimer]; uint256 from = genRequest.epoch; uint256[] memory availableWithdrawals = new uint256[](epoch - from); if (genRequest.amount == 0) { return (false, availableWithdrawals); } for (uint256 i = 0; i < epoch; ) { if (claimerWithdrawalsQueue[i].receiver == claimer) { able = true; availableWithdrawals[index] = i; ++index; } unchecked { ++i; } } // decrease arrays if (availableWithdrawals.length - index > 0) { assembly { mstore(availableWithdrawals, index) } } return (able, availableWithdrawals); } function ratio() public view returns (uint256) { uint256 totalDeposited = getTotalDeposited(); uint256 totalSupply = IERC20(address(inceptionToken)).totalSupply(); // take into account the pending withdrawn amount uint256 denominator = totalDeposited < totalAmountToWithdraw ? 0 : totalDeposited - totalAmountToWithdraw; if (denominator == 0 || totalSupply == 0) return 1e18; return Convert.multiplyAndDivideCeil(totalSupply, 1e18, denominator); } /// @dev returns the total deposited into asset strategy function getTotalDeposited() public view returns (uint256) { return getTotalDelegated() + totalAssets() + _pendingWithdrawalAmount; } function getTotalDelegated() public view returns (uint256 total) { uint256 stakersNum = restakers.length; for (uint256 i = 0; i < stakersNum; ) { if (restakers[i] == address(0)) { continue; } total += strategy.userUnderlyingView(restakers[i]); unchecked { ++i; } } return total + strategy.userUnderlyingView(address(this)); } function _verifyDelegated() internal view returns (bool) { for (uint256 i = 0; i < restakers.length; ) { if (restakers[i] == address(0)) { unchecked { ++i; } continue; } if (!delegationManager.isDelegated(restakers[i])) return false; unchecked { ++i; } } if ( strategy.userUnderlyingView(address(this)) > 0 && !delegationManager.isDelegated(address(this)) ) return false; return true; } function getDelegatedTo(address elOperator) public view returns (uint256) { return strategy.userUnderlyingView(_operatorRestakers[elOperator]); } function getPendingWithdrawalOf( address claimer ) public view returns (uint256) { return _claimerWithdrawals[claimer].amount; } /*////////////////////////////// ////// Convert functions ////// ////////////////////////////*/ function convertToShares( uint256 assets ) public view returns (uint256 shares) { return Convert.multiplyAndDivideFloor(assets, ratio(), 1e18); } function convertToAssets( uint256 iShares ) public view returns (uint256 assets) { return Convert.multiplyAndDivideFloor(iShares, 1e18, ratio()); } /*////////////////////////// ////// SET functions ////// ////////////////////////*/ function setOperator(address newOperator) external onlyOwner { if (newOperator == address(0)) { revert NullParams(); } emit OperatorChanged(_operator, newOperator); _operator = newOperator; } function setMinAmount(uint256 newMinAmount) external onlyOwner { emit MinAmountChanged(minAmount, newMinAmount); minAmount = newMinAmount; } function setName(string memory newVaultName) external onlyOwner { if (bytes(newVaultName).length == 0) { revert NullParams(); } emit NameChanged(name, newVaultName); name = newVaultName; } function addELOperator(address newELOperator) external onlyOwner { require( delegationManager.isOperator(newELOperator), "InceptionVault: it is not an EL operator" ); require( _operatorRestakers[newELOperator] == address(0), "InceptionVault: operator already exists" ); _operatorRestakers[newELOperator] = _MOCK_ADDRESS; emit ELOperatorAdded(newELOperator); } /*/////////////////////////////// ////// Pausable functions ////// /////////////////////////////*/ function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./IStrategy.sol"; interface IDelegationManager { // @notice Struct that bundles together a signature and an expiration time for the signature. Used primarily for stack management. struct SignatureWithExpiry { // the signature itself, formatted as a single bytes object bytes signature; // the expiration timestamp (UTC) of the signature uint256 expiry; } // @notice Struct that bundles together a signature, a salt for uniqueness, and an expiration time for the signature. Used primarily for stack management. struct SignatureWithSaltAndExpiry { // the signature itself, formatted as a single bytes object bytes signature; // the salt used to generate the signature bytes32 salt; // the expiration timestamp (UTC) of the signature uint256 expiry; } struct QueuedWithdrawalParams { // Array of strategies that the QueuedWithdrawal contains IStrategy[] strategies; // Array containing the amount of shares in each Strategy in the `strategies` array uint256[] shares; // The address of the withdrawer address withdrawer; } struct Withdrawal { // The address that originated the Withdrawal address staker; // The address that the staker was delegated to at the time that the Withdrawal was created address delegatedTo; // The address that can complete the Withdrawal + will receive funds when completing the withdrawal address withdrawer; // Nonce used to guarantee that otherwise identical withdrawals have unique hashes uint256 nonce; // Block number when the Withdrawal was created uint32 startBlock; // Array of strategies that the Withdrawal contains IStrategy[] strategies; // Array containing the amount of shares in each Strategy in the `strategies` array uint256[] shares; } function delegateTo( address operator, SignatureWithExpiry memory approverSignatureAndExpiry, bytes32 approverSalt ) external; function undelegate(address staker) external; event WithdrawalQueued(bytes32 withdrawalRoot, Withdrawal withdrawal); function completeQueuedWithdrawal( Withdrawal calldata withdrawal, IERC20[] calldata tokens, uint256 middlewareTimesIndex, bool receiveAsTokens ) external; function completeQueuedWithdrawals( Withdrawal[] calldata withdrawals, IERC20[][] calldata tokens, uint256[] calldata middlewareTimesIndexes, bool[] calldata receiveAsTokens ) external; function queueWithdrawals( QueuedWithdrawalParams[] calldata queuedWithdrawalParams ) external returns (bytes32[] memory); function delegatedTo(address staker) external view returns (address); function operatorShares( address operator, address strategy ) external view returns (uint256); function cumulativeWithdrawalsQueued( address staker ) external view returns (uint256); function withdrawalDelayBlocks() external view returns (uint256); function isOperator(address operator) external view returns (bool); function isDelegated(address staker) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./IStrategyManager.sol"; interface IEigenLayerHandler { /// @dev Epoch represents the period of the rebalancing process /// @dev Receiver is a receiver of assets in claim() /// @dev Amount represents the exact amount of the asset to be claimed struct Withdrawal { uint256 epoch; address receiver; uint256 amount; } event StartWithdrawal( address indexed stakerAddress, IStrategy strategy, uint256 shares, uint32 withdrawalStartBlock, address delegatedAddress, uint256 nonce ); event DepositedToEL(address indexed stakerAddress, uint256 amount); event DelegatedTo( address indexed stakerAddress, address indexed operatorAddress ); event Withdrawn(address asset, uint256 shares, uint256 ethAmount); event WithdrawalClaimed(uint256 totalAmount); event DelegationManagerChanged(address prevValue, address newValue); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IInceptionAssetHandler { /*////////////////////////// ////// GET functions ////// ////////////////////////*/ /// @dev returns total balance of Vault in the asset function totalAssets() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./IDelegationManager.sol"; interface IInceptionRestaker { event StartWithdrawal( address indexed stakerAddress, bytes32 withdrawalRoot, IStrategy[] strategies, uint256[] shares, uint32 withdrawalStartBlock, address delegatedAddress, uint256 nonce ); event Withdrawal( bytes32 withdrawalRoot, IStrategy[] strategies, uint256[] shares, uint32 withdrawalStartBlock ); function depositAssetIntoStrategy(uint256 amount) external; function delegateToOperator( address operator, bytes32 approverSalt, IDelegationManager.SignatureWithExpiry memory approverSignatureAndExpiry ) external; function withdrawFromEL(uint256 shares) external; function claimWithdrawals( IDelegationManager.Withdrawal[] calldata withdrawals, IERC20[][] calldata tokens, uint256[] calldata middlewareTimesIndexes, bool[] calldata receiveAsTokens ) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IInceptionToken { event VaultChanged(address prevValue, address newValue); event Paused(address account); event Unpaused(address account); function mint(address account, uint256 amount) external; function burn(address account, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./IInceptionToken.sol"; interface IInceptionVault { /*/////////////////// ////// Events ////// /////////////////*/ event Deposit( address indexed sender, address indexed receiver, uint256 amount, uint256 iShares ); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 amount, uint256 iShares ); event Redeem( address indexed sender, address indexed receiver, uint256 amount ); event RedeemedRequests(uint256[] withdrawals); event WithdrawalQueued( address depositor, uint96 nonce, address withdrawer, address delegatedAddress, bytes32 withdrawalRoot ); event OperatorChanged(address prevValue, address newValue); event DepositFeeChanged(uint256 prevValue, uint256 newValue); event MinAmountChanged(uint256 prevValue, uint256 newValue); event ELOperatorAdded(address indexed newELOperator); event RestakerDeployed(address indexed restaker); event ImplementationUpgraded(address prevValue, address newValue); event NameChanged(string prevValue, string newValue); event ReferralCode(bytes32 indexed code); function inceptionToken() external view returns (IInceptionToken); function ratio() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IInceptionVaultErrors { error TransferAssetFailed(address assetAddress); error TransferAssetFromFailed(address assetAddress); error InsufficientCapacity(uint256 capacity); error InceptionOnPause(); error InconsistentData(); error NullParams(); error WithdrawFutile(); error OperatorNotRegistered(); error RestakerNotRegistered(); error ImplementationNotSet(); error NotEigenLayerOperator(); error EigenLayerOperatorAlreadyExists(); error AlreadyDelegated(); error DelegationManagerImmutable(); /// TVL errors error ExceedsMaxPerDeposit(uint256 max, uint256 amount); error ExceedsMaxTotalDeposited(uint256 max, uint256 amount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IOwnable { function transferOwnership(address newOwner) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IRebalanceStrategy { function rebalance(bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IStEth is IERC20 { function sharesOf(address accounts) external returns (uint256); function getPooledEthByShares( uint256 _sharesAmount ) external view returns (uint256); function getSharesByPooledEth( uint256 _ethAmount ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IStrategy { function deposit(IERC20 token, uint256 amount) external returns (uint256); function withdraw( address depositor, IERC20 token, uint256 amountShares ) external; function sharesToUnderlying( uint256 amountShares ) external returns (uint256); function underlyingToShares( uint256 amountUnderlying ) external returns (uint256); function userUnderlying(address user) external returns (uint256); function sharesToUnderlyingView( uint256 amountShares ) external view returns (uint256); function underlyingToSharesView( uint256 amountUnderlying ) external view returns (uint256); /** * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in * this strategy. In contrast to `userUnderlying`, this function guarantees no state modifications */ function userUnderlyingView(address user) external view returns (uint256); /// @notice The underlying token for shares in this Strategy function underlyingToken() external view returns (IERC20); /// @notice The total number of extant shares in this Strategy function totalShares() external view returns (uint256); /// @notice Returns either a brief string explaining the strategy's goal & purpose, or a link to metadata that explains in more detail. function explanation() external view returns (string memory); /// @notice Simple getter function that returns the current values of `maxPerDeposit` and `maxTotalDeposits`. function getTVLLimits() external view returns (uint256, uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./IStrategy.sol"; interface IStrategyManager { struct WithdrawerAndNonce { address withdrawer; uint96 nonce; } struct QueuedWithdrawal { IStrategy[] strategies; uint256[] shares; address depositor; WithdrawerAndNonce withdrawerAndNonce; uint32 withdrawalStartBlock; address delegatedAddress; } function withdrawalRootPending(bytes32) external returns (bool); function depositIntoStrategy( IStrategy strategy, IERC20 token, uint256 amount ) external returns (uint256 shares); function stakerStrategyShares( address user, IStrategy strategy ) external view returns (uint256 shares); function getDeposits( address depositor ) external view returns (IStrategy[] memory, uint256[] memory); function stakerStrategyListLength( address staker ) external view returns (uint256); function queueWithdrawal( uint256[] calldata strategyIndexes, IStrategy[] calldata strategies, uint256[] calldata shares, address withdrawer, bool undelegateIfPossible ) external returns (bytes32); function completeQueuedWithdrawal( QueuedWithdrawal calldata queuedWithdrawal, IERC20[] calldata tokens, uint256 middlewareTimesIndex, bool receiveAsTokens ) external; function completeQueuedWithdrawals( QueuedWithdrawal[] calldata queuedWithdrawals, IERC20[][] calldata tokens, uint256[] calldata middlewareTimesIndexes, bool[] calldata receiveAsTokens ) external; function slashShares( address slashedAddress, address recipient, IStrategy[] calldata strategies, IERC20[] calldata tokens, uint256[] calldata strategyIndexes, uint256[] calldata shareAmounts ) external; function slashQueuedWithdrawal( address recipient, QueuedWithdrawal calldata queuedWithdrawal, IERC20[] calldata tokens, uint256[] calldata indicesToSkip ) external; function calculateWithdrawalRoot( QueuedWithdrawal memory queuedWithdrawal ) external pure returns (bytes32); function addStrategiesToDepositWhitelist( IStrategy[] calldata strategiesToWhitelist ) external; function removeStrategiesFromDepositWhitelist( IStrategy[] calldata strategiesToRemoveFromWhitelist ) external; function withdrawalDelayBlocks() external view returns (uint256); function numWithdrawalsQueued( address account ) external view returns (uint256); function delegation() external view returns (address); }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyDelegated","type":"error"},{"inputs":[],"name":"DelegationManagerImmutable","type":"error"},{"inputs":[],"name":"EigenLayerOperatorAlreadyExists","type":"error"},{"inputs":[{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExceedsMaxPerDeposit","type":"error"},{"inputs":[{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExceedsMaxTotalDeposited","type":"error"},{"inputs":[],"name":"ImplementationNotSet","type":"error"},{"inputs":[],"name":"InceptionOnPause","type":"error"},{"inputs":[],"name":"InconsistentData","type":"error"},{"inputs":[{"internalType":"uint256","name":"capacity","type":"uint256"}],"name":"InsufficientCapacity","type":"error"},{"inputs":[],"name":"NotEigenLayerOperator","type":"error"},{"inputs":[],"name":"NullParams","type":"error"},{"inputs":[],"name":"OperatorNotRegistered","type":"error"},{"inputs":[],"name":"RestakerNotRegistered","type":"error"},{"inputs":[{"internalType":"address","name":"assetAddress","type":"address"}],"name":"TransferAssetFailed","type":"error"},{"inputs":[{"internalType":"address","name":"assetAddress","type":"address"}],"name":"TransferAssetFromFailed","type":"error"},{"inputs":[],"name":"WithdrawFutile","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakerAddress","type":"address"},{"indexed":true,"internalType":"address","name":"operatorAddress","type":"address"}],"name":"DelegatedTo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"DelegationManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"iShares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"DepositFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositedToEL","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newELOperator","type":"address"}],"name":"ELOperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"ImplementationUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MinAmountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"prevValue","type":"string"},{"indexed":false,"internalType":"string","name":"newValue","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"OperatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"withdrawals","type":"uint256[]"}],"name":"RedeemedRequests","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"ReferralCode","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"restaker","type":"address"}],"name":"RestakerDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakerAddress","type":"address"},{"indexed":false,"internalType":"contract IStrategy","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"withdrawalStartBlock","type":"uint32"},{"indexed":false,"internalType":"address","name":"delegatedAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"StartWithdrawal","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":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"iShares","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"WithdrawalClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint96","name":"nonce","type":"uint96"},{"indexed":false,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":false,"internalType":"address","name":"delegatedAddress","type":"address"},{"indexed":false,"internalType":"bytes32","name":"withdrawalRoot","type":"bytes32"}],"name":"WithdrawalQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"newELOperator","type":"address"}],"name":"addELOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"restaker","type":"address"},{"components":[{"internalType":"address","name":"staker","type":"address"},{"internalType":"address","name":"delegatedTo","type":"address"},{"internalType":"address","name":"withdrawer","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint32","name":"startBlock","type":"uint32"},{"internalType":"contract IStrategy[]","name":"strategies","type":"address[]"},{"internalType":"uint256[]","name":"shares","type":"uint256[]"}],"internalType":"struct IDelegationManager.Withdrawal[]","name":"withdrawals","type":"tuple[]"}],"name":"claimCompletedWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimerWithdrawalsQueue","outputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"iShares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"elOperator","type":"address"},{"internalType":"bytes32","name":"approverSalt","type":"bytes32"},{"components":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"expiry","type":"uint256"}],"internalType":"struct IDelegationManager.SignatureWithExpiry","name":"approverSignatureAndExpiry","type":"tuple"}],"name":"delegateToOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"elOperator","type":"address"},{"internalType":"bytes32","name":"approverSalt","type":"bytes32"},{"components":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"expiry","type":"uint256"}],"internalType":"struct IDelegationManager.SignatureWithExpiry","name":"approverSignatureAndExpiry","type":"tuple"}],"name":"delegateToOperatorFromVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delegationManager","outputs":[{"internalType":"contract IDelegationManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositAssetIntoStrategyFromVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"depositWithReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"restaker","type":"address"}],"name":"forceUndelegateRecovery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"elOperator","type":"address"}],"name":"getDelegatedTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingWithdrawalAmountFromEL","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"getPendingWithdrawalOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDelegated","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inceptionToken","outputs":[{"internalType":"contract IInceptionToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"vaultName","type":"string"},{"internalType":"address","name":"operatorAddress","type":"address"},{"internalType":"contract IStrategyManager","name":"_strategyManager","type":"address"},{"internalType":"contract IInceptionToken","name":"_inceptionToken","type":"address"},{"internalType":"contract IStrategy","name":"_assetStrategy","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"isAbleToRedeem","outputs":[{"internalType":"bool","name":"able","type":"bool"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ratio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemReservedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"restakers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDelegationManager","name":"newDelegationManager","type":"address"}],"name":"setDelegationManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinAmount","type":"uint256"}],"name":"setMinAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newVaultName","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOperator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategy","outputs":[{"internalType":"contract IStrategy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategyManager","outputs":[{"internalType":"contract IStrategyManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAmountToWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"elOperatorAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"undelegateFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"undelegateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"iShares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6158d780620000f36000396000f3fe60806040523480156200001157600080fd5b5060043610620002cc5760003560e01c8063897b06371162000185578063c235fb1411620000df578063ea4d3c9b1162000092578063ea4d3c9b1462000642578063eae43a441462000657578063edb594fc146200066e578063ef13b2c71462000685578063f297687114620006ac578063f2fde38b14620006b657600080fd5b8063c235fb141462000596578063c47f002714620005ab578063c6e6f59214620005c2578063ce5119ee14620005d9578063d9540d6a14620005f0578063e91bb844146200060757600080fd5b8063a8c62e761162000138578063a8c62e761462000503578063ab89b6af1462000517578063ac48eb9f1462000547578063b3ab15fb146200055e578063b68ef5591462000575578063b9ff20c8146200057f57600080fd5b8063897b063714620004975780638da5cb5b14620004ae578063900cf0cf14620004c057806395a2251f14620004ca5780639b2cb5d814620004e1578063a0ed8b9914620004ec57600080fd5b806339b70e38116200023757806366bcd64111620001ea57806366bcd64114620004415780636e553f65146200044b578063715018a6146200046257806371ca337d146200046c578063841143d214620004765780638456cb59146200048d57600080fd5b806339b70e3814620003be5780633f4ba83a14620003eb5780634fe2bb8214620003f557806353268ad0146200040c5780635c60da1b14620004175780635c975abb146200042a57600080fd5b80630b885ac311620002905780630b885ac3146200034e5780631a8d0de21462000365578063252b7edc146200037c5780632df2228a14620003935780633659cfe6146200039d57806336f4fb0214620003b457600080fd5b8062f714ce14620002d157806301e1d11414620002ea57806306fdde03146200030757806307a2d13a1462000320578063081ab7ad1462000337575b600080fd5b620002e8620002e236600462004009565b620006cd565b005b620002f462000920565b6040519081526020015b60405180910390f35b6200031162000995565b604051620002fe919062004084565b620002f46200033136600462004099565b62000a2c565b620002e8620003483660046200420e565b62000a4c565b620002e86200035f3660046200428f565b62000ba1565b620002e86200037636600462004324565b62000cc5565b620002e86200038d36600462004344565b62000d66565b61010054620002f4565b620002e8620003ae36600462004324565b620010e1565b620002e8620011d2565b60fb54620003d2906001600160a01b031681565b6040516001600160a01b039091168152602001620002fe565b620002e8620011e8565b620002e86200040636600462004099565b620011fc565b620002f46101035481565b610131546001600160a01b0316620003d2565b60335460ff166040519015158152602001620002fe565b620002f460ff5481565b620002f46200045c36600462004009565b620016d9565b620002e862001709565b620002f46200171f565b620002e86200048736600462004009565b62001813565b620002e8620019bf565b620002e8620004a836600462004099565b620019d3565b6097546001600160a01b0316620003d2565b620002f460fd5481565b620002e8620004db36600462004324565b62001a20565b620002f461012e5481565b620002e8620004fd36600462004324565b62001d57565b60fc54620003d2906001600160a01b031681565b620002f46200052836600462004324565b6001600160a01b0316600090815261012f602052604090206002015490565b620002e86200055836600462004373565b62001f06565b620002e86200056f36600462004324565b62002246565b620002f4620022e1565b620002e86200059036600462004099565b62002313565b61012d54620003d2906001600160a01b031681565b620002e8620005bc36600462004401565b6200241d565b620002f4620005d336600462004099565b62002496565b620002f4620005ea36600462004324565b620024b6565b620002e86200060136600462004439565b6200253d565b6200061e6200061836600462004099565b620026f4565b604080519384526001600160a01b03909216602084015290820152606001620002fe565b61010154620003d2906001600160a01b031681565b620003d26200066836600462004099565b62002735565b620002f46200067f366004620044a1565b62002761565b6200069c6200069636600462004324565b620027c3565b604051620002fe92919062004519565b620002f46200293b565b620002e8620006c736600462004324565b62002ac8565b620006d762002b44565b620006e162002b8c565b620006ed818362002be7565b3360006200070e84670de0b6b3a7640000620007086200171f565b62002c59565b905061012e548110156200078f5760405162461bcd60e51b815260206004820152603a60248201527f496e63657074696f6e5661756c743a20616d6f756e74206973206c657373207460448201527f68616e20746865206d696e696d756d207769746864726177616c00000000000060648201526084015b60405180910390fd5b61012d54604051632770a7eb60e21b81526001600160a01b0384811660048301526024820187905290911690639dc29fac90604401600060405180830381600087803b158015620007df57600080fd5b505af1158015620007f4573d6000803e3d6000fd5b505050508060ff60008282546200080c91906200454c565b90915550506001600160a01b038316600090815261012f60205260409020620008358262002caa565b8160020160008282546200084a91906200454c565b909155505060408051606081018252610102805482526001600160a01b03871660208301529181016200087d8562002caa565b9052815460018082018455600093845260209384902083516003909302019182558284015190820180546001600160a01b0319166001600160a01b039283161790556040928301516002909201919091558151858152928301889052858116929087169183917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a45050506200091c6001606555565b5050565b60c9546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200096a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000990919062004562565b905090565b6101308054620009a5906200457c565b80601f0160208091040260200160405190810160405280929190818152602001828054620009d3906200457c565b801562000a245780601f10620009f85761010080835404028352916020019162000a24565b820191906000526020600020905b81548152906001019060200180831162000a0657829003601f168201915b505050505081565b600062000a4682670de0b6b3a7640000620007086200171f565b92915050565b62000a5662002b8c565b62000a6062002b44565b60fe546001600160a01b0316331462000a8d5760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b03831662000ab55760405163a22b4cd760e01b815260040160405180910390fd5b61010154604051631976849960e21b81523060048201526000916001600160a01b0316906365da126490602401602060405180830381865afa15801562000b00573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b26919062004600565b6001600160a01b03161462000b4e57604051631a30c08d60e31b815260040160405180910390fd5b62000b5b83838362002cc0565b6040516001600160a01b0384169030907f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38790600090a362000b9c6001606555565b505050565b600054610100900460ff161580801562000bc25750600054600160ff909116105b8062000bde5750303b15801562000bde575060005460ff166001145b62000c435760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000786565b6000805460ff19166001179055801562000c67576000805461ff0019166101001790555b62000c76868686868662002d30565b801562000cbd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b62000ccf62002d8f565b610101546001600160a01b03161562000cfb57604051634fa0a5d560e11b815260040160405180910390fd5b61010154604080516001600160a01b03928316815291831660208301527fbae75576f1af1fe832366c069d0608003eb7aad2dcc476a5158f70b2b67d3d8b910160405180910390a161010180546001600160a01b0319166001600160a01b0392909216919091179055565b62000d7062002b44565b62000d7a62002b8c565b60fe546001600160a01b0316331462000da75760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b0380831660009081526101046020526040902054168062000de2576040516325ec6c1f60e01b815260040160405180910390fd5b6612344fffffffff196001600160a01b0382160162000e145760405163a22b4cd760e01b815260040160405180910390fd5b6101015460405163285e212160e21b81526001600160a01b038381166004830152600092169063a178848490602401602060405180830381865afa15801562000e61573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e87919062004562565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa15801562000ee2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f08919062004562565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa15801562000f58573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7e919062004562565b905062000f8d8160056200454c565b82101562000f985750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa15801562000fe2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001008919062004562565b60fc546040519196506001600160a01b03808716927fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec520829262001054921690859043908c908a9062004620565b60405180910390a28461010060008282546200107191906200454c565b909155505060405163b64d26ab60e01b8152600481018290526001600160a01b0385169063b64d26ab90602401600060405180830381600087803b158015620010b957600080fd5b505af1158015620010ce573d6000803e3d6000fd5b50505050505050506200091c6001606555565b620010eb62002b44565b620010f562002d8f565b6001600160a01b0381163b620011675760405162461bcd60e51b815260206004820152603060248201527f496e63657074696f6e5661756c743a20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b606482015260840162000786565b61013154604080516001600160a01b03928316815291831660208301527f1a5ca99a64512489fd9455e8da426740174107a69292fca0a8b80b08f6f67892910160405180910390a161013180546001600160a01b0319166001600160a01b0392909216919091179055565b620011dc62002b44565b620011e662002deb565b565b620011f262002d8f565b620011e662002e77565b6200120662002b44565b6200121062002b8c565b60fe546001600160a01b031633146200123d5760405162461bcd60e51b81526004016200078690620045b8565b6101015460405163285e212160e21b81523060048201819052916000916001600160a01b039091169063a178848490602401602060405180830381865afa1580156200128d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620012b3919062004562565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa1580156200130e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001334919062004562565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa15801562001384573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013aa919062004562565b9050620013b98160056200454c565b821015620013c45750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa1580156200140e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001434919062004562565b60408051600180825281830190925291965060009190602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060fc5482519293506001600160a01b031691839150600090620014a057620014a062004659565b60200260200101906001600160a01b031690816001600160a01b0316815250508282600081518110620014d757620014d762004659565b6020908102919091010152604080516001808252818301909252600091816020015b60408051606080820183528082526020820152600091810191909152815260200190600190039081620014f95790505090506040518060600160405280838152602001848152602001306001600160a01b03168152508160008151811062001565576200156562004659565b60200260200101819052508761010060008282546200158591906200454c565b9091555050610101546040516306ec6e8160e11b81526001600160a01b0390911690630dd8dd0290620015bd908490600401620046aa565b6000604051808303816000875af1158015620015dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001607919081019062004770565b5060fc5461010154604051631976849960e21b81526001600160a01b038a811660048301819052937fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec5208293908216928992439216906365da126490602401602060405180830381865afa15801562001682573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016a8919062004600565b8b604051620016bc95949392919062004620565b60405180910390a250505050505050620016d66001606555565b50565b6000620016e562002b8c565b620016ef62002b44565b620016fc83338462002ecb565b905062000a466001606555565b6200171362002d8f565b620011e6600062003007565b6000806200172c620022e1565b9050600061012d60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001785573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017ab919062004562565b9050600060ff548310620017ce5760ff54620017c8908462004804565b620017d1565b60005b9050801580620017df575081155b15620017f657670de0b6b3a7640000935050505090565b6200180b82670de0b6b3a76400008362003059565b935050505090565b60fe546001600160a01b03163314620018405760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b038116620018685760405163a22b4cd760e01b815260040160405180910390fd5b60005b61010554811015620019a057816001600160a01b0316610105828154811062001898576200189862004659565b6000918252602090912001546001600160a01b03161480156200195e57506101015461010580546001600160a01b0390921691633e28391d919084908110620018e557620018e562004659565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562001936573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200195c91906200481a565b155b15620019975766123450000000006001600160a01b031661010582815481106200198c576200198c62004659565b5060005250620019a0565b6001016200186b565b50816101006000828254620019b691906200454c565b90915550505050565b620019c962002d8f565b620011e6620030dd565b620019dd62002d8f565b61012e5460408051918252602082018390527f633c1a71f1236c727d460906a677e5c96556b3f5ad34c9b64072540f1c2eddea910160405180910390a161012e55565b62001a2a62002b44565b62001a3462002b8c565b60008062001a4283620027c3565b915091508162001aa75760405162461bcd60e51b815260206004820152602960248201527f496e63657074696f6e5661756c743a2072656465656d2063616e206e6f74206260448201526819481c1c9bd8d9595960ba1b606482015260840162000786565b80516000816001600160401b0381111562001ac65762001ac6620040b3565b60405190808252806020026020018201604052801562001af0578160200160208202803683370190505b506001600160a01b038616600090815261012f60205260408120919250805b8481101562001c9257600086828151811062001b2f5762001b2f62004659565b602002602001015190506000610102828154811062001b525762001b5262004659565b600091825260208083206040805160608101825260039094029091018054845260018101546001600160a01b03169284019290925260029182015490830181905290880180549294509092839262001bac90849062004804565b9091555062001bbd9050816200311d565b60ff600082825462001bd0919062004804565b9250508190555080610103600082825462001bec919062004804565b9091555062001bfe905081866200454c565b94508287858151811062001c165762001c1662004659565b60200260200101818152505061010289858151811062001c3a5762001c3a62004659565b60200260200101518154811062001c555762001c5562004659565b600091825260208220600390910201818155600180820180546001600160a01b031916905560029091019190915593909301925062001b0f915050565b508462001ca160018662004804565b8151811062001cb45762001cb462004659565b6020908102919091010151825562001ccd87826200312c565b7fd4e9104c456539f8bc402dcb01d19f8d74a18e45395a5b518feb89fbbda5961c8360405162001cfe91906200483e565b60405180910390a16040518181526001600160a01b0388169033907fd12200efa34901b99367694174c3b0d32c99585fdf37c7c26892136ddd0836d99060200160405180910390a3505050505050620016d66001606555565b62001d6162002d8f565b610101546040516336b87bd760e11b81526001600160a01b03838116600483015290911690636d70f7ae90602401602060405180830381865afa15801562001dad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001dd391906200481a565b62001e325760405162461bcd60e51b815260206004820152602860248201527f496e63657074696f6e5661756c743a206974206973206e6f7420616e20454c2060448201526737b832b930ba37b960c11b606482015260840162000786565b6001600160a01b0381811660009081526101046020526040902054161562001ead5760405162461bcd60e51b815260206004820152602760248201527f496e63657074696f6e5661756c743a206f70657261746f7220616c72656164796044820152662065786973747360c81b606482015260840162000786565b6001600160a01b0381166000818152610104602052604080822080546001600160a01b0319166612345000000000179055517f3b2e539a214fa1a91dca8c6e5c54b67f6429ae3142a56bd7e07bd1a1955706b69190a250565b62001f1062002b44565b62001f1a62002b8c565b806000816001600160401b0381111562001f385762001f38620040b3565b60405190808252806020026020018201604052801562001f6d57816020015b606081526020019060019003908162001f575790505b5090506000826001600160401b0381111562001f8d5762001f8d620040b3565b60405190808252806020026020018201604052801562001fb7578160200160208202803683370190505b5090506000836001600160401b0381111562001fd75762001fd7620040b3565b60405190808252806020026020018201604052801562002001578160200160208202803683370190505b50905060005b84811015620020e15760408051600180825281830190925290602080830190803683370190505084828151811062002043576200204362004659565b602090810291909101015260c95484516001600160a01b039091169085908390811062002074576200207462004659565b602002602001015160008151811062002091576200209162004659565b60200260200101906001600160a01b031690816001600160a01b0316815250506001828281518110620020c857620020c862004659565b9115156020928302919091019091015260010162002007565b506000306001600160a01b0389160362002116576200210e62002105878962004942565b858585620031d4565b9050620021be565b620021218862003341565b6200213f5760405163563fb6d760e11b815260040160405180910390fd5b604051631de1b03360e01b81526001600160a01b03891690631de1b0339062002175908a908a9089908990899060040162004bf9565b6020604051808303816000875af115801562002195573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620021bb919062004562565b90505b6040518181527f8772d6f79a1845a0c0e90ef18d99f91242bbc0ba98c9ca780feaad42b81f02ba9060200160405180910390a1806101005410620022135780610100546200220d919062004804565b62002216565b60005b610100819055600711156200222c576000610100555b6200223662002deb565b505050505062000b9c6001606555565b6200225062002d8f565b6001600160a01b038116620022785760405163a22b4cd760e01b815260040160405180910390fd5b60fe54604080516001600160a01b03928316815291831660208301527fd58299b712891143e76310d5e664c4203c940a67db37cf856bdaa3c5c76a802c910160405180910390a160fe80546001600160a01b0319166001600160a01b0392909216919091179055565b600061010054620022f162000920565b620022fb6200293b565b6200230791906200454c565b6200099091906200454c565b6200231d62002b8c565b60fe546001600160a01b031633146200234a5760405162461bcd60e51b81526004016200078690620045b8565b6200235581620033a7565b60fb5460fc5460c9546040516373d0285560e11b81526001600160a01b03928316600482015290821660248201526044810184905291169063e7a050aa906064016020604051808303816000875af1158015620023b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620023dc919062004562565b5060405181815230907f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b79060200160405180910390a2620016d66001606555565b6200242762002d8f565b80516000036200244a5760405163a22b4cd760e01b815260040160405180910390fd5b7f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a610130826040516200247f92919062004d6d565b60405180910390a16101306200091c828262004e60565b600062000a4682620024a76200171f565b670de0b6b3a764000062002c59565b60fc546001600160a01b0382811660009081526101046020526040808220549051630aa794bf60e31b815290831660048201529092919091169063553ca5f890602401602060405180830381865afa15801562002517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a46919062004562565b6200254762002b8c565b6200255162002b44565b60fe546001600160a01b031633146200257e5760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b038316620025a65760405163a22b4cd760e01b815260040160405180910390fd5b620025b184620033a7565b6001600160a01b03808416600090815261010460205260409020541680620025ec576040516325ec6c1f60e01b815260040160405180910390fd5b60006612344fffffffff196001600160a01b0383160162002680575060016200261462003544565b6001600160a01b0380871660009081526101046020526040812080549284166001600160a01b03199384168117909155610105805460018101825592527ffc62abc8c0fc47c2d92f5aec99bf8b60f375828e14394d89345cae11a9867371909101805490921617905591505b6200268c8287620036d7565b8015620026a157620026a182868686620037f6565b846001600160a01b0316826001600160a01b03167f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38760405160405180910390a35050620026ee6001606555565b50505050565b61010281815481106200270657600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b039091169083565b61010581815481106200274757600080fd5b6000918252602090912001546001600160a01b0316905081565b60006200276d62002b8c565b6200277762002b44565b60405182907f3c16de186f1ef5ecb8049424d69d8038355dfdd932e194e95067b0dadd05259890600090a2620027af84338562002ecb565b9050620027bc6001606555565b9392505050565b6001600160a01b03808216600090815261012f6020908152604080832081516060818101845282548083526001840154909716948201949094526002909101549181019190915260fd549293919284929083906200282390839062004804565b6001600160401b038111156200283d576200283d620040b3565b60405190808252806020026020018201604052801562002867578160200160208202803683370190505b50905082604001516000036200288557600097909650945050505050565b60005b60fd548110156200291357876001600160a01b03166101028281548110620028b457620028b462004659565b60009182526020909120600160039092020101546001600160a01b0316036200290a576001965080828681518110620028f157620028f162004659565b6020908102919091010152620029078562004f2c565b94505b60010162002888565b50600084825162002925919062004804565b111562002930578381525b949694955050505050565b61010554600090815b8181101562002a465760006001600160a01b031661010582815481106200296f576200296f62004659565b6000918252602090912001546001600160a01b031614620029445760fc5461010580546001600160a01b039092169163553ca5f8919084908110620029b857620029b862004659565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562002a09573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002a2f919062004562565b62002a3b90846200454c565b925060010162002944565b5060fc54604051630aa794bf60e31b81523060048201526001600160a01b039091169063553ca5f890602401602060405180830381865afa15801562002a90573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002ab6919062004562565b62002ac290836200454c565b91505090565b62002ad262002d8f565b6001600160a01b03811662002b395760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000786565b620016d68162003007565b60335460ff1615620011e65760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000786565b60026065540362002be05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000786565b6002606555565b8060000362002c095760405163a22b4cd760e01b815260040160405180910390fd5b6001600160a01b03821662002c315760405163a22b4cd760e01b815260040160405180910390fd5b62002c3b62003862565b6200091c57604051638e201a8b60e01b815260040160405180910390fd5b600062002ca262002c7662002c6f848762004f5e565b8562003a72565b838562002c84828962004f75565b62002c90919062004f8c565b62002c9c919062004f5e565b62003aaf565b949350505050565b600062000a4660018362004804565b6001606555565b6101015460405163eea9064b60e01b81526001600160a01b039091169063eea9064b9062002cf79086908590879060040162004fd1565b600060405180830381600087803b15801562002d1257600080fd5b505af115801562002d27573d6000803e3d6000fd5b50505050505050565b62002d3a62003ac9565b62002d46838262003afd565b61013062002d55868262004e60565b505060fe80546001600160a01b039485166001600160a01b03199182161790915561012d8054929094169116179091555050606461012e55565b6097546001600160a01b03163314620011e65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000786565b610102546101035460009062002e0062000920565b62002e0c919062004804565b60fd549091505b8281101562000b9c576000610102828154811062002e355762002e3562004659565b90600052602060002090600302016002015490508281111562002e585750505050565b61010380548201905560fd805460019081019091559203910162002e13565b62002e8162003c97565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008062002ed86200171f565b905062002ee6838662003ce2565b600062002ef262000920565b905062002f00858762003d76565b8062002f0b62000920565b62002f17919062004804565b9550600062002f308784670de0b6b3a764000062002c59565b61012d546040516340c10f1960e01b81526001600160a01b038881166004830152602482018490529293509116906340c10f1990604401600060405180830381600087803b15801562002f8257600080fd5b505af115801562002f97573d6000803e3d6000fd5b5050505062002fa68162003e24565b846001600160a01b0316866001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7898460405162002ff5929190918252602082015260400190565b60405180910390a39695505050505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081600003620030965760405162461bcd60e51b8152602060048201526006602482015265063203d3d20360d41b604482015260640162000786565b62002ca2620030aa62002c6f848762004f5e565b83620030b860018262004804565b86620030c5878a62004f75565b620030d1919062004f8c565b62002c9091906200454c565b620030e762002b44565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25862002eae3390565b600062000a468260016200454c565b60c95460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303816000875af115801562003180573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620031a691906200481a565b6200091c5760c954604051631fca53a760e11b81526001600160a01b03909116600482015260240162000786565b60c9546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003222573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003248919062004562565b610101546040516319a021cb60e11b81529192506001600160a01b0316906333404396906200328290899089908990899060040162005007565b600060405180830381600087803b1580156200329d57600080fd5b505af1158015620032b2573d6000803e3d6000fd5b505060c9546040516370a0823160e01b8152306004820152600093508492506001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003304573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200332a919062004562565b62003336919062004804565b979650505050505050565b61010554600090815b818110156200339d5761010581815481106200336a576200336a62004659565b6000918252602090912001546001600160a01b039081169085160362003394575060019392505050565b6001016200334a565b5060009392505050565b61010354620033b562000920565b620033c1919062004804565b811115620033f057620033d362000920565b604051636688dd2d60e11b81526004016200078691815260200190565b60fc546040805163df6fadc160e01b8152815160009384936001600160a01b039091169263df6fadc192600480830193928290030181865afa1580156200343b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003461919062005116565b91509150818311156200349257604051633c690bcb60e11b8152600481018390526024810184905260440162000786565b60c95460fc546040516370a0823160e01b81526001600160a01b03918216600482015260009291909116906370a0823190602401602060405180830381865afa158015620034e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200350a919062004562565b9050816200351985836200454c565b1115620026ee57604051630dbbc86f60e11b8152600481018390526024810182905260440162000786565b610131546000906001600160a01b031662003572576040516340dde93560e01b815260040160405180910390fd5b6101015460fb5460fc5460fe546040516001600160a01b0394851660248201529284166044840152908316606483015291909116608482015260009060a40160408051601f198184030181529181526020820180516001600160e01b0316637c643b2f60e11b1790525190915060009030908390620035f19062003fd3565b620035fe9291906200513b565b604051809103906000f0801580156200361b573d6000803e3d6000fd5b509050806001600160a01b03811663f2fde38b620036416097546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b1580156200368357600080fd5b505af115801562003698573d6000803e3d6000fd5b50506040516001600160a01b03851692507f9e676714ad2ee7d362cccabb3a543102aada709f27c2bda6bf6ef42fce70ff259150600090a25092915050565b60c95460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af11580156200372b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200375191906200481a565b50604051635466590560e01b8152600481018290526001600160a01b03831690635466590590602401600060405180830381600087803b1580156200379557600080fd5b505af1158015620037aa573d6000803e3d6000fd5b50505050816001600160a01b03167f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b782604051620037ea91815260200190565b60405180910390a25050565b60405163511e274f60e01b81526001600160a01b0385169063511e274f90620038289086908690869060040162005161565b600060405180830381600087803b1580156200384357600080fd5b505af115801562003858573d6000803e3d6000fd5b5050505050505050565b6000805b61010554811015620039745760006001600160a01b0316610105828154811062003894576200389462004659565b6000918252602090912001546001600160a01b031603620038b85760010162003866565b6101015461010580546001600160a01b0390921691633e28391d919084908110620038e757620038e762004659565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562003938573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200395e91906200481a565b6200396b57600091505090565b60010162003866565b5060fc54604051630aa794bf60e31b81523060048201526000916001600160a01b03169063553ca5f890602401602060405180830381865afa158015620039bf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620039e5919062004562565b11801562003a60575061010154604051633e28391d60e01b81523060048201526001600160a01b0390911690633e28391d90602401602060405180830381865afa15801562003a38573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003a5e91906200481a565b155b1562003a6c5750600090565b50600190565b60008260000362003a865750600062000a46565b8282028284828162003a9c5762003a9c62004f48565b0414620027bc5760001991505062000a46565b600082820183811015620027bc5760001991505062000a46565b600054610100900460ff1662003af35760405162461bcd60e51b815260040162000786906200518a565b620011e662003e76565b600054610100900460ff1662003b275760405162461bcd60e51b815260040162000786906200518a565b60fb80546001600160a01b038085166001600160a01b03199283161790925560fc8054928416929091168217905560408051632495a59960e01b8152905162003bc29291632495a5999160048083019260209291908290030181865afa15801562003b96573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003bbc919062004600565b62003eab565b60c95460fb5460405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af115801562003c19573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003c3f91906200481a565b6200091c5760405162461bcd60e51b815260206004820152602160248201527f456967656e4c6179657248616e646c65723a20617070726f7665206661696c656044820152601960fa1b606482015260840162000786565b60335460ff16620011e65760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640162000786565b6001600160a01b03821662003d0a5760405163a22b4cd760e01b815260040160405180910390fd5b61012e5481101562002c315760405162461bcd60e51b815260206004820152602e60248201527f496e63657074696f6e5661756c743a206465706f7369746564206c657373207460448201526d1a185b881b5a5b88185b5bdd5b9d60921b606482015260840162000786565b60c9546040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201849052909116906323b872dd906064016020604051808303816000875af115801562003dd0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003df691906200481a565b6200091c5760c9546040516302ce902360e61b81526001600160a01b03909116600482015260240162000786565b60008111620016d65760405162461bcd60e51b815260206004820181905260248201527f496e63657074696f6e5661756c743a20726573756c7420695368617265732030604482015260640162000786565b600054610100900460ff1662003ea05760405162461bcd60e51b815260040162000786906200518a565b620011e63362003007565b600054610100900460ff1662003ed55760405162461bcd60e51b815260040162000786906200518a565b62003edf62003f0b565b62003ee962003f3f565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1662003f355760405162461bcd60e51b815260040162000786906200518a565b620011e662003f73565b600054610100900460ff1662003f695760405162461bcd60e51b815260040162000786906200518a565b620011e662003fa9565b600054610100900460ff1662003f9d5760405162461bcd60e51b815260040162000786906200518a565b6033805460ff19169055565b600054610100900460ff1662002cb95760405162461bcd60e51b815260040162000786906200518a565b6106cc80620051d683390190565b6001600160a01b0381168114620016d657600080fd5b8035620040048162003fe1565b919050565b600080604083850312156200401d57600080fd5b823591506020830135620040318162003fe1565b809150509250929050565b6000815180845260005b81811015620040645760208185018101518683018201520162004046565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000620027bc60208301846200403c565b600060208284031215620040ac57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715620040ee57620040ee620040b3565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200411f576200411f620040b3565b604052919050565b60006001600160401b03831115620041435762004143620040b3565b62004158601f8401601f1916602001620040f4565b90508281528383830111156200416d57600080fd5b828260208301376000602084830101529392505050565b6000604082840312156200419757600080fd5b604051604081016001600160401b038282108183111715620041bd57620041bd620040b3565b816040528293508435915080821115620041d657600080fd5b508301601f81018513620041e957600080fd5b620041fa8582356020840162004127565b825250602083013560208201525092915050565b6000806000606084860312156200422457600080fd5b8335620042318162003fe1565b92506020840135915060408401356001600160401b038111156200425457600080fd5b620042628682870162004184565b9150509250925092565b600082601f8301126200427e57600080fd5b620027bc8383356020850162004127565b600080600080600060a08688031215620042a857600080fd5b85356001600160401b03811115620042bf57600080fd5b620042cd888289016200426c565b9550506020860135620042e08162003fe1565b93506040860135620042f28162003fe1565b92506060860135620043048162003fe1565b91506080860135620043168162003fe1565b809150509295509295909350565b6000602082840312156200433757600080fd5b8135620027bc8162003fe1565b600080604083850312156200435857600080fd5b8235620043658162003fe1565b946020939093013593505050565b6000806000604084860312156200438957600080fd5b8335620043968162003fe1565b925060208401356001600160401b0380821115620043b357600080fd5b818601915086601f830112620043c857600080fd5b813581811115620043d857600080fd5b8760208260051b8501011115620043ee57600080fd5b6020830194508093505050509250925092565b6000602082840312156200441457600080fd5b81356001600160401b038111156200442b57600080fd5b62002ca2848285016200426c565b600080600080608085870312156200445057600080fd5b843593506020850135620044648162003fe1565b92506040850135915060608501356001600160401b038111156200448757600080fd5b620044958782880162004184565b91505092959194509250565b600080600060608486031215620044b757600080fd5b833592506020840135620044cb8162003fe1565b929592945050506040919091013590565b600081518084526020808501945080840160005b838110156200450e57815187529582019590820190600101620044f0565b509495945050505050565b821515815260406020820152600062002ca26040830184620044dc565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000a465762000a4662004536565b6000602082840312156200457557600080fd5b5051919050565b600181811c908216806200459157607f821691505b602082108103620045b257634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526028908201527f456967656e4c6179657248616e646c65723a206f6e6c79206f70657261746f7260408201526708185b1b1bddd95960c21b606082015260800190565b6000602082840312156200461357600080fd5b8151620027bc8162003fe1565b6001600160a01b039586168152602081019490945263ffffffff9290921660408401529092166060820152608081019190915260a00190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156200450e5781516001600160a01b03168752958201959082019060010162004683565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156200473c57603f19898403018552815160608151818652620046fa828701826200466f565b915050888201518582038a870152620047148282620044dc565b928901516001600160a01b0316958901959095525094870194925090860190600101620046d1565b509098975050505050505050565b60006001600160401b03821115620047665762004766620040b3565b5060051b60200190565b600060208083850312156200478457600080fd5b82516001600160401b038111156200479b57600080fd5b8301601f81018513620047ad57600080fd5b8051620047c4620047be826200474a565b620040f4565b81815260059190911b82018301908381019087831115620047e457600080fd5b928401925b828410156200333657835182529284019290840190620047e9565b8181038181111562000a465762000a4662004536565b6000602082840312156200482d57600080fd5b81518015158114620027bc57600080fd5b602081526000620027bc6020830184620044dc565b803563ffffffff811681146200400457600080fd5b600082601f8301126200487a57600080fd5b813560206200488d620047be836200474a565b82815260059290921b84018101918181019086841115620048ad57600080fd5b8286015b84811015620048d5578035620048c78162003fe1565b8352918301918301620048b1565b509695505050505050565b600082601f830112620048f257600080fd5b8135602062004905620047be836200474a565b82815260059290921b840181019181810190868411156200492557600080fd5b8286015b84811015620048d5578035835291830191830162004929565b600062004953620047be846200474a565b80848252602080830192508560051b8501368111156200497257600080fd5b855b8181101562004a695780356001600160401b0380821115620049965760008081fd5b818901915060e08236031215620049ad5760008081fd5b620049b7620040c9565b620049c28362003ff7565b8152620049d186840162003ff7565b868201526040620049e481850162003ff7565b9082015260608381013590820152608062004a0181850162004853565b9082015260a0838101358381111562004a1a5760008081fd5b62004a283682870162004868565b82840152505060c0808401358381111562004a435760008081fd5b62004a5136828701620048e0565b91830191909152508752505093820193820162004974565b50919695505050505050565b6000808335601e1984360301811262004a8d57600080fd5b83016020810192503590506001600160401b0381111562004aad57600080fd5b8060051b360382131562004ac057600080fd5b9250929050565b8183526000602080850194508260005b858110156200450e57813562004aed8162003fe1565b6001600160a01b03168752958201959082019060010162004ad7565b81835260006001600160fb1b0383111562004b2357600080fd5b8260051b80836020870137939093016020019392505050565b600081518084526020808501808196508360051b810191508286016000805b8681101562004bb7578385038a52825180518087529087019087870190845b8181101562004ba15783516001600160a01b03168352928901929189019160010162004b7a565b50509a87019a9550509185019160010162004b5b565b509298975050505050505050565b600081518084526020808501945080840160005b838110156200450e57815115158752958201959082019060010162004bd9565b608080825281810186905260009060a0808401600589901b850182018a85805b8c81101562004d1b57888403609f190185528235368f900360de1901811262004c40578283fd5b8e0160e0813562004c518162003fe1565b6001600160a01b0316865260208281013562004c6d8162003fe1565b6001600160a01b031681880152604062004c8984820162003ff7565b6001600160a01b0316908801526060838101359088015262004cad8a840162004853565b63ffffffff168a88015262004cc5838a018462004a75565b838b8a015262004cd9848a01828462004ac7565b9350505060c062004ced8185018562004a75565b9450888403828a015262004d0384868362004b09565b99830199985050509490940193505060010162004c19565b505050858103602087015262004d32818a62004b3c565b9350505050828103604084015262004d4b8186620044dc565b9050828103606084015262004d61818562004bc5565b98975050505050505050565b60408152600080845462004d81816200457c565b806040860152606060018084166000811462004da6576001811462004dc15762004df4565b60ff1985168884015283151560051b88018301955062004df4565b8960005260208060002060005b8681101562004deb5781548b820187015290840190820162004dce565b8a018501975050505b5050505050828103602084015262004e0d81856200403c565b95945050505050565b601f82111562000b9c57600081815260208120601f850160051c8101602086101562004e3f5750805b601f850160051c820191505b8181101562000cbd5782815560010162004e4b565b81516001600160401b0381111562004e7c5762004e7c620040b3565b62004e948162004e8d84546200457c565b8462004e16565b602080601f83116001811462004ecc576000841562004eb35750858301515b600019600386901b1c1916600185901b17855562000cbd565b600085815260208120601f198616915b8281101562004efd5788860151825594840194600190910190840162004edc565b508582101562004f1c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001820162004f415762004f4162004536565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008262004f705762004f7062004f48565b500490565b60008262004f875762004f8762004f48565b500690565b808202811582820484141762000a465762000a4662004536565b600081516040845262004fbd60408501826200403c565b602093840151949093019390935250919050565b6001600160a01b038416815260606020820181905260009062004ff79083018562004fa6565b9050826040830152949350505050565b6000608080830181845280885180835260a092508286019150828160051b8701016020808c0160005b84811015620050d157898403609f19018652815180516001600160a01b0390811686528482015181168587015260408083015190911690860152606080820151908601528881015163ffffffff16898601528781015160e0898701819052906200509d828801826200466f565b91505060c08083015192508682038188015250620050bc8183620044dc565b97850197955050509082019060010162005030565b505087820390880152620050e6818b62004b3c565b9450505050508281036040840152620051008186620044dc565b9050828103606084015262003336818562004bc5565b600080604083850312156200512a57600080fd5b505080516020909101519092909150565b6001600160a01b038316815260406020820181905260009062002ca2908301846200403c565b60018060a01b038416815282602082015260606040820152600062004e0d606083018462004fa6565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe60806040526040516106cc3803806106cc83398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106a5602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b61014c806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122044bae01418f8f4d3e2aa454c2b5942f4fa2dcacad01b2d54be1f93cf2feef3dc64736f6c63430008140033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220ff87365d90f14afb2d0e7e6a8d5137988488ef3ea7d297ac5eae99146ec409e064736f6c63430008140033
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620002cc5760003560e01c8063897b06371162000185578063c235fb1411620000df578063ea4d3c9b1162000092578063ea4d3c9b1462000642578063eae43a441462000657578063edb594fc146200066e578063ef13b2c71462000685578063f297687114620006ac578063f2fde38b14620006b657600080fd5b8063c235fb141462000596578063c47f002714620005ab578063c6e6f59214620005c2578063ce5119ee14620005d9578063d9540d6a14620005f0578063e91bb844146200060757600080fd5b8063a8c62e761162000138578063a8c62e761462000503578063ab89b6af1462000517578063ac48eb9f1462000547578063b3ab15fb146200055e578063b68ef5591462000575578063b9ff20c8146200057f57600080fd5b8063897b063714620004975780638da5cb5b14620004ae578063900cf0cf14620004c057806395a2251f14620004ca5780639b2cb5d814620004e1578063a0ed8b9914620004ec57600080fd5b806339b70e38116200023757806366bcd64111620001ea57806366bcd64114620004415780636e553f65146200044b578063715018a6146200046257806371ca337d146200046c578063841143d214620004765780638456cb59146200048d57600080fd5b806339b70e3814620003be5780633f4ba83a14620003eb5780634fe2bb8214620003f557806353268ad0146200040c5780635c60da1b14620004175780635c975abb146200042a57600080fd5b80630b885ac311620002905780630b885ac3146200034e5780631a8d0de21462000365578063252b7edc146200037c5780632df2228a14620003935780633659cfe6146200039d57806336f4fb0214620003b457600080fd5b8062f714ce14620002d157806301e1d11414620002ea57806306fdde03146200030757806307a2d13a1462000320578063081ab7ad1462000337575b600080fd5b620002e8620002e236600462004009565b620006cd565b005b620002f462000920565b6040519081526020015b60405180910390f35b6200031162000995565b604051620002fe919062004084565b620002f46200033136600462004099565b62000a2c565b620002e8620003483660046200420e565b62000a4c565b620002e86200035f3660046200428f565b62000ba1565b620002e86200037636600462004324565b62000cc5565b620002e86200038d36600462004344565b62000d66565b61010054620002f4565b620002e8620003ae36600462004324565b620010e1565b620002e8620011d2565b60fb54620003d2906001600160a01b031681565b6040516001600160a01b039091168152602001620002fe565b620002e8620011e8565b620002e86200040636600462004099565b620011fc565b620002f46101035481565b610131546001600160a01b0316620003d2565b60335460ff166040519015158152602001620002fe565b620002f460ff5481565b620002f46200045c36600462004009565b620016d9565b620002e862001709565b620002f46200171f565b620002e86200048736600462004009565b62001813565b620002e8620019bf565b620002e8620004a836600462004099565b620019d3565b6097546001600160a01b0316620003d2565b620002f460fd5481565b620002e8620004db36600462004324565b62001a20565b620002f461012e5481565b620002e8620004fd36600462004324565b62001d57565b60fc54620003d2906001600160a01b031681565b620002f46200052836600462004324565b6001600160a01b0316600090815261012f602052604090206002015490565b620002e86200055836600462004373565b62001f06565b620002e86200056f36600462004324565b62002246565b620002f4620022e1565b620002e86200059036600462004099565b62002313565b61012d54620003d2906001600160a01b031681565b620002e8620005bc36600462004401565b6200241d565b620002f4620005d336600462004099565b62002496565b620002f4620005ea36600462004324565b620024b6565b620002e86200060136600462004439565b6200253d565b6200061e6200061836600462004099565b620026f4565b604080519384526001600160a01b03909216602084015290820152606001620002fe565b61010154620003d2906001600160a01b031681565b620003d26200066836600462004099565b62002735565b620002f46200067f366004620044a1565b62002761565b6200069c6200069636600462004324565b620027c3565b604051620002fe92919062004519565b620002f46200293b565b620002e8620006c736600462004324565b62002ac8565b620006d762002b44565b620006e162002b8c565b620006ed818362002be7565b3360006200070e84670de0b6b3a7640000620007086200171f565b62002c59565b905061012e548110156200078f5760405162461bcd60e51b815260206004820152603a60248201527f496e63657074696f6e5661756c743a20616d6f756e74206973206c657373207460448201527f68616e20746865206d696e696d756d207769746864726177616c00000000000060648201526084015b60405180910390fd5b61012d54604051632770a7eb60e21b81526001600160a01b0384811660048301526024820187905290911690639dc29fac90604401600060405180830381600087803b158015620007df57600080fd5b505af1158015620007f4573d6000803e3d6000fd5b505050508060ff60008282546200080c91906200454c565b90915550506001600160a01b038316600090815261012f60205260409020620008358262002caa565b8160020160008282546200084a91906200454c565b909155505060408051606081018252610102805482526001600160a01b03871660208301529181016200087d8562002caa565b9052815460018082018455600093845260209384902083516003909302019182558284015190820180546001600160a01b0319166001600160a01b039283161790556040928301516002909201919091558151858152928301889052858116929087169183917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a45050506200091c6001606555565b5050565b60c9546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200096a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000990919062004562565b905090565b6101308054620009a5906200457c565b80601f0160208091040260200160405190810160405280929190818152602001828054620009d3906200457c565b801562000a245780601f10620009f85761010080835404028352916020019162000a24565b820191906000526020600020905b81548152906001019060200180831162000a0657829003601f168201915b505050505081565b600062000a4682670de0b6b3a7640000620007086200171f565b92915050565b62000a5662002b8c565b62000a6062002b44565b60fe546001600160a01b0316331462000a8d5760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b03831662000ab55760405163a22b4cd760e01b815260040160405180910390fd5b61010154604051631976849960e21b81523060048201526000916001600160a01b0316906365da126490602401602060405180830381865afa15801562000b00573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b26919062004600565b6001600160a01b03161462000b4e57604051631a30c08d60e31b815260040160405180910390fd5b62000b5b83838362002cc0565b6040516001600160a01b0384169030907f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38790600090a362000b9c6001606555565b505050565b600054610100900460ff161580801562000bc25750600054600160ff909116105b8062000bde5750303b15801562000bde575060005460ff166001145b62000c435760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000786565b6000805460ff19166001179055801562000c67576000805461ff0019166101001790555b62000c76868686868662002d30565b801562000cbd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b62000ccf62002d8f565b610101546001600160a01b03161562000cfb57604051634fa0a5d560e11b815260040160405180910390fd5b61010154604080516001600160a01b03928316815291831660208301527fbae75576f1af1fe832366c069d0608003eb7aad2dcc476a5158f70b2b67d3d8b910160405180910390a161010180546001600160a01b0319166001600160a01b0392909216919091179055565b62000d7062002b44565b62000d7a62002b8c565b60fe546001600160a01b0316331462000da75760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b0380831660009081526101046020526040902054168062000de2576040516325ec6c1f60e01b815260040160405180910390fd5b6612344fffffffff196001600160a01b0382160162000e145760405163a22b4cd760e01b815260040160405180910390fd5b6101015460405163285e212160e21b81526001600160a01b038381166004830152600092169063a178848490602401602060405180830381865afa15801562000e61573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e87919062004562565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa15801562000ee2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f08919062004562565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa15801562000f58573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7e919062004562565b905062000f8d8160056200454c565b82101562000f985750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa15801562000fe2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001008919062004562565b60fc546040519196506001600160a01b03808716927fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec520829262001054921690859043908c908a9062004620565b60405180910390a28461010060008282546200107191906200454c565b909155505060405163b64d26ab60e01b8152600481018290526001600160a01b0385169063b64d26ab90602401600060405180830381600087803b158015620010b957600080fd5b505af1158015620010ce573d6000803e3d6000fd5b50505050505050506200091c6001606555565b620010eb62002b44565b620010f562002d8f565b6001600160a01b0381163b620011675760405162461bcd60e51b815260206004820152603060248201527f496e63657074696f6e5661756c743a20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b606482015260840162000786565b61013154604080516001600160a01b03928316815291831660208301527f1a5ca99a64512489fd9455e8da426740174107a69292fca0a8b80b08f6f67892910160405180910390a161013180546001600160a01b0319166001600160a01b0392909216919091179055565b620011dc62002b44565b620011e662002deb565b565b620011f262002d8f565b620011e662002e77565b6200120662002b44565b6200121062002b8c565b60fe546001600160a01b031633146200123d5760405162461bcd60e51b81526004016200078690620045b8565b6101015460405163285e212160e21b81523060048201819052916000916001600160a01b039091169063a178848490602401602060405180830381865afa1580156200128d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620012b3919062004562565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa1580156200130e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001334919062004562565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa15801562001384573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013aa919062004562565b9050620013b98160056200454c565b821015620013c45750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa1580156200140e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001434919062004562565b60408051600180825281830190925291965060009190602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060fc5482519293506001600160a01b031691839150600090620014a057620014a062004659565b60200260200101906001600160a01b031690816001600160a01b0316815250508282600081518110620014d757620014d762004659565b6020908102919091010152604080516001808252818301909252600091816020015b60408051606080820183528082526020820152600091810191909152815260200190600190039081620014f95790505090506040518060600160405280838152602001848152602001306001600160a01b03168152508160008151811062001565576200156562004659565b60200260200101819052508761010060008282546200158591906200454c565b9091555050610101546040516306ec6e8160e11b81526001600160a01b0390911690630dd8dd0290620015bd908490600401620046aa565b6000604051808303816000875af1158015620015dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001607919081019062004770565b5060fc5461010154604051631976849960e21b81526001600160a01b038a811660048301819052937fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec5208293908216928992439216906365da126490602401602060405180830381865afa15801562001682573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016a8919062004600565b8b604051620016bc95949392919062004620565b60405180910390a250505050505050620016d66001606555565b50565b6000620016e562002b8c565b620016ef62002b44565b620016fc83338462002ecb565b905062000a466001606555565b6200171362002d8f565b620011e6600062003007565b6000806200172c620022e1565b9050600061012d60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001785573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017ab919062004562565b9050600060ff548310620017ce5760ff54620017c8908462004804565b620017d1565b60005b9050801580620017df575081155b15620017f657670de0b6b3a7640000935050505090565b6200180b82670de0b6b3a76400008362003059565b935050505090565b60fe546001600160a01b03163314620018405760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b038116620018685760405163a22b4cd760e01b815260040160405180910390fd5b60005b61010554811015620019a057816001600160a01b0316610105828154811062001898576200189862004659565b6000918252602090912001546001600160a01b03161480156200195e57506101015461010580546001600160a01b0390921691633e28391d919084908110620018e557620018e562004659565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562001936573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200195c91906200481a565b155b15620019975766123450000000006001600160a01b031661010582815481106200198c576200198c62004659565b5060005250620019a0565b6001016200186b565b50816101006000828254620019b691906200454c565b90915550505050565b620019c962002d8f565b620011e6620030dd565b620019dd62002d8f565b61012e5460408051918252602082018390527f633c1a71f1236c727d460906a677e5c96556b3f5ad34c9b64072540f1c2eddea910160405180910390a161012e55565b62001a2a62002b44565b62001a3462002b8c565b60008062001a4283620027c3565b915091508162001aa75760405162461bcd60e51b815260206004820152602960248201527f496e63657074696f6e5661756c743a2072656465656d2063616e206e6f74206260448201526819481c1c9bd8d9595960ba1b606482015260840162000786565b80516000816001600160401b0381111562001ac65762001ac6620040b3565b60405190808252806020026020018201604052801562001af0578160200160208202803683370190505b506001600160a01b038616600090815261012f60205260408120919250805b8481101562001c9257600086828151811062001b2f5762001b2f62004659565b602002602001015190506000610102828154811062001b525762001b5262004659565b600091825260208083206040805160608101825260039094029091018054845260018101546001600160a01b03169284019290925260029182015490830181905290880180549294509092839262001bac90849062004804565b9091555062001bbd9050816200311d565b60ff600082825462001bd0919062004804565b9250508190555080610103600082825462001bec919062004804565b9091555062001bfe905081866200454c565b94508287858151811062001c165762001c1662004659565b60200260200101818152505061010289858151811062001c3a5762001c3a62004659565b60200260200101518154811062001c555762001c5562004659565b600091825260208220600390910201818155600180820180546001600160a01b031916905560029091019190915593909301925062001b0f915050565b508462001ca160018662004804565b8151811062001cb45762001cb462004659565b6020908102919091010151825562001ccd87826200312c565b7fd4e9104c456539f8bc402dcb01d19f8d74a18e45395a5b518feb89fbbda5961c8360405162001cfe91906200483e565b60405180910390a16040518181526001600160a01b0388169033907fd12200efa34901b99367694174c3b0d32c99585fdf37c7c26892136ddd0836d99060200160405180910390a3505050505050620016d66001606555565b62001d6162002d8f565b610101546040516336b87bd760e11b81526001600160a01b03838116600483015290911690636d70f7ae90602401602060405180830381865afa15801562001dad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001dd391906200481a565b62001e325760405162461bcd60e51b815260206004820152602860248201527f496e63657074696f6e5661756c743a206974206973206e6f7420616e20454c2060448201526737b832b930ba37b960c11b606482015260840162000786565b6001600160a01b0381811660009081526101046020526040902054161562001ead5760405162461bcd60e51b815260206004820152602760248201527f496e63657074696f6e5661756c743a206f70657261746f7220616c72656164796044820152662065786973747360c81b606482015260840162000786565b6001600160a01b0381166000818152610104602052604080822080546001600160a01b0319166612345000000000179055517f3b2e539a214fa1a91dca8c6e5c54b67f6429ae3142a56bd7e07bd1a1955706b69190a250565b62001f1062002b44565b62001f1a62002b8c565b806000816001600160401b0381111562001f385762001f38620040b3565b60405190808252806020026020018201604052801562001f6d57816020015b606081526020019060019003908162001f575790505b5090506000826001600160401b0381111562001f8d5762001f8d620040b3565b60405190808252806020026020018201604052801562001fb7578160200160208202803683370190505b5090506000836001600160401b0381111562001fd75762001fd7620040b3565b60405190808252806020026020018201604052801562002001578160200160208202803683370190505b50905060005b84811015620020e15760408051600180825281830190925290602080830190803683370190505084828151811062002043576200204362004659565b602090810291909101015260c95484516001600160a01b039091169085908390811062002074576200207462004659565b602002602001015160008151811062002091576200209162004659565b60200260200101906001600160a01b031690816001600160a01b0316815250506001828281518110620020c857620020c862004659565b9115156020928302919091019091015260010162002007565b506000306001600160a01b0389160362002116576200210e62002105878962004942565b858585620031d4565b9050620021be565b620021218862003341565b6200213f5760405163563fb6d760e11b815260040160405180910390fd5b604051631de1b03360e01b81526001600160a01b03891690631de1b0339062002175908a908a9089908990899060040162004bf9565b6020604051808303816000875af115801562002195573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620021bb919062004562565b90505b6040518181527f8772d6f79a1845a0c0e90ef18d99f91242bbc0ba98c9ca780feaad42b81f02ba9060200160405180910390a1806101005410620022135780610100546200220d919062004804565b62002216565b60005b610100819055600711156200222c576000610100555b6200223662002deb565b505050505062000b9c6001606555565b6200225062002d8f565b6001600160a01b038116620022785760405163a22b4cd760e01b815260040160405180910390fd5b60fe54604080516001600160a01b03928316815291831660208301527fd58299b712891143e76310d5e664c4203c940a67db37cf856bdaa3c5c76a802c910160405180910390a160fe80546001600160a01b0319166001600160a01b0392909216919091179055565b600061010054620022f162000920565b620022fb6200293b565b6200230791906200454c565b6200099091906200454c565b6200231d62002b8c565b60fe546001600160a01b031633146200234a5760405162461bcd60e51b81526004016200078690620045b8565b6200235581620033a7565b60fb5460fc5460c9546040516373d0285560e11b81526001600160a01b03928316600482015290821660248201526044810184905291169063e7a050aa906064016020604051808303816000875af1158015620023b6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620023dc919062004562565b5060405181815230907f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b79060200160405180910390a2620016d66001606555565b6200242762002d8f565b80516000036200244a5760405163a22b4cd760e01b815260040160405180910390fd5b7f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a610130826040516200247f92919062004d6d565b60405180910390a16101306200091c828262004e60565b600062000a4682620024a76200171f565b670de0b6b3a764000062002c59565b60fc546001600160a01b0382811660009081526101046020526040808220549051630aa794bf60e31b815290831660048201529092919091169063553ca5f890602401602060405180830381865afa15801562002517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a46919062004562565b6200254762002b8c565b6200255162002b44565b60fe546001600160a01b031633146200257e5760405162461bcd60e51b81526004016200078690620045b8565b6001600160a01b038316620025a65760405163a22b4cd760e01b815260040160405180910390fd5b620025b184620033a7565b6001600160a01b03808416600090815261010460205260409020541680620025ec576040516325ec6c1f60e01b815260040160405180910390fd5b60006612344fffffffff196001600160a01b0383160162002680575060016200261462003544565b6001600160a01b0380871660009081526101046020526040812080549284166001600160a01b03199384168117909155610105805460018101825592527ffc62abc8c0fc47c2d92f5aec99bf8b60f375828e14394d89345cae11a9867371909101805490921617905591505b6200268c8287620036d7565b8015620026a157620026a182868686620037f6565b846001600160a01b0316826001600160a01b03167f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38760405160405180910390a35050620026ee6001606555565b50505050565b61010281815481106200270657600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b039091169083565b61010581815481106200274757600080fd5b6000918252602090912001546001600160a01b0316905081565b60006200276d62002b8c565b6200277762002b44565b60405182907f3c16de186f1ef5ecb8049424d69d8038355dfdd932e194e95067b0dadd05259890600090a2620027af84338562002ecb565b9050620027bc6001606555565b9392505050565b6001600160a01b03808216600090815261012f6020908152604080832081516060818101845282548083526001840154909716948201949094526002909101549181019190915260fd549293919284929083906200282390839062004804565b6001600160401b038111156200283d576200283d620040b3565b60405190808252806020026020018201604052801562002867578160200160208202803683370190505b50905082604001516000036200288557600097909650945050505050565b60005b60fd548110156200291357876001600160a01b03166101028281548110620028b457620028b462004659565b60009182526020909120600160039092020101546001600160a01b0316036200290a576001965080828681518110620028f157620028f162004659565b6020908102919091010152620029078562004f2c565b94505b60010162002888565b50600084825162002925919062004804565b111562002930578381525b949694955050505050565b61010554600090815b8181101562002a465760006001600160a01b031661010582815481106200296f576200296f62004659565b6000918252602090912001546001600160a01b031614620029445760fc5461010580546001600160a01b039092169163553ca5f8919084908110620029b857620029b862004659565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562002a09573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002a2f919062004562565b62002a3b90846200454c565b925060010162002944565b5060fc54604051630aa794bf60e31b81523060048201526001600160a01b039091169063553ca5f890602401602060405180830381865afa15801562002a90573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002ab6919062004562565b62002ac290836200454c565b91505090565b62002ad262002d8f565b6001600160a01b03811662002b395760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000786565b620016d68162003007565b60335460ff1615620011e65760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000786565b60026065540362002be05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000786565b6002606555565b8060000362002c095760405163a22b4cd760e01b815260040160405180910390fd5b6001600160a01b03821662002c315760405163a22b4cd760e01b815260040160405180910390fd5b62002c3b62003862565b6200091c57604051638e201a8b60e01b815260040160405180910390fd5b600062002ca262002c7662002c6f848762004f5e565b8562003a72565b838562002c84828962004f75565b62002c90919062004f8c565b62002c9c919062004f5e565b62003aaf565b949350505050565b600062000a4660018362004804565b6001606555565b6101015460405163eea9064b60e01b81526001600160a01b039091169063eea9064b9062002cf79086908590879060040162004fd1565b600060405180830381600087803b15801562002d1257600080fd5b505af115801562002d27573d6000803e3d6000fd5b50505050505050565b62002d3a62003ac9565b62002d46838262003afd565b61013062002d55868262004e60565b505060fe80546001600160a01b039485166001600160a01b03199182161790915561012d8054929094169116179091555050606461012e55565b6097546001600160a01b03163314620011e65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000786565b610102546101035460009062002e0062000920565b62002e0c919062004804565b60fd549091505b8281101562000b9c576000610102828154811062002e355762002e3562004659565b90600052602060002090600302016002015490508281111562002e585750505050565b61010380548201905560fd805460019081019091559203910162002e13565b62002e8162003c97565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008062002ed86200171f565b905062002ee6838662003ce2565b600062002ef262000920565b905062002f00858762003d76565b8062002f0b62000920565b62002f17919062004804565b9550600062002f308784670de0b6b3a764000062002c59565b61012d546040516340c10f1960e01b81526001600160a01b038881166004830152602482018490529293509116906340c10f1990604401600060405180830381600087803b15801562002f8257600080fd5b505af115801562002f97573d6000803e3d6000fd5b5050505062002fa68162003e24565b846001600160a01b0316866001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7898460405162002ff5929190918252602082015260400190565b60405180910390a39695505050505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081600003620030965760405162461bcd60e51b8152602060048201526006602482015265063203d3d20360d41b604482015260640162000786565b62002ca2620030aa62002c6f848762004f5e565b83620030b860018262004804565b86620030c5878a62004f75565b620030d1919062004f8c565b62002c9091906200454c565b620030e762002b44565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25862002eae3390565b600062000a468260016200454c565b60c95460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303816000875af115801562003180573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620031a691906200481a565b6200091c5760c954604051631fca53a760e11b81526001600160a01b03909116600482015260240162000786565b60c9546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003222573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003248919062004562565b610101546040516319a021cb60e11b81529192506001600160a01b0316906333404396906200328290899089908990899060040162005007565b600060405180830381600087803b1580156200329d57600080fd5b505af1158015620032b2573d6000803e3d6000fd5b505060c9546040516370a0823160e01b8152306004820152600093508492506001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003304573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200332a919062004562565b62003336919062004804565b979650505050505050565b61010554600090815b818110156200339d5761010581815481106200336a576200336a62004659565b6000918252602090912001546001600160a01b039081169085160362003394575060019392505050565b6001016200334a565b5060009392505050565b61010354620033b562000920565b620033c1919062004804565b811115620033f057620033d362000920565b604051636688dd2d60e11b81526004016200078691815260200190565b60fc546040805163df6fadc160e01b8152815160009384936001600160a01b039091169263df6fadc192600480830193928290030181865afa1580156200343b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003461919062005116565b91509150818311156200349257604051633c690bcb60e11b8152600481018390526024810184905260440162000786565b60c95460fc546040516370a0823160e01b81526001600160a01b03918216600482015260009291909116906370a0823190602401602060405180830381865afa158015620034e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200350a919062004562565b9050816200351985836200454c565b1115620026ee57604051630dbbc86f60e11b8152600481018390526024810182905260440162000786565b610131546000906001600160a01b031662003572576040516340dde93560e01b815260040160405180910390fd5b6101015460fb5460fc5460fe546040516001600160a01b0394851660248201529284166044840152908316606483015291909116608482015260009060a40160408051601f198184030181529181526020820180516001600160e01b0316637c643b2f60e11b1790525190915060009030908390620035f19062003fd3565b620035fe9291906200513b565b604051809103906000f0801580156200361b573d6000803e3d6000fd5b509050806001600160a01b03811663f2fde38b620036416097546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b1580156200368357600080fd5b505af115801562003698573d6000803e3d6000fd5b50506040516001600160a01b03851692507f9e676714ad2ee7d362cccabb3a543102aada709f27c2bda6bf6ef42fce70ff259150600090a25092915050565b60c95460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af11580156200372b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200375191906200481a565b50604051635466590560e01b8152600481018290526001600160a01b03831690635466590590602401600060405180830381600087803b1580156200379557600080fd5b505af1158015620037aa573d6000803e3d6000fd5b50505050816001600160a01b03167f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b782604051620037ea91815260200190565b60405180910390a25050565b60405163511e274f60e01b81526001600160a01b0385169063511e274f90620038289086908690869060040162005161565b600060405180830381600087803b1580156200384357600080fd5b505af115801562003858573d6000803e3d6000fd5b5050505050505050565b6000805b61010554811015620039745760006001600160a01b0316610105828154811062003894576200389462004659565b6000918252602090912001546001600160a01b031603620038b85760010162003866565b6101015461010580546001600160a01b0390921691633e28391d919084908110620038e757620038e762004659565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562003938573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200395e91906200481a565b6200396b57600091505090565b60010162003866565b5060fc54604051630aa794bf60e31b81523060048201526000916001600160a01b03169063553ca5f890602401602060405180830381865afa158015620039bf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620039e5919062004562565b11801562003a60575061010154604051633e28391d60e01b81523060048201526001600160a01b0390911690633e28391d90602401602060405180830381865afa15801562003a38573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003a5e91906200481a565b155b1562003a6c5750600090565b50600190565b60008260000362003a865750600062000a46565b8282028284828162003a9c5762003a9c62004f48565b0414620027bc5760001991505062000a46565b600082820183811015620027bc5760001991505062000a46565b600054610100900460ff1662003af35760405162461bcd60e51b815260040162000786906200518a565b620011e662003e76565b600054610100900460ff1662003b275760405162461bcd60e51b815260040162000786906200518a565b60fb80546001600160a01b038085166001600160a01b03199283161790925560fc8054928416929091168217905560408051632495a59960e01b8152905162003bc29291632495a5999160048083019260209291908290030181865afa15801562003b96573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003bbc919062004600565b62003eab565b60c95460fb5460405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af115801562003c19573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003c3f91906200481a565b6200091c5760405162461bcd60e51b815260206004820152602160248201527f456967656e4c6179657248616e646c65723a20617070726f7665206661696c656044820152601960fa1b606482015260840162000786565b60335460ff16620011e65760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640162000786565b6001600160a01b03821662003d0a5760405163a22b4cd760e01b815260040160405180910390fd5b61012e5481101562002c315760405162461bcd60e51b815260206004820152602e60248201527f496e63657074696f6e5661756c743a206465706f7369746564206c657373207460448201526d1a185b881b5a5b88185b5bdd5b9d60921b606482015260840162000786565b60c9546040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201849052909116906323b872dd906064016020604051808303816000875af115801562003dd0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003df691906200481a565b6200091c5760c9546040516302ce902360e61b81526001600160a01b03909116600482015260240162000786565b60008111620016d65760405162461bcd60e51b815260206004820181905260248201527f496e63657074696f6e5661756c743a20726573756c7420695368617265732030604482015260640162000786565b600054610100900460ff1662003ea05760405162461bcd60e51b815260040162000786906200518a565b620011e63362003007565b600054610100900460ff1662003ed55760405162461bcd60e51b815260040162000786906200518a565b62003edf62003f0b565b62003ee962003f3f565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff1662003f355760405162461bcd60e51b815260040162000786906200518a565b620011e662003f73565b600054610100900460ff1662003f695760405162461bcd60e51b815260040162000786906200518a565b620011e662003fa9565b600054610100900460ff1662003f9d5760405162461bcd60e51b815260040162000786906200518a565b6033805460ff19169055565b600054610100900460ff1662002cb95760405162461bcd60e51b815260040162000786906200518a565b6106cc80620051d683390190565b6001600160a01b0381168114620016d657600080fd5b8035620040048162003fe1565b919050565b600080604083850312156200401d57600080fd5b823591506020830135620040318162003fe1565b809150509250929050565b6000815180845260005b81811015620040645760208185018101518683018201520162004046565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000620027bc60208301846200403c565b600060208284031215620040ac57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715620040ee57620040ee620040b3565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200411f576200411f620040b3565b604052919050565b60006001600160401b03831115620041435762004143620040b3565b62004158601f8401601f1916602001620040f4565b90508281528383830111156200416d57600080fd5b828260208301376000602084830101529392505050565b6000604082840312156200419757600080fd5b604051604081016001600160401b038282108183111715620041bd57620041bd620040b3565b816040528293508435915080821115620041d657600080fd5b508301601f81018513620041e957600080fd5b620041fa8582356020840162004127565b825250602083013560208201525092915050565b6000806000606084860312156200422457600080fd5b8335620042318162003fe1565b92506020840135915060408401356001600160401b038111156200425457600080fd5b620042628682870162004184565b9150509250925092565b600082601f8301126200427e57600080fd5b620027bc8383356020850162004127565b600080600080600060a08688031215620042a857600080fd5b85356001600160401b03811115620042bf57600080fd5b620042cd888289016200426c565b9550506020860135620042e08162003fe1565b93506040860135620042f28162003fe1565b92506060860135620043048162003fe1565b91506080860135620043168162003fe1565b809150509295509295909350565b6000602082840312156200433757600080fd5b8135620027bc8162003fe1565b600080604083850312156200435857600080fd5b8235620043658162003fe1565b946020939093013593505050565b6000806000604084860312156200438957600080fd5b8335620043968162003fe1565b925060208401356001600160401b0380821115620043b357600080fd5b818601915086601f830112620043c857600080fd5b813581811115620043d857600080fd5b8760208260051b8501011115620043ee57600080fd5b6020830194508093505050509250925092565b6000602082840312156200441457600080fd5b81356001600160401b038111156200442b57600080fd5b62002ca2848285016200426c565b600080600080608085870312156200445057600080fd5b843593506020850135620044648162003fe1565b92506040850135915060608501356001600160401b038111156200448757600080fd5b620044958782880162004184565b91505092959194509250565b600080600060608486031215620044b757600080fd5b833592506020840135620044cb8162003fe1565b929592945050506040919091013590565b600081518084526020808501945080840160005b838110156200450e57815187529582019590820190600101620044f0565b509495945050505050565b821515815260406020820152600062002ca26040830184620044dc565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000a465762000a4662004536565b6000602082840312156200457557600080fd5b5051919050565b600181811c908216806200459157607f821691505b602082108103620045b257634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526028908201527f456967656e4c6179657248616e646c65723a206f6e6c79206f70657261746f7260408201526708185b1b1bddd95960c21b606082015260800190565b6000602082840312156200461357600080fd5b8151620027bc8162003fe1565b6001600160a01b039586168152602081019490945263ffffffff9290921660408401529092166060820152608081019190915260a00190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156200450e5781516001600160a01b03168752958201959082019060010162004683565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156200473c57603f19898403018552815160608151818652620046fa828701826200466f565b915050888201518582038a870152620047148282620044dc565b928901516001600160a01b0316958901959095525094870194925090860190600101620046d1565b509098975050505050505050565b60006001600160401b03821115620047665762004766620040b3565b5060051b60200190565b600060208083850312156200478457600080fd5b82516001600160401b038111156200479b57600080fd5b8301601f81018513620047ad57600080fd5b8051620047c4620047be826200474a565b620040f4565b81815260059190911b82018301908381019087831115620047e457600080fd5b928401925b828410156200333657835182529284019290840190620047e9565b8181038181111562000a465762000a4662004536565b6000602082840312156200482d57600080fd5b81518015158114620027bc57600080fd5b602081526000620027bc6020830184620044dc565b803563ffffffff811681146200400457600080fd5b600082601f8301126200487a57600080fd5b813560206200488d620047be836200474a565b82815260059290921b84018101918181019086841115620048ad57600080fd5b8286015b84811015620048d5578035620048c78162003fe1565b8352918301918301620048b1565b509695505050505050565b600082601f830112620048f257600080fd5b8135602062004905620047be836200474a565b82815260059290921b840181019181810190868411156200492557600080fd5b8286015b84811015620048d5578035835291830191830162004929565b600062004953620047be846200474a565b80848252602080830192508560051b8501368111156200497257600080fd5b855b8181101562004a695780356001600160401b0380821115620049965760008081fd5b818901915060e08236031215620049ad5760008081fd5b620049b7620040c9565b620049c28362003ff7565b8152620049d186840162003ff7565b868201526040620049e481850162003ff7565b9082015260608381013590820152608062004a0181850162004853565b9082015260a0838101358381111562004a1a5760008081fd5b62004a283682870162004868565b82840152505060c0808401358381111562004a435760008081fd5b62004a5136828701620048e0565b91830191909152508752505093820193820162004974565b50919695505050505050565b6000808335601e1984360301811262004a8d57600080fd5b83016020810192503590506001600160401b0381111562004aad57600080fd5b8060051b360382131562004ac057600080fd5b9250929050565b8183526000602080850194508260005b858110156200450e57813562004aed8162003fe1565b6001600160a01b03168752958201959082019060010162004ad7565b81835260006001600160fb1b0383111562004b2357600080fd5b8260051b80836020870137939093016020019392505050565b600081518084526020808501808196508360051b810191508286016000805b8681101562004bb7578385038a52825180518087529087019087870190845b8181101562004ba15783516001600160a01b03168352928901929189019160010162004b7a565b50509a87019a9550509185019160010162004b5b565b509298975050505050505050565b600081518084526020808501945080840160005b838110156200450e57815115158752958201959082019060010162004bd9565b608080825281810186905260009060a0808401600589901b850182018a85805b8c81101562004d1b57888403609f190185528235368f900360de1901811262004c40578283fd5b8e0160e0813562004c518162003fe1565b6001600160a01b0316865260208281013562004c6d8162003fe1565b6001600160a01b031681880152604062004c8984820162003ff7565b6001600160a01b0316908801526060838101359088015262004cad8a840162004853565b63ffffffff168a88015262004cc5838a018462004a75565b838b8a015262004cd9848a01828462004ac7565b9350505060c062004ced8185018562004a75565b9450888403828a015262004d0384868362004b09565b99830199985050509490940193505060010162004c19565b505050858103602087015262004d32818a62004b3c565b9350505050828103604084015262004d4b8186620044dc565b9050828103606084015262004d61818562004bc5565b98975050505050505050565b60408152600080845462004d81816200457c565b806040860152606060018084166000811462004da6576001811462004dc15762004df4565b60ff1985168884015283151560051b88018301955062004df4565b8960005260208060002060005b8681101562004deb5781548b820187015290840190820162004dce565b8a018501975050505b5050505050828103602084015262004e0d81856200403c565b95945050505050565b601f82111562000b9c57600081815260208120601f850160051c8101602086101562004e3f5750805b601f850160051c820191505b8181101562000cbd5782815560010162004e4b565b81516001600160401b0381111562004e7c5762004e7c620040b3565b62004e948162004e8d84546200457c565b8462004e16565b602080601f83116001811462004ecc576000841562004eb35750858301515b600019600386901b1c1916600185901b17855562000cbd565b600085815260208120601f198616915b8281101562004efd5788860151825594840194600190910190840162004edc565b508582101562004f1c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001820162004f415762004f4162004536565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008262004f705762004f7062004f48565b500490565b60008262004f875762004f8762004f48565b500690565b808202811582820484141762000a465762000a4662004536565b600081516040845262004fbd60408501826200403c565b602093840151949093019390935250919050565b6001600160a01b038416815260606020820181905260009062004ff79083018562004fa6565b9050826040830152949350505050565b6000608080830181845280885180835260a092508286019150828160051b8701016020808c0160005b84811015620050d157898403609f19018652815180516001600160a01b0390811686528482015181168587015260408083015190911690860152606080820151908601528881015163ffffffff16898601528781015160e0898701819052906200509d828801826200466f565b91505060c08083015192508682038188015250620050bc8183620044dc565b97850197955050509082019060010162005030565b505087820390880152620050e6818b62004b3c565b9450505050508281036040840152620051008186620044dc565b9050828103606084015262003336818562004bc5565b600080604083850312156200512a57600080fd5b505080516020909101519092909150565b6001600160a01b038316815260406020820181905260009062002ca2908301846200403c565b60018060a01b038416815282602082015260606040820152600062004e0d606083018462004fa6565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe60806040526040516106cc3803806106cc83398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106a5602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b61014c806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122044bae01418f8f4d3e2aa454c2b5942f4fa2dcacad01b2d54be1f93cf2feef3dc64736f6c63430008140033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220ff87365d90f14afb2d0e7e6a8d5137988488ef3ea7d297ac5eae99146ec409e064736f6c63430008140033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.