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 | 19903305 | 57 days ago | IN | Create: InVault_E1 | 0 ETH | 0.0173097 |
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(); } /*/////////////////////////////////// /////////// M2 migration /////////// /////////////////////////////////*/ function setWithdrawalQueue( address[] memory receivers ) external onlyOperator { uint256 numberOfReceivers = receivers.length; // let's update redeemReservedAmount and epoch for (uint256 i = 0; i < numberOfReceivers; ) { address receiver = receivers[i]; Withdrawal storage request = _claimerWithdrawals[receiver]; uint256 amount = request.amount; if (amount == 0) { unchecked { ++i; } continue; } request.epoch = 0; // update global state and claimer's state claimerWithdrawalsQueue.push( Withdrawal({ epoch: claimerWithdrawalsQueue.length, receiver: receiver, amount: amount }) ); unchecked { ++i; } } } function setUpdatedEpoch(address[] memory receivers) external onlyOperator { uint256 numberOfReceivers = receivers.length; // let's update redeemReservedAmount and epoch for (uint256 i = 0; i < numberOfReceivers; ) { address receiver = receivers[i]; Withdrawal storage request = _claimerWithdrawals[receiver]; request.epoch = 0; unchecked { ++i; } } } function getWithdrawal( address claimer ) public view returns (Withdrawal memory) { return _claimerWithdrawals[claimer]; } function updateEpoch(uint256 newEpoch) external onlyOperator { epoch = newEpoch; } }
// 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":[{"internalType":"address","name":"claimer","type":"address"}],"name":"getWithdrawal","outputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IEigenLayerHandler.Withdrawal","name":"","type":"tuple"}],"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":[{"internalType":"address[]","name":"receivers","type":"address[]"}],"name":"setUpdatedEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"}],"name":"setWithdrawalQueue","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":[{"internalType":"uint256","name":"newEpoch","type":"uint256"}],"name":"updateEpoch","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
60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b615ce880620000f36000396000f3fe60806040523480156200001157600080fd5b50600436106200032f5760003560e01c80638da5cb5b11620001bf578063c235fb1411620000fc578063e91bb84411620000af578063edb594fc1162000086578063edb594fc1462000759578063ef13b2c71462000770578063f29768711462000797578063f2fde38b14620007a157600080fd5b8063e91bb84414620006f2578063ea4d3c9b146200072d578063eae43a44146200074257600080fd5b8063c235fb14146200066a578063c47f0027146200067f578063c6e6f5921462000696578063ce5119ee14620006ad578063d2a7666314620006c4578063d9540d6a14620006db57600080fd5b8063a8c62e761162000172578063ac579b771162000149578063ac579b77146200061b578063b3ab15fb1462000632578063b68ef5591462000649578063b9ff20c8146200065357600080fd5b8063a8c62e7614620005c0578063ab89b6af14620005d4578063ac48eb9f146200060457600080fd5b80638da5cb5b1462000528578063900cf0cf146200053a57806395a2251f146200054457806399f62bab146200055b5780639b2cb5d8146200059e578063a0ed8b9914620005a957600080fd5b806339b70e38116200028e57806366bcd641116200024157806371ca337d116200021857806371ca337d14620004e6578063841143d214620004f05780638456cb591462000507578063897b0637146200051157600080fd5b806366bcd64114620004bb5780636e553f6514620004c5578063715018a614620004dc57600080fd5b806339b70e3814620004385780633f4ba83a14620004655780634fe2bb82146200046f57806353268ad014620004865780635c60da1b14620004915780635c975abb14620004a457600080fd5b806315ca0dc011620002e757806315ca0dc014620003c85780631a8d0de214620003df578063252b7edc14620003f65780632df2228a146200040d5780633659cfe6146200041757806336f4fb02146200042e57600080fd5b8062f714ce146200033457806301e1d114146200034d57806306fdde03146200036a57806307a2d13a1462000383578063081ab7ad146200039a5780630b885ac314620003b1575b600080fd5b6200034b620003453660046200437e565b620007b8565b005b6200035762000a0b565b6040519081526020015b60405180910390f35b6200037462000a80565b604051620003619190620043f9565b62000357620003943660046200440e565b62000b17565b6200034b620003ab36600462004583565b62000b37565b6200034b620003c236600462004604565b62000c8c565b6200034b620003d93660046200440e565b62000db0565b6200034b620003f036600462004699565b62000de2565b6200034b62000407366004620046b9565b62000e83565b6101005462000357565b6200034b6200042836600462004699565b620011fe565b6200034b620012ef565b60fb546200044c906001600160a01b031681565b6040516001600160a01b03909116815260200162000361565b6200034b62001305565b6200034b620004803660046200440e565b62001319565b620003576101035481565b610131546001600160a01b03166200044c565b60335460ff16604051901515815260200162000361565b6200035760ff5481565b62000357620004d63660046200437e565b620017f6565b6200034b62001826565b620003576200183c565b6200034b620005013660046200437e565b62001930565b6200034b62001adc565b6200034b620005223660046200440e565b62001af0565b6097546001600160a01b03166200044c565b6200035760fd5481565b6200034b6200055536600462004699565b62001b3d565b620005726200056c36600462004699565b62001e74565b60408051825181526020808401516001600160a01b031690820152918101519082015260600162000361565b6200035761012e5481565b6200034b620005ba36600462004699565b62001ee7565b60fc546200044c906001600160a01b031681565b62000357620005e536600462004699565b6001600160a01b0316600090815261012f602052604090206002015490565b6200034b62000615366004620046e8565b62002096565b6200034b6200062c3660046200479c565b620023d6565b6200034b6200064336600462004699565b6200253a565b62000357620025d5565b6200034b620006643660046200440e565b62002607565b61012d546200044c906001600160a01b031681565b6200034b620006903660046200483b565b62002711565b62000357620006a73660046200440e565b6200278a565b62000357620006be36600462004699565b620027aa565b6200034b620006d53660046200479c565b62002831565b6200034b620006ec36600462004873565b620028b2565b62000709620007033660046200440e565b62002a69565b604080519384526001600160a01b0390921660208401529082015260600162000361565b610101546200044c906001600160a01b031681565b6200044c620007533660046200440e565b62002aaa565b620003576200076a366004620048db565b62002ad6565b620007876200078136600462004699565b62002b38565b6040516200036192919062004953565b6200035762002cb0565b6200034b620007b236600462004699565b62002e3d565b620007c262002eb9565b620007cc62002f01565b620007d8818362002f5c565b336000620007f984670de0b6b3a7640000620007f36200183c565b62002fce565b905061012e548110156200087a5760405162461bcd60e51b815260206004820152603a60248201527f496e63657074696f6e5661756c743a20616d6f756e74206973206c657373207460448201527f68616e20746865206d696e696d756d207769746864726177616c00000000000060648201526084015b60405180910390fd5b61012d54604051632770a7eb60e21b81526001600160a01b0384811660048301526024820187905290911690639dc29fac90604401600060405180830381600087803b158015620008ca57600080fd5b505af1158015620008df573d6000803e3d6000fd5b505050508060ff6000828254620008f7919062004986565b90915550506001600160a01b038316600090815261012f6020526040902062000920826200301f565b81600201600082825462000935919062004986565b909155505060408051606081018252610102805482526001600160a01b038716602083015291810162000968856200301f565b9052815460018082018455600093845260209384902083516003909302019182558284015190820180546001600160a01b0319166001600160a01b039283161790556040928301516002909201919091558151858152928301889052858116929087169183917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a450505062000a076001606555565b5050565b60c9546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000a55573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a7b91906200499c565b905090565b610130805462000a9090620049b6565b80601f016020809104026020016040519081016040528092919081815260200182805462000abe90620049b6565b801562000b0f5780601f1062000ae35761010080835404028352916020019162000b0f565b820191906000526020600020905b81548152906001019060200180831162000af157829003601f168201915b505050505081565b600062000b3182670de0b6b3a7640000620007f36200183c565b92915050565b62000b4162002f01565b62000b4b62002eb9565b60fe546001600160a01b0316331462000b785760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b03831662000ba05760405163a22b4cd760e01b815260040160405180910390fd5b61010154604051631976849960e21b81523060048201526000916001600160a01b0316906365da126490602401602060405180830381865afa15801562000beb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c11919062004a3a565b6001600160a01b03161462000c3957604051631a30c08d60e31b815260040160405180910390fd5b62000c4683838362003035565b6040516001600160a01b0384169030907f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38790600090a362000c876001606555565b505050565b600054610100900460ff161580801562000cad5750600054600160ff909116105b8062000cc95750303b15801562000cc9575060005460ff166001145b62000d2e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000871565b6000805460ff19166001179055801562000d52576000805461ff0019166101001790555b62000d618686868686620030a5565b801562000da8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60fe546001600160a01b0316331462000ddd5760405162461bcd60e51b81526004016200087190620049f2565b60fd55565b62000dec62003104565b610101546001600160a01b03161562000e1857604051634fa0a5d560e11b815260040160405180910390fd5b61010154604080516001600160a01b03928316815291831660208301527fbae75576f1af1fe832366c069d0608003eb7aad2dcc476a5158f70b2b67d3d8b910160405180910390a161010180546001600160a01b0319166001600160a01b0392909216919091179055565b62000e8d62002eb9565b62000e9762002f01565b60fe546001600160a01b0316331462000ec45760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b0380831660009081526101046020526040902054168062000eff576040516325ec6c1f60e01b815260040160405180910390fd5b6612344fffffffff196001600160a01b0382160162000f315760405163a22b4cd760e01b815260040160405180910390fd5b6101015460405163285e212160e21b81526001600160a01b038381166004830152600092169063a178848490602401602060405180830381865afa15801562000f7e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fa491906200499c565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa15801562000fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200102591906200499c565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa15801562001075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200109b91906200499c565b9050620010aa81600562004986565b821015620010b55750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa158015620010ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200112591906200499c565b60fc546040519196506001600160a01b03808716927fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec520829262001171921690859043908c908a9062004a5a565b60405180910390a28461010060008282546200118e919062004986565b909155505060405163b64d26ab60e01b8152600481018290526001600160a01b0385169063b64d26ab90602401600060405180830381600087803b158015620011d657600080fd5b505af1158015620011eb573d6000803e3d6000fd5b505050505050505062000a076001606555565b6200120862002eb9565b6200121262003104565b6001600160a01b0381163b620012845760405162461bcd60e51b815260206004820152603060248201527f496e63657074696f6e5661756c743a20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b606482015260840162000871565b61013154604080516001600160a01b03928316815291831660208301527f1a5ca99a64512489fd9455e8da426740174107a69292fca0a8b80b08f6f67892910160405180910390a161013180546001600160a01b0319166001600160a01b0392909216919091179055565b620012f962002eb9565b6200130362003160565b565b6200130f62003104565b62001303620031ec565b6200132362002eb9565b6200132d62002f01565b60fe546001600160a01b031633146200135a5760405162461bcd60e51b81526004016200087190620049f2565b6101015460405163285e212160e21b81523060048201819052916000916001600160a01b039091169063a178848490602401602060405180830381865afa158015620013aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013d091906200499c565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa1580156200142b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200145191906200499c565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa158015620014a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014c791906200499c565b9050620014d681600562004986565b821015620014e15750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa1580156200152b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200155191906200499c565b60408051600180825281830190925291965060009190602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060fc5482519293506001600160a01b031691839150600090620015bd57620015bd62004a93565b60200260200101906001600160a01b031690816001600160a01b0316815250508282600081518110620015f457620015f462004a93565b6020908102919091010152604080516001808252818301909252600091816020015b60408051606080820183528082526020820152600091810191909152815260200190600190039081620016165790505090506040518060600160405280838152602001848152602001306001600160a01b03168152508160008151811062001682576200168262004a93565b6020026020010181905250876101006000828254620016a2919062004986565b9091555050610101546040516306ec6e8160e11b81526001600160a01b0390911690630dd8dd0290620016da90849060040162004ae4565b6000604051808303816000875af1158015620016fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001724919081019062004b84565b5060fc5461010154604051631976849960e21b81526001600160a01b038a811660048301819052937fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec5208293908216928992439216906365da126490602401602060405180830381865afa1580156200179f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c5919062004a3a565b8b604051620017d995949392919062004a5a565b60405180910390a250505050505050620017f36001606555565b50565b60006200180262002f01565b6200180c62002eb9565b6200181983338462003240565b905062000b316001606555565b6200183062003104565b6200130360006200337c565b60008062001849620025d5565b9050600061012d60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c891906200499c565b9050600060ff548310620018eb5760ff54620018e5908462004c12565b620018ee565b60005b9050801580620018fc575081155b156200191357670de0b6b3a7640000935050505090565b6200192882670de0b6b3a764000083620033ce565b935050505090565b60fe546001600160a01b031633146200195d5760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b038116620019855760405163a22b4cd760e01b815260040160405180910390fd5b60005b6101055481101562001abd57816001600160a01b03166101058281548110620019b557620019b562004a93565b6000918252602090912001546001600160a01b031614801562001a7b57506101015461010580546001600160a01b0390921691633e28391d91908490811062001a025762001a0262004a93565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562001a53573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a79919062004c28565b155b1562001ab45766123450000000006001600160a01b0316610105828154811062001aa95762001aa962004a93565b506000525062001abd565b60010162001988565b5081610100600082825462001ad3919062004986565b90915550505050565b62001ae662003104565b6200130362003452565b62001afa62003104565b61012e5460408051918252602082018390527f633c1a71f1236c727d460906a677e5c96556b3f5ad34c9b64072540f1c2eddea910160405180910390a161012e55565b62001b4762002eb9565b62001b5162002f01565b60008062001b5f8362002b38565b915091508162001bc45760405162461bcd60e51b815260206004820152602960248201527f496e63657074696f6e5661756c743a2072656465656d2063616e206e6f74206260448201526819481c1c9bd8d9595960ba1b606482015260840162000871565b80516000816001600160401b0381111562001be35762001be362004428565b60405190808252806020026020018201604052801562001c0d578160200160208202803683370190505b506001600160a01b038616600090815261012f60205260408120919250805b8481101562001daf57600086828151811062001c4c5762001c4c62004a93565b602002602001015190506000610102828154811062001c6f5762001c6f62004a93565b600091825260208083206040805160608101825260039094029091018054845260018101546001600160a01b03169284019290925260029182015490830181905290880180549294509092839262001cc990849062004c12565b9091555062001cda90508162003492565b60ff600082825462001ced919062004c12565b9250508190555080610103600082825462001d09919062004c12565b9091555062001d1b9050818662004986565b94508287858151811062001d335762001d3362004a93565b60200260200101818152505061010289858151811062001d575762001d5762004a93565b60200260200101518154811062001d725762001d7262004a93565b600091825260208220600390910201818155600180820180546001600160a01b031916905560029091019190915593909301925062001c2c915050565b508462001dbe60018662004c12565b8151811062001dd15762001dd162004a93565b6020908102919091010151825562001dea8782620034a1565b7fd4e9104c456539f8bc402dcb01d19f8d74a18e45395a5b518feb89fbbda5961c8360405162001e1b919062004c4c565b60405180910390a16040518181526001600160a01b0388169033907fd12200efa34901b99367694174c3b0d32c99585fdf37c7c26892136ddd0836d99060200160405180910390a3505050505050620017f36001606555565b62001ea260405180606001604052806000815260200160006001600160a01b03168152602001600081525090565b506001600160a01b03908116600090815261012f6020908152604091829020825160608101845281548152600182015490941691840191909152600201549082015290565b62001ef162003104565b610101546040516336b87bd760e11b81526001600160a01b03838116600483015290911690636d70f7ae90602401602060405180830381865afa15801562001f3d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001f63919062004c28565b62001fc25760405162461bcd60e51b815260206004820152602860248201527f496e63657074696f6e5661756c743a206974206973206e6f7420616e20454c2060448201526737b832b930ba37b960c11b606482015260840162000871565b6001600160a01b038181166000908152610104602052604090205416156200203d5760405162461bcd60e51b815260206004820152602760248201527f496e63657074696f6e5661756c743a206f70657261746f7220616c72656164796044820152662065786973747360c81b606482015260840162000871565b6001600160a01b0381166000818152610104602052604080822080546001600160a01b0319166612345000000000179055517f3b2e539a214fa1a91dca8c6e5c54b67f6429ae3142a56bd7e07bd1a1955706b69190a250565b620020a062002eb9565b620020aa62002f01565b806000816001600160401b03811115620020c857620020c862004428565b604051908082528060200260200182016040528015620020fd57816020015b6060815260200190600190039081620020e75790505b5090506000826001600160401b038111156200211d576200211d62004428565b60405190808252806020026020018201604052801562002147578160200160208202803683370190505b5090506000836001600160401b0381111562002167576200216762004428565b60405190808252806020026020018201604052801562002191578160200160208202803683370190505b50905060005b848110156200227157604080516001808252818301909252906020808301908036833701905050848281518110620021d357620021d362004a93565b602090810291909101015260c95484516001600160a01b039091169085908390811062002204576200220462004a93565b602002602001015160008151811062002221576200222162004a93565b60200260200101906001600160a01b031690816001600160a01b031681525050600182828151811062002258576200225862004a93565b9115156020928302919091019091015260010162002197565b506000306001600160a01b03891603620022a6576200229e62002295878962004d50565b85858562003549565b90506200234e565b620022b188620036b6565b620022cf5760405163563fb6d760e11b815260040160405180910390fd5b604051631de1b03360e01b81526001600160a01b03891690631de1b0339062002305908a908a908990899089906004016200500a565b6020604051808303816000875af115801562002325573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200234b91906200499c565b90505b6040518181527f8772d6f79a1845a0c0e90ef18d99f91242bbc0ba98c9ca780feaad42b81f02ba9060200160405180910390a1806101005410620023a35780610100546200239d919062004c12565b620023a6565b60005b61010081905560071115620023bc576000610100555b620023c662003160565b505050505062000c876001606555565b60fe546001600160a01b03163314620024035760405162461bcd60e51b81526004016200087190620049f2565b805160005b8181101562000c8757600083828151811062002428576200242862004a93565b6020908102919091018101516001600160a01b038116600090815261012f909252604082206002810154919350918190036200246d5783600101935050505062002408565b6000918290556040805160608101825261010280548083526001600160a01b0396871660208401908152938301948552600180820183559190955290517f93bdaa6a4190909b7c3fbe8d42169ffe1cab19f51dfc8db24c71abf849eced4a60039095029485015590517f93bdaa6a4190909b7c3fbe8d42169ffe1cab19f51dfc8db24c71abf849eced4b840180546001600160a01b0319169190951617909355517f93bdaa6a4190909b7c3fbe8d42169ffe1cab19f51dfc8db24c71abf849eced4c909101550162002408565b6200254462003104565b6001600160a01b0381166200256c5760405163a22b4cd760e01b815260040160405180910390fd5b60fe54604080516001600160a01b03928316815291831660208301527fd58299b712891143e76310d5e664c4203c940a67db37cf856bdaa3c5c76a802c910160405180910390a160fe80546001600160a01b0319166001600160a01b0392909216919091179055565b600061010054620025e562000a0b565b620025ef62002cb0565b620025fb919062004986565b62000a7b919062004986565b6200261162002f01565b60fe546001600160a01b031633146200263e5760405162461bcd60e51b81526004016200087190620049f2565b62002649816200371c565b60fb5460fc5460c9546040516373d0285560e11b81526001600160a01b03928316600482015290821660248201526044810184905291169063e7a050aa906064016020604051808303816000875af1158015620026aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026d091906200499c565b5060405181815230907f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b79060200160405180910390a2620017f36001606555565b6200271b62003104565b80516000036200273e5760405163a22b4cd760e01b815260040160405180910390fd5b7f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a61013082604051620027739291906200517e565b60405180910390a161013062000a07828262005271565b600062000b31826200279b6200183c565b670de0b6b3a764000062002fce565b60fc546001600160a01b0382811660009081526101046020526040808220549051630aa794bf60e31b815290831660048201529092919091169063553ca5f890602401602060405180830381865afa1580156200280b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3191906200499c565b60fe546001600160a01b031633146200285e5760405162461bcd60e51b81526004016200087190620049f2565b805160005b8181101562000c8757600083828151811062002883576200288362004a93565b6020908102919091018101516001600160a01b0316600090815261012f90915260408120555060010162002863565b620028bc62002f01565b620028c662002eb9565b60fe546001600160a01b03163314620028f35760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b0383166200291b5760405163a22b4cd760e01b815260040160405180910390fd5b62002926846200371c565b6001600160a01b0380841660009081526101046020526040902054168062002961576040516325ec6c1f60e01b815260040160405180910390fd5b60006612344fffffffff196001600160a01b03831601620029f55750600162002989620038b9565b6001600160a01b0380871660009081526101046020526040812080549284166001600160a01b03199384168117909155610105805460018101825592527ffc62abc8c0fc47c2d92f5aec99bf8b60f375828e14394d89345cae11a9867371909101805490921617905591505b62002a01828762003a4c565b801562002a165762002a168286868662003b6b565b846001600160a01b0316826001600160a01b03167f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38760405160405180910390a3505062002a636001606555565b50505050565b610102818154811062002a7b57600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b039091169083565b610105818154811062002abc57600080fd5b6000918252602090912001546001600160a01b0316905081565b600062002ae262002f01565b62002aec62002eb9565b60405182907f3c16de186f1ef5ecb8049424d69d8038355dfdd932e194e95067b0dadd05259890600090a262002b2484338562003240565b905062002b316001606555565b9392505050565b6001600160a01b03808216600090815261012f6020908152604080832081516060818101845282548083526001840154909716948201949094526002909101549181019190915260fd5492939192849290839062002b9890839062004c12565b6001600160401b0381111562002bb25762002bb262004428565b60405190808252806020026020018201604052801562002bdc578160200160208202803683370190505b509050826040015160000362002bfa57600097909650945050505050565b60005b60fd5481101562002c8857876001600160a01b0316610102828154811062002c295762002c2962004a93565b60009182526020909120600160039092020101546001600160a01b03160362002c7f57600196508082868151811062002c665762002c6662004a93565b602090810291909101015262002c7c856200533d565b94505b60010162002bfd565b50600084825162002c9a919062004c12565b111562002ca5578381525b949694955050505050565b61010554600090815b8181101562002dbb5760006001600160a01b0316610105828154811062002ce45762002ce462004a93565b6000918252602090912001546001600160a01b03161462002cb95760fc5461010580546001600160a01b039092169163553ca5f891908490811062002d2d5762002d2d62004a93565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562002d7e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002da491906200499c565b62002db0908462004986565b925060010162002cb9565b5060fc54604051630aa794bf60e31b81523060048201526001600160a01b039091169063553ca5f890602401602060405180830381865afa15801562002e05573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002e2b91906200499c565b62002e37908362004986565b91505090565b62002e4762003104565b6001600160a01b03811662002eae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000871565b620017f3816200337c565b60335460ff1615620013035760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000871565b60026065540362002f555760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000871565b6002606555565b8060000362002f7e5760405163a22b4cd760e01b815260040160405180910390fd5b6001600160a01b03821662002fa65760405163a22b4cd760e01b815260040160405180910390fd5b62002fb062003bd7565b62000a0757604051638e201a8b60e01b815260040160405180910390fd5b60006200301762002feb62002fe484876200536f565b8562003de7565b838562002ff9828962005386565b6200300591906200539d565b6200301191906200536f565b62003e24565b949350505050565b600062000b3160018362004c12565b6001606555565b6101015460405163eea9064b60e01b81526001600160a01b039091169063eea9064b906200306c90869085908790600401620053e2565b600060405180830381600087803b1580156200308757600080fd5b505af11580156200309c573d6000803e3d6000fd5b50505050505050565b620030af62003e3e565b620030bb838262003e72565b610130620030ca868262005271565b505060fe80546001600160a01b039485166001600160a01b03199182161790915561012d8054929094169116179091555050606461012e55565b6097546001600160a01b03163314620013035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000871565b61010254610103546000906200317562000a0b565b62003181919062004c12565b60fd549091505b8281101562000c875760006101028281548110620031aa57620031aa62004a93565b906000526020600020906003020160020154905082811115620031cd5750505050565b61010380548201905560fd805460019081019091559203910162003188565b620031f66200400c565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000806200324d6200183c565b90506200325b838662004057565b60006200326762000a0b565b9050620032758587620040eb565b806200328062000a0b565b6200328c919062004c12565b95506000620032a58784670de0b6b3a764000062002fce565b61012d546040516340c10f1960e01b81526001600160a01b038881166004830152602482018490529293509116906340c10f1990604401600060405180830381600087803b158015620032f757600080fd5b505af11580156200330c573d6000803e3d6000fd5b505050506200331b8162004199565b846001600160a01b0316866001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d789846040516200336a929190918252602082015260400190565b60405180910390a39695505050505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000816000036200340b5760405162461bcd60e51b8152602060048201526006602482015265063203d3d20360d41b604482015260640162000871565b620030176200341f62002fe484876200536f565b836200342d60018262004c12565b866200343a878a62005386565b6200344691906200539d565b62003005919062004986565b6200345c62002eb9565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620032233390565b600062000b3182600162004986565b60c95460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303816000875af1158015620034f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200351b919062004c28565b62000a075760c954604051631fca53a760e11b81526001600160a01b03909116600482015260240162000871565b60c9546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003597573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620035bd91906200499c565b610101546040516319a021cb60e11b81529192506001600160a01b031690633340439690620035f790899089908990899060040162005418565b600060405180830381600087803b1580156200361257600080fd5b505af115801562003627573d6000803e3d6000fd5b505060c9546040516370a0823160e01b8152306004820152600093508492506001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003679573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200369f91906200499c565b620036ab919062004c12565b979650505050505050565b61010554600090815b8181101562003712576101058181548110620036df57620036df62004a93565b6000918252602090912001546001600160a01b039081169085160362003709575060019392505050565b600101620036bf565b5060009392505050565b610103546200372a62000a0b565b62003736919062004c12565b81111562003765576200374862000a0b565b604051636688dd2d60e11b81526004016200087191815260200190565b60fc546040805163df6fadc160e01b8152815160009384936001600160a01b039091169263df6fadc192600480830193928290030181865afa158015620037b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620037d6919062005527565b91509150818311156200380757604051633c690bcb60e11b8152600481018390526024810184905260440162000871565b60c95460fc546040516370a0823160e01b81526001600160a01b03918216600482015260009291909116906370a0823190602401602060405180830381865afa15801562003859573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200387f91906200499c565b9050816200388e858362004986565b111562002a6357604051630dbbc86f60e11b8152600481018390526024810182905260440162000871565b610131546000906001600160a01b0316620038e7576040516340dde93560e01b815260040160405180910390fd5b6101015460fb5460fc5460fe546040516001600160a01b0394851660248201529284166044840152908316606483015291909116608482015260009060a40160408051601f198184030181529181526020820180516001600160e01b0316637c643b2f60e11b1790525190915060009030908390620039669062004348565b620039739291906200554c565b604051809103906000f08015801562003990573d6000803e3d6000fd5b509050806001600160a01b03811663f2fde38b620039b66097546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015620039f857600080fd5b505af115801562003a0d573d6000803e3d6000fd5b50506040516001600160a01b03851692507f9e676714ad2ee7d362cccabb3a543102aada709f27c2bda6bf6ef42fce70ff259150600090a25092915050565b60c95460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af115801562003aa0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003ac6919062004c28565b50604051635466590560e01b8152600481018290526001600160a01b03831690635466590590602401600060405180830381600087803b15801562003b0a57600080fd5b505af115801562003b1f573d6000803e3d6000fd5b50505050816001600160a01b03167f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b78260405162003b5f91815260200190565b60405180910390a25050565b60405163511e274f60e01b81526001600160a01b0385169063511e274f9062003b9d9086908690869060040162005572565b600060405180830381600087803b15801562003bb857600080fd5b505af115801562003bcd573d6000803e3d6000fd5b5050505050505050565b6000805b6101055481101562003ce95760006001600160a01b0316610105828154811062003c095762003c0962004a93565b6000918252602090912001546001600160a01b03160362003c2d5760010162003bdb565b6101015461010580546001600160a01b0390921691633e28391d91908490811062003c5c5762003c5c62004a93565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562003cad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003cd3919062004c28565b62003ce057600091505090565b60010162003bdb565b5060fc54604051630aa794bf60e31b81523060048201526000916001600160a01b03169063553ca5f890602401602060405180830381865afa15801562003d34573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003d5a91906200499c565b11801562003dd5575061010154604051633e28391d60e01b81523060048201526001600160a01b0390911690633e28391d90602401602060405180830381865afa15801562003dad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003dd3919062004c28565b155b1562003de15750600090565b50600190565b60008260000362003dfb5750600062000b31565b8282028284828162003e115762003e1162005359565b041462002b315760001991505062000b31565b60008282018381101562002b315760001991505062000b31565b600054610100900460ff1662003e685760405162461bcd60e51b815260040162000871906200559b565b62001303620041eb565b600054610100900460ff1662003e9c5760405162461bcd60e51b815260040162000871906200559b565b60fb80546001600160a01b038085166001600160a01b03199283161790925560fc8054928416929091168217905560408051632495a59960e01b8152905162003f379291632495a5999160048083019260209291908290030181865afa15801562003f0b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003f31919062004a3a565b62004220565b60c95460fb5460405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af115801562003f8e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003fb4919062004c28565b62000a075760405162461bcd60e51b815260206004820152602160248201527f456967656e4c6179657248616e646c65723a20617070726f7665206661696c656044820152601960fa1b606482015260840162000871565b60335460ff16620013035760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640162000871565b6001600160a01b0382166200407f5760405163a22b4cd760e01b815260040160405180910390fd5b61012e5481101562002fa65760405162461bcd60e51b815260206004820152602e60248201527f496e63657074696f6e5661756c743a206465706f7369746564206c657373207460448201526d1a185b881b5a5b88185b5bdd5b9d60921b606482015260840162000871565b60c9546040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201849052909116906323b872dd906064016020604051808303816000875af115801562004145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200416b919062004c28565b62000a075760c9546040516302ce902360e61b81526001600160a01b03909116600482015260240162000871565b60008111620017f35760405162461bcd60e51b815260206004820181905260248201527f496e63657074696f6e5661756c743a20726573756c7420695368617265732030604482015260640162000871565b600054610100900460ff16620042155760405162461bcd60e51b815260040162000871906200559b565b62001303336200337c565b600054610100900460ff166200424a5760405162461bcd60e51b815260040162000871906200559b565b6200425462004280565b6200425e620042b4565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16620042aa5760405162461bcd60e51b815260040162000871906200559b565b62001303620042e8565b600054610100900460ff16620042de5760405162461bcd60e51b815260040162000871906200559b565b620013036200431e565b600054610100900460ff16620043125760405162461bcd60e51b815260040162000871906200559b565b6033805460ff19169055565b600054610100900460ff166200302e5760405162461bcd60e51b815260040162000871906200559b565b6106cc80620055e783390190565b6001600160a01b0381168114620017f357600080fd5b8035620043798162004356565b919050565b600080604083850312156200439257600080fd5b823591506020830135620043a68162004356565b809150509250929050565b6000815180845260005b81811015620043d957602081850181015186830182015201620043bb565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600062002b316020830184620043b1565b6000602082840312156200442157600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171562004463576200446362004428565b60405290565b604051601f8201601f191681016001600160401b038111828210171562004494576200449462004428565b604052919050565b60006001600160401b03831115620044b857620044b862004428565b620044cd601f8401601f191660200162004469565b9050828152838383011115620044e257600080fd5b828260208301376000602084830101529392505050565b6000604082840312156200450c57600080fd5b604051604081016001600160401b03828210818311171562004532576200453262004428565b8160405282935084359150808211156200454b57600080fd5b508301601f810185136200455e57600080fd5b6200456f858235602084016200449c565b825250602083013560208201525092915050565b6000806000606084860312156200459957600080fd5b8335620045a68162004356565b92506020840135915060408401356001600160401b03811115620045c957600080fd5b620045d786828701620044f9565b9150509250925092565b600082601f830112620045f357600080fd5b62002b31838335602085016200449c565b600080600080600060a086880312156200461d57600080fd5b85356001600160401b038111156200463457600080fd5b6200464288828901620045e1565b9550506020860135620046558162004356565b93506040860135620046678162004356565b92506060860135620046798162004356565b915060808601356200468b8162004356565b809150509295509295909350565b600060208284031215620046ac57600080fd5b813562002b318162004356565b60008060408385031215620046cd57600080fd5b8235620046da8162004356565b946020939093013593505050565b600080600060408486031215620046fe57600080fd5b83356200470b8162004356565b925060208401356001600160401b03808211156200472857600080fd5b818601915086601f8301126200473d57600080fd5b8135818111156200474d57600080fd5b8760208260051b85010111156200476357600080fd5b6020830194508093505050509250925092565b60006001600160401b0382111562004792576200479262004428565b5060051b60200190565b60006020808385031215620047b057600080fd5b82356001600160401b03811115620047c757600080fd5b8301601f81018513620047d957600080fd5b8035620047f0620047ea8262004776565b62004469565b81815260059190911b820183019083810190878311156200481057600080fd5b928401925b82841015620036ab5783356200482b8162004356565b8252928401929084019062004815565b6000602082840312156200484e57600080fd5b81356001600160401b038111156200486557600080fd5b6200301784828501620045e1565b600080600080608085870312156200488a57600080fd5b8435935060208501356200489e8162004356565b92506040850135915060608501356001600160401b03811115620048c157600080fd5b620048cf87828801620044f9565b91505092959194509250565b600080600060608486031215620048f157600080fd5b833592506020840135620049058162004356565b929592945050506040919091013590565b600081518084526020808501945080840160005b8381101562004948578151875295820195908201906001016200492a565b509495945050505050565b821515815260406020820152600062003017604083018462004916565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000b315762000b3162004970565b600060208284031215620049af57600080fd5b5051919050565b600181811c90821680620049cb57607f821691505b602082108103620049ec57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526028908201527f456967656e4c6179657248616e646c65723a206f6e6c79206f70657261746f7260408201526708185b1b1bddd95960c21b606082015260800190565b60006020828403121562004a4d57600080fd5b815162002b318162004356565b6001600160a01b039586168152602081019490945263ffffffff9290921660408401529092166060820152608081019190915260a00190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015620049485781516001600160a01b03168752958201959082019060010162004abd565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101562004b7657603f1989840301855281516060815181865262004b348287018262004aa9565b915050888201518582038a87015262004b4e828262004916565b928901516001600160a01b031695890195909552509487019492509086019060010162004b0b565b509098975050505050505050565b6000602080838503121562004b9857600080fd5b82516001600160401b0381111562004baf57600080fd5b8301601f8101851362004bc157600080fd5b805162004bd2620047ea8262004776565b81815260059190911b8201830190838101908783111562004bf257600080fd5b928401925b82841015620036ab5783518252928401929084019062004bf7565b8181038181111562000b315762000b3162004970565b60006020828403121562004c3b57600080fd5b8151801515811462002b3157600080fd5b60208152600062002b31602083018462004916565b803563ffffffff811681146200437957600080fd5b600082601f83011262004c8857600080fd5b8135602062004c9b620047ea8362004776565b82815260059290921b8401810191818101908684111562004cbb57600080fd5b8286015b8481101562004ce357803562004cd58162004356565b835291830191830162004cbf565b509695505050505050565b600082601f83011262004d0057600080fd5b8135602062004d13620047ea8362004776565b82815260059290921b8401810191818101908684111562004d3357600080fd5b8286015b8481101562004ce3578035835291830191830162004d37565b600062004d61620047ea8462004776565b80848252602080830192508560051b85013681111562004d8057600080fd5b855b8181101562004e775780356001600160401b038082111562004da45760008081fd5b818901915060e0823603121562004dbb5760008081fd5b62004dc56200443e565b62004dd0836200436c565b815262004ddf8684016200436c565b86820152604062004df28185016200436c565b9082015260608381013590820152608062004e0f81850162004c61565b9082015260a0838101358381111562004e285760008081fd5b62004e363682870162004c76565b82840152505060c0808401358381111562004e515760008081fd5b62004e5f3682870162004cee565b91830191909152508752505093820193820162004d82565b50919695505050505050565b6000808335601e1984360301811262004e9b57600080fd5b83016020810192503590506001600160401b0381111562004ebb57600080fd5b8060051b360382131562004ece57600080fd5b9250929050565b8183526000602080850194508260005b858110156200494857813562004efb8162004356565b6001600160a01b03168752958201959082019060010162004ee5565b81835260006001600160fb1b0383111562004f3157600080fd5b8260051b80836020870137939093016020019392505050565b600082825180855260208086019550808260051b8401018186016000805b8581101562004fc857868403601f19018a52825180518086529086019086860190845b8181101562004fb25783516001600160a01b03168352928801929188019160010162004f8b565b50509a86019a9450509184019160010162004f68565b509198975050505050505050565b600081518084526020808501945080840160005b838110156200494857815115158752958201959082019060010162004fea565b608080825281810186905260009060a0808401600589901b850182018a85805b8c8110156200512c57888403609f190185528235368f900360de1901811262005051578283fd5b8e0160e08135620050628162004356565b6001600160a01b031686526020828101356200507e8162004356565b6001600160a01b03168188015260406200509a8482016200436c565b6001600160a01b03169088015260608381013590880152620050be8a840162004c61565b63ffffffff168a880152620050d6838a018462004e83565b838b8a0152620050ea848a01828462004ed5565b9350505060c0620050fe8185018562004e83565b9450888403828a01526200511484868362004f17565b9983019998505050949094019350506001016200502a565b505050858103602087015262005143818a62004f4a565b935050505082810360408401526200515c818662004916565b9050828103606084015262005172818562004fd6565b98975050505050505050565b6040815260008084546200519281620049b6565b8060408601526060600180841660008114620051b75760018114620051d25762005205565b60ff1985168884015283151560051b88018301955062005205565b8960005260208060002060005b86811015620051fc5781548b8201870152908401908201620051df565b8a018501975050505b505050505082810360208401526200521e8185620043b1565b95945050505050565b601f82111562000c8757600081815260208120601f850160051c81016020861015620052505750805b601f850160051c820191505b8181101562000da8578281556001016200525c565b81516001600160401b038111156200528d576200528d62004428565b620052a5816200529e8454620049b6565b8462005227565b602080601f831160018114620052dd5760008415620052c45750858301515b600019600386901b1c1916600185901b17855562000da8565b600085815260208120601f198616915b828110156200530e57888601518255948401946001909101908401620052ed565b50858210156200532d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001820162005352576200535262004970565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008262005381576200538162005359565b500490565b60008262005398576200539862005359565b500690565b808202811582820484141762000b315762000b3162004970565b6000815160408452620053ce6040850182620043b1565b602093840151949093019390935250919050565b6001600160a01b03841681526060602082018190526000906200540890830185620053b7565b9050826040830152949350505050565b6000608080830181845280885180835260a092508286019150828160051b8701016020808c0160005b84811015620054e257898403609f19018652815180516001600160a01b0390811686528482015181168587015260408083015190911690860152606080820151908601528881015163ffffffff16898601528781015160e089870181905290620054ae8288018262004aa9565b91505060c08083015192508682038188015250620054cd818362004916565b97850197955050509082019060010162005441565b505087820390880152620054f7818b62004f4a565b945050505050828103604084015262005511818662004916565b90508281036060840152620036ab818562004fd6565b600080604083850312156200553b57600080fd5b505080516020909101519092909150565b6001600160a01b03831681526040602082018190526000906200301790830184620043b1565b60018060a01b03841681528260208201526060604082015260006200521e6060830184620053b7565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe60806040526040516106cc3803806106cc83398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106a5602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b61014c806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122044bae01418f8f4d3e2aa454c2b5942f4fa2dcacad01b2d54be1f93cf2feef3dc64736f6c63430008140033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b5fd1dcc945ce9d63256ce18c0a111a0877e8deaddd9b5b92efaa5be79c1946464736f6c63430008140033
Deployed Bytecode
0x60806040523480156200001157600080fd5b50600436106200032f5760003560e01c80638da5cb5b11620001bf578063c235fb1411620000fc578063e91bb84411620000af578063edb594fc1162000086578063edb594fc1462000759578063ef13b2c71462000770578063f29768711462000797578063f2fde38b14620007a157600080fd5b8063e91bb84414620006f2578063ea4d3c9b146200072d578063eae43a44146200074257600080fd5b8063c235fb14146200066a578063c47f0027146200067f578063c6e6f5921462000696578063ce5119ee14620006ad578063d2a7666314620006c4578063d9540d6a14620006db57600080fd5b8063a8c62e761162000172578063ac579b771162000149578063ac579b77146200061b578063b3ab15fb1462000632578063b68ef5591462000649578063b9ff20c8146200065357600080fd5b8063a8c62e7614620005c0578063ab89b6af14620005d4578063ac48eb9f146200060457600080fd5b80638da5cb5b1462000528578063900cf0cf146200053a57806395a2251f146200054457806399f62bab146200055b5780639b2cb5d8146200059e578063a0ed8b9914620005a957600080fd5b806339b70e38116200028e57806366bcd641116200024157806371ca337d116200021857806371ca337d14620004e6578063841143d214620004f05780638456cb591462000507578063897b0637146200051157600080fd5b806366bcd64114620004bb5780636e553f6514620004c5578063715018a614620004dc57600080fd5b806339b70e3814620004385780633f4ba83a14620004655780634fe2bb82146200046f57806353268ad014620004865780635c60da1b14620004915780635c975abb14620004a457600080fd5b806315ca0dc011620002e757806315ca0dc014620003c85780631a8d0de214620003df578063252b7edc14620003f65780632df2228a146200040d5780633659cfe6146200041757806336f4fb02146200042e57600080fd5b8062f714ce146200033457806301e1d114146200034d57806306fdde03146200036a57806307a2d13a1462000383578063081ab7ad146200039a5780630b885ac314620003b1575b600080fd5b6200034b620003453660046200437e565b620007b8565b005b6200035762000a0b565b6040519081526020015b60405180910390f35b6200037462000a80565b604051620003619190620043f9565b62000357620003943660046200440e565b62000b17565b6200034b620003ab36600462004583565b62000b37565b6200034b620003c236600462004604565b62000c8c565b6200034b620003d93660046200440e565b62000db0565b6200034b620003f036600462004699565b62000de2565b6200034b62000407366004620046b9565b62000e83565b6101005462000357565b6200034b6200042836600462004699565b620011fe565b6200034b620012ef565b60fb546200044c906001600160a01b031681565b6040516001600160a01b03909116815260200162000361565b6200034b62001305565b6200034b620004803660046200440e565b62001319565b620003576101035481565b610131546001600160a01b03166200044c565b60335460ff16604051901515815260200162000361565b6200035760ff5481565b62000357620004d63660046200437e565b620017f6565b6200034b62001826565b620003576200183c565b6200034b620005013660046200437e565b62001930565b6200034b62001adc565b6200034b620005223660046200440e565b62001af0565b6097546001600160a01b03166200044c565b6200035760fd5481565b6200034b6200055536600462004699565b62001b3d565b620005726200056c36600462004699565b62001e74565b60408051825181526020808401516001600160a01b031690820152918101519082015260600162000361565b6200035761012e5481565b6200034b620005ba36600462004699565b62001ee7565b60fc546200044c906001600160a01b031681565b62000357620005e536600462004699565b6001600160a01b0316600090815261012f602052604090206002015490565b6200034b62000615366004620046e8565b62002096565b6200034b6200062c3660046200479c565b620023d6565b6200034b6200064336600462004699565b6200253a565b62000357620025d5565b6200034b620006643660046200440e565b62002607565b61012d546200044c906001600160a01b031681565b6200034b620006903660046200483b565b62002711565b62000357620006a73660046200440e565b6200278a565b62000357620006be36600462004699565b620027aa565b6200034b620006d53660046200479c565b62002831565b6200034b620006ec36600462004873565b620028b2565b62000709620007033660046200440e565b62002a69565b604080519384526001600160a01b0390921660208401529082015260600162000361565b610101546200044c906001600160a01b031681565b6200044c620007533660046200440e565b62002aaa565b620003576200076a366004620048db565b62002ad6565b620007876200078136600462004699565b62002b38565b6040516200036192919062004953565b6200035762002cb0565b6200034b620007b236600462004699565b62002e3d565b620007c262002eb9565b620007cc62002f01565b620007d8818362002f5c565b336000620007f984670de0b6b3a7640000620007f36200183c565b62002fce565b905061012e548110156200087a5760405162461bcd60e51b815260206004820152603a60248201527f496e63657074696f6e5661756c743a20616d6f756e74206973206c657373207460448201527f68616e20746865206d696e696d756d207769746864726177616c00000000000060648201526084015b60405180910390fd5b61012d54604051632770a7eb60e21b81526001600160a01b0384811660048301526024820187905290911690639dc29fac90604401600060405180830381600087803b158015620008ca57600080fd5b505af1158015620008df573d6000803e3d6000fd5b505050508060ff6000828254620008f7919062004986565b90915550506001600160a01b038316600090815261012f6020526040902062000920826200301f565b81600201600082825462000935919062004986565b909155505060408051606081018252610102805482526001600160a01b038716602083015291810162000968856200301f565b9052815460018082018455600093845260209384902083516003909302019182558284015190820180546001600160a01b0319166001600160a01b039283161790556040928301516002909201919091558151858152928301889052858116929087169183917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a450505062000a076001606555565b5050565b60c9546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801562000a55573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000a7b91906200499c565b905090565b610130805462000a9090620049b6565b80601f016020809104026020016040519081016040528092919081815260200182805462000abe90620049b6565b801562000b0f5780601f1062000ae35761010080835404028352916020019162000b0f565b820191906000526020600020905b81548152906001019060200180831162000af157829003601f168201915b505050505081565b600062000b3182670de0b6b3a7640000620007f36200183c565b92915050565b62000b4162002f01565b62000b4b62002eb9565b60fe546001600160a01b0316331462000b785760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b03831662000ba05760405163a22b4cd760e01b815260040160405180910390fd5b61010154604051631976849960e21b81523060048201526000916001600160a01b0316906365da126490602401602060405180830381865afa15801562000beb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c11919062004a3a565b6001600160a01b03161462000c3957604051631a30c08d60e31b815260040160405180910390fd5b62000c4683838362003035565b6040516001600160a01b0384169030907f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38790600090a362000c876001606555565b505050565b600054610100900460ff161580801562000cad5750600054600160ff909116105b8062000cc95750303b15801562000cc9575060005460ff166001145b62000d2e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000871565b6000805460ff19166001179055801562000d52576000805461ff0019166101001790555b62000d618686868686620030a5565b801562000da8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60fe546001600160a01b0316331462000ddd5760405162461bcd60e51b81526004016200087190620049f2565b60fd55565b62000dec62003104565b610101546001600160a01b03161562000e1857604051634fa0a5d560e11b815260040160405180910390fd5b61010154604080516001600160a01b03928316815291831660208301527fbae75576f1af1fe832366c069d0608003eb7aad2dcc476a5158f70b2b67d3d8b910160405180910390a161010180546001600160a01b0319166001600160a01b0392909216919091179055565b62000e8d62002eb9565b62000e9762002f01565b60fe546001600160a01b0316331462000ec45760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b0380831660009081526101046020526040902054168062000eff576040516325ec6c1f60e01b815260040160405180910390fd5b6612344fffffffff196001600160a01b0382160162000f315760405163a22b4cd760e01b815260040160405180910390fd5b6101015460405163285e212160e21b81526001600160a01b038381166004830152600092169063a178848490602401602060405180830381865afa15801562000f7e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fa491906200499c565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa15801562000fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200102591906200499c565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa15801562001075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200109b91906200499c565b9050620010aa81600562004986565b821015620010b55750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa158015620010ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200112591906200499c565b60fc546040519196506001600160a01b03808716927fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec520829262001171921690859043908c908a9062004a5a565b60405180910390a28461010060008282546200118e919062004986565b909155505060405163b64d26ab60e01b8152600481018290526001600160a01b0385169063b64d26ab90602401600060405180830381600087803b158015620011d657600080fd5b505af1158015620011eb573d6000803e3d6000fd5b505050505050505062000a076001606555565b6200120862002eb9565b6200121262003104565b6001600160a01b0381163b620012845760405162461bcd60e51b815260206004820152603060248201527f496e63657074696f6e5661756c743a20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b606482015260840162000871565b61013154604080516001600160a01b03928316815291831660208301527f1a5ca99a64512489fd9455e8da426740174107a69292fca0a8b80b08f6f67892910160405180910390a161013180546001600160a01b0319166001600160a01b0392909216919091179055565b620012f962002eb9565b6200130362003160565b565b6200130f62003104565b62001303620031ec565b6200132362002eb9565b6200132d62002f01565b60fe546001600160a01b031633146200135a5760405162461bcd60e51b81526004016200087190620049f2565b6101015460405163285e212160e21b81523060048201819052916000916001600160a01b039091169063a178848490602401602060405180830381865afa158015620013aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013d091906200499c565b60fb5460fc54604051633d3f06c960e11b81526001600160a01b0386811660048301529182166024820152929350600092911690637a7e0d9290604401602060405180830381865afa1580156200142b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200145191906200499c565b60fc546040516338f6b94760e21b8152600481018790529192506000916001600160a01b039091169063e3dae51c90602401602060405180830381865afa158015620014a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014c791906200499c565b9050620014d681600562004986565b821015620014e15750805b60fc54604051637a8b263760e01b8152600481018390526001600160a01b0390911690637a8b263790602401602060405180830381865afa1580156200152b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200155191906200499c565b60408051600180825281830190925291965060009190602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060fc5482519293506001600160a01b031691839150600090620015bd57620015bd62004a93565b60200260200101906001600160a01b031690816001600160a01b0316815250508282600081518110620015f457620015f462004a93565b6020908102919091010152604080516001808252818301909252600091816020015b60408051606080820183528082526020820152600091810191909152815260200190600190039081620016165790505090506040518060600160405280838152602001848152602001306001600160a01b03168152508160008151811062001682576200168262004a93565b6020026020010181905250876101006000828254620016a2919062004986565b9091555050610101546040516306ec6e8160e11b81526001600160a01b0390911690630dd8dd0290620016da90849060040162004ae4565b6000604051808303816000875af1158015620016fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001724919081019062004b84565b5060fc5461010154604051631976849960e21b81526001600160a01b038a811660048301819052937fdbee882832247c009fcded16f057a75cfd42a40de981aae8f96c49496ec5208293908216928992439216906365da126490602401602060405180830381865afa1580156200179f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c5919062004a3a565b8b604051620017d995949392919062004a5a565b60405180910390a250505050505050620017f36001606555565b50565b60006200180262002f01565b6200180c62002eb9565b6200181983338462003240565b905062000b316001606555565b6200183062003104565b6200130360006200337c565b60008062001849620025d5565b9050600061012d60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c891906200499c565b9050600060ff548310620018eb5760ff54620018e5908462004c12565b620018ee565b60005b9050801580620018fc575081155b156200191357670de0b6b3a7640000935050505090565b6200192882670de0b6b3a764000083620033ce565b935050505090565b60fe546001600160a01b031633146200195d5760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b038116620019855760405163a22b4cd760e01b815260040160405180910390fd5b60005b6101055481101562001abd57816001600160a01b03166101058281548110620019b557620019b562004a93565b6000918252602090912001546001600160a01b031614801562001a7b57506101015461010580546001600160a01b0390921691633e28391d91908490811062001a025762001a0262004a93565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562001a53573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a79919062004c28565b155b1562001ab45766123450000000006001600160a01b0316610105828154811062001aa95762001aa962004a93565b506000525062001abd565b60010162001988565b5081610100600082825462001ad3919062004986565b90915550505050565b62001ae662003104565b6200130362003452565b62001afa62003104565b61012e5460408051918252602082018390527f633c1a71f1236c727d460906a677e5c96556b3f5ad34c9b64072540f1c2eddea910160405180910390a161012e55565b62001b4762002eb9565b62001b5162002f01565b60008062001b5f8362002b38565b915091508162001bc45760405162461bcd60e51b815260206004820152602960248201527f496e63657074696f6e5661756c743a2072656465656d2063616e206e6f74206260448201526819481c1c9bd8d9595960ba1b606482015260840162000871565b80516000816001600160401b0381111562001be35762001be362004428565b60405190808252806020026020018201604052801562001c0d578160200160208202803683370190505b506001600160a01b038616600090815261012f60205260408120919250805b8481101562001daf57600086828151811062001c4c5762001c4c62004a93565b602002602001015190506000610102828154811062001c6f5762001c6f62004a93565b600091825260208083206040805160608101825260039094029091018054845260018101546001600160a01b03169284019290925260029182015490830181905290880180549294509092839262001cc990849062004c12565b9091555062001cda90508162003492565b60ff600082825462001ced919062004c12565b9250508190555080610103600082825462001d09919062004c12565b9091555062001d1b9050818662004986565b94508287858151811062001d335762001d3362004a93565b60200260200101818152505061010289858151811062001d575762001d5762004a93565b60200260200101518154811062001d725762001d7262004a93565b600091825260208220600390910201818155600180820180546001600160a01b031916905560029091019190915593909301925062001c2c915050565b508462001dbe60018662004c12565b8151811062001dd15762001dd162004a93565b6020908102919091010151825562001dea8782620034a1565b7fd4e9104c456539f8bc402dcb01d19f8d74a18e45395a5b518feb89fbbda5961c8360405162001e1b919062004c4c565b60405180910390a16040518181526001600160a01b0388169033907fd12200efa34901b99367694174c3b0d32c99585fdf37c7c26892136ddd0836d99060200160405180910390a3505050505050620017f36001606555565b62001ea260405180606001604052806000815260200160006001600160a01b03168152602001600081525090565b506001600160a01b03908116600090815261012f6020908152604091829020825160608101845281548152600182015490941691840191909152600201549082015290565b62001ef162003104565b610101546040516336b87bd760e11b81526001600160a01b03838116600483015290911690636d70f7ae90602401602060405180830381865afa15801562001f3d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001f63919062004c28565b62001fc25760405162461bcd60e51b815260206004820152602860248201527f496e63657074696f6e5661756c743a206974206973206e6f7420616e20454c2060448201526737b832b930ba37b960c11b606482015260840162000871565b6001600160a01b038181166000908152610104602052604090205416156200203d5760405162461bcd60e51b815260206004820152602760248201527f496e63657074696f6e5661756c743a206f70657261746f7220616c72656164796044820152662065786973747360c81b606482015260840162000871565b6001600160a01b0381166000818152610104602052604080822080546001600160a01b0319166612345000000000179055517f3b2e539a214fa1a91dca8c6e5c54b67f6429ae3142a56bd7e07bd1a1955706b69190a250565b620020a062002eb9565b620020aa62002f01565b806000816001600160401b03811115620020c857620020c862004428565b604051908082528060200260200182016040528015620020fd57816020015b6060815260200190600190039081620020e75790505b5090506000826001600160401b038111156200211d576200211d62004428565b60405190808252806020026020018201604052801562002147578160200160208202803683370190505b5090506000836001600160401b0381111562002167576200216762004428565b60405190808252806020026020018201604052801562002191578160200160208202803683370190505b50905060005b848110156200227157604080516001808252818301909252906020808301908036833701905050848281518110620021d357620021d362004a93565b602090810291909101015260c95484516001600160a01b039091169085908390811062002204576200220462004a93565b602002602001015160008151811062002221576200222162004a93565b60200260200101906001600160a01b031690816001600160a01b031681525050600182828151811062002258576200225862004a93565b9115156020928302919091019091015260010162002197565b506000306001600160a01b03891603620022a6576200229e62002295878962004d50565b85858562003549565b90506200234e565b620022b188620036b6565b620022cf5760405163563fb6d760e11b815260040160405180910390fd5b604051631de1b03360e01b81526001600160a01b03891690631de1b0339062002305908a908a908990899089906004016200500a565b6020604051808303816000875af115801562002325573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200234b91906200499c565b90505b6040518181527f8772d6f79a1845a0c0e90ef18d99f91242bbc0ba98c9ca780feaad42b81f02ba9060200160405180910390a1806101005410620023a35780610100546200239d919062004c12565b620023a6565b60005b61010081905560071115620023bc576000610100555b620023c662003160565b505050505062000c876001606555565b60fe546001600160a01b03163314620024035760405162461bcd60e51b81526004016200087190620049f2565b805160005b8181101562000c8757600083828151811062002428576200242862004a93565b6020908102919091018101516001600160a01b038116600090815261012f909252604082206002810154919350918190036200246d5783600101935050505062002408565b6000918290556040805160608101825261010280548083526001600160a01b0396871660208401908152938301948552600180820183559190955290517f93bdaa6a4190909b7c3fbe8d42169ffe1cab19f51dfc8db24c71abf849eced4a60039095029485015590517f93bdaa6a4190909b7c3fbe8d42169ffe1cab19f51dfc8db24c71abf849eced4b840180546001600160a01b0319169190951617909355517f93bdaa6a4190909b7c3fbe8d42169ffe1cab19f51dfc8db24c71abf849eced4c909101550162002408565b6200254462003104565b6001600160a01b0381166200256c5760405163a22b4cd760e01b815260040160405180910390fd5b60fe54604080516001600160a01b03928316815291831660208301527fd58299b712891143e76310d5e664c4203c940a67db37cf856bdaa3c5c76a802c910160405180910390a160fe80546001600160a01b0319166001600160a01b0392909216919091179055565b600061010054620025e562000a0b565b620025ef62002cb0565b620025fb919062004986565b62000a7b919062004986565b6200261162002f01565b60fe546001600160a01b031633146200263e5760405162461bcd60e51b81526004016200087190620049f2565b62002649816200371c565b60fb5460fc5460c9546040516373d0285560e11b81526001600160a01b03928316600482015290821660248201526044810184905291169063e7a050aa906064016020604051808303816000875af1158015620026aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026d091906200499c565b5060405181815230907f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b79060200160405180910390a2620017f36001606555565b6200271b62003104565b80516000036200273e5760405163a22b4cd760e01b815260040160405180910390fd5b7f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a61013082604051620027739291906200517e565b60405180910390a161013062000a07828262005271565b600062000b31826200279b6200183c565b670de0b6b3a764000062002fce565b60fc546001600160a01b0382811660009081526101046020526040808220549051630aa794bf60e31b815290831660048201529092919091169063553ca5f890602401602060405180830381865afa1580156200280b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3191906200499c565b60fe546001600160a01b031633146200285e5760405162461bcd60e51b81526004016200087190620049f2565b805160005b8181101562000c8757600083828151811062002883576200288362004a93565b6020908102919091018101516001600160a01b0316600090815261012f90915260408120555060010162002863565b620028bc62002f01565b620028c662002eb9565b60fe546001600160a01b03163314620028f35760405162461bcd60e51b81526004016200087190620049f2565b6001600160a01b0383166200291b5760405163a22b4cd760e01b815260040160405180910390fd5b62002926846200371c565b6001600160a01b0380841660009081526101046020526040902054168062002961576040516325ec6c1f60e01b815260040160405180910390fd5b60006612344fffffffff196001600160a01b03831601620029f55750600162002989620038b9565b6001600160a01b0380871660009081526101046020526040812080549284166001600160a01b03199384168117909155610105805460018101825592527ffc62abc8c0fc47c2d92f5aec99bf8b60f375828e14394d89345cae11a9867371909101805490921617905591505b62002a01828762003a4c565b801562002a165762002a168286868662003b6b565b846001600160a01b0316826001600160a01b03167f9e4280ca07e73dad7462e494990e9f45ffb8990d79423e65b536d2d7a11fa38760405160405180910390a3505062002a636001606555565b50505050565b610102818154811062002a7b57600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b039091169083565b610105818154811062002abc57600080fd5b6000918252602090912001546001600160a01b0316905081565b600062002ae262002f01565b62002aec62002eb9565b60405182907f3c16de186f1ef5ecb8049424d69d8038355dfdd932e194e95067b0dadd05259890600090a262002b2484338562003240565b905062002b316001606555565b9392505050565b6001600160a01b03808216600090815261012f6020908152604080832081516060818101845282548083526001840154909716948201949094526002909101549181019190915260fd5492939192849290839062002b9890839062004c12565b6001600160401b0381111562002bb25762002bb262004428565b60405190808252806020026020018201604052801562002bdc578160200160208202803683370190505b509050826040015160000362002bfa57600097909650945050505050565b60005b60fd5481101562002c8857876001600160a01b0316610102828154811062002c295762002c2962004a93565b60009182526020909120600160039092020101546001600160a01b03160362002c7f57600196508082868151811062002c665762002c6662004a93565b602090810291909101015262002c7c856200533d565b94505b60010162002bfd565b50600084825162002c9a919062004c12565b111562002ca5578381525b949694955050505050565b61010554600090815b8181101562002dbb5760006001600160a01b0316610105828154811062002ce45762002ce462004a93565b6000918252602090912001546001600160a01b03161462002cb95760fc5461010580546001600160a01b039092169163553ca5f891908490811062002d2d5762002d2d62004a93565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562002d7e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002da491906200499c565b62002db0908462004986565b925060010162002cb9565b5060fc54604051630aa794bf60e31b81523060048201526001600160a01b039091169063553ca5f890602401602060405180830381865afa15801562002e05573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002e2b91906200499c565b62002e37908362004986565b91505090565b62002e4762003104565b6001600160a01b03811662002eae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000871565b620017f3816200337c565b60335460ff1615620013035760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000871565b60026065540362002f555760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000871565b6002606555565b8060000362002f7e5760405163a22b4cd760e01b815260040160405180910390fd5b6001600160a01b03821662002fa65760405163a22b4cd760e01b815260040160405180910390fd5b62002fb062003bd7565b62000a0757604051638e201a8b60e01b815260040160405180910390fd5b60006200301762002feb62002fe484876200536f565b8562003de7565b838562002ff9828962005386565b6200300591906200539d565b6200301191906200536f565b62003e24565b949350505050565b600062000b3160018362004c12565b6001606555565b6101015460405163eea9064b60e01b81526001600160a01b039091169063eea9064b906200306c90869085908790600401620053e2565b600060405180830381600087803b1580156200308757600080fd5b505af11580156200309c573d6000803e3d6000fd5b50505050505050565b620030af62003e3e565b620030bb838262003e72565b610130620030ca868262005271565b505060fe80546001600160a01b039485166001600160a01b03199182161790915561012d8054929094169116179091555050606461012e55565b6097546001600160a01b03163314620013035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000871565b61010254610103546000906200317562000a0b565b62003181919062004c12565b60fd549091505b8281101562000c875760006101028281548110620031aa57620031aa62004a93565b906000526020600020906003020160020154905082811115620031cd5750505050565b61010380548201905560fd805460019081019091559203910162003188565b620031f66200400c565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000806200324d6200183c565b90506200325b838662004057565b60006200326762000a0b565b9050620032758587620040eb565b806200328062000a0b565b6200328c919062004c12565b95506000620032a58784670de0b6b3a764000062002fce565b61012d546040516340c10f1960e01b81526001600160a01b038881166004830152602482018490529293509116906340c10f1990604401600060405180830381600087803b158015620032f757600080fd5b505af11580156200330c573d6000803e3d6000fd5b505050506200331b8162004199565b846001600160a01b0316866001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d789846040516200336a929190918252602082015260400190565b60405180910390a39695505050505050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000816000036200340b5760405162461bcd60e51b8152602060048201526006602482015265063203d3d20360d41b604482015260640162000871565b620030176200341f62002fe484876200536f565b836200342d60018262004c12565b866200343a878a62005386565b6200344691906200539d565b62003005919062004986565b6200345c62002eb9565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620032233390565b600062000b3182600162004986565b60c95460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303816000875af1158015620034f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200351b919062004c28565b62000a075760c954604051631fca53a760e11b81526001600160a01b03909116600482015260240162000871565b60c9546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003597573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620035bd91906200499c565b610101546040516319a021cb60e11b81529192506001600160a01b031690633340439690620035f790899089908990899060040162005418565b600060405180830381600087803b1580156200361257600080fd5b505af115801562003627573d6000803e3d6000fd5b505060c9546040516370a0823160e01b8152306004820152600093508492506001600160a01b03909116906370a0823190602401602060405180830381865afa15801562003679573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200369f91906200499c565b620036ab919062004c12565b979650505050505050565b61010554600090815b8181101562003712576101058181548110620036df57620036df62004a93565b6000918252602090912001546001600160a01b039081169085160362003709575060019392505050565b600101620036bf565b5060009392505050565b610103546200372a62000a0b565b62003736919062004c12565b81111562003765576200374862000a0b565b604051636688dd2d60e11b81526004016200087191815260200190565b60fc546040805163df6fadc160e01b8152815160009384936001600160a01b039091169263df6fadc192600480830193928290030181865afa158015620037b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620037d6919062005527565b91509150818311156200380757604051633c690bcb60e11b8152600481018390526024810184905260440162000871565b60c95460fc546040516370a0823160e01b81526001600160a01b03918216600482015260009291909116906370a0823190602401602060405180830381865afa15801562003859573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200387f91906200499c565b9050816200388e858362004986565b111562002a6357604051630dbbc86f60e11b8152600481018390526024810182905260440162000871565b610131546000906001600160a01b0316620038e7576040516340dde93560e01b815260040160405180910390fd5b6101015460fb5460fc5460fe546040516001600160a01b0394851660248201529284166044840152908316606483015291909116608482015260009060a40160408051601f198184030181529181526020820180516001600160e01b0316637c643b2f60e11b1790525190915060009030908390620039669062004348565b620039739291906200554c565b604051809103906000f08015801562003990573d6000803e3d6000fd5b509050806001600160a01b03811663f2fde38b620039b66097546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015620039f857600080fd5b505af115801562003a0d573d6000803e3d6000fd5b50506040516001600160a01b03851692507f9e676714ad2ee7d362cccabb3a543102aada709f27c2bda6bf6ef42fce70ff259150600090a25092915050565b60c95460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af115801562003aa0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003ac6919062004c28565b50604051635466590560e01b8152600481018290526001600160a01b03831690635466590590602401600060405180830381600087803b15801562003b0a57600080fd5b505af115801562003b1f573d6000803e3d6000fd5b50505050816001600160a01b03167f890a6c1c3db8b3fa62f2928d2c9851b5c456f019d09d93f72d984454511b87b78260405162003b5f91815260200190565b60405180910390a25050565b60405163511e274f60e01b81526001600160a01b0385169063511e274f9062003b9d9086908690869060040162005572565b600060405180830381600087803b15801562003bb857600080fd5b505af115801562003bcd573d6000803e3d6000fd5b5050505050505050565b6000805b6101055481101562003ce95760006001600160a01b0316610105828154811062003c095762003c0962004a93565b6000918252602090912001546001600160a01b03160362003c2d5760010162003bdb565b6101015461010580546001600160a01b0390921691633e28391d91908490811062003c5c5762003c5c62004a93565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa15801562003cad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003cd3919062004c28565b62003ce057600091505090565b60010162003bdb565b5060fc54604051630aa794bf60e31b81523060048201526000916001600160a01b03169063553ca5f890602401602060405180830381865afa15801562003d34573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003d5a91906200499c565b11801562003dd5575061010154604051633e28391d60e01b81523060048201526001600160a01b0390911690633e28391d90602401602060405180830381865afa15801562003dad573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003dd3919062004c28565b155b1562003de15750600090565b50600190565b60008260000362003dfb5750600062000b31565b8282028284828162003e115762003e1162005359565b041462002b315760001991505062000b31565b60008282018381101562002b315760001991505062000b31565b600054610100900460ff1662003e685760405162461bcd60e51b815260040162000871906200559b565b62001303620041eb565b600054610100900460ff1662003e9c5760405162461bcd60e51b815260040162000871906200559b565b60fb80546001600160a01b038085166001600160a01b03199283161790925560fc8054928416929091168217905560408051632495a59960e01b8152905162003f379291632495a5999160048083019260209291908290030181865afa15801562003f0b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003f31919062004a3a565b62004220565b60c95460fb5460405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af115801562003f8e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062003fb4919062004c28565b62000a075760405162461bcd60e51b815260206004820152602160248201527f456967656e4c6179657248616e646c65723a20617070726f7665206661696c656044820152601960fa1b606482015260840162000871565b60335460ff16620013035760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640162000871565b6001600160a01b0382166200407f5760405163a22b4cd760e01b815260040160405180910390fd5b61012e5481101562002fa65760405162461bcd60e51b815260206004820152602e60248201527f496e63657074696f6e5661756c743a206465706f7369746564206c657373207460448201526d1a185b881b5a5b88185b5bdd5b9d60921b606482015260840162000871565b60c9546040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201849052909116906323b872dd906064016020604051808303816000875af115801562004145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200416b919062004c28565b62000a075760c9546040516302ce902360e61b81526001600160a01b03909116600482015260240162000871565b60008111620017f35760405162461bcd60e51b815260206004820181905260248201527f496e63657074696f6e5661756c743a20726573756c7420695368617265732030604482015260640162000871565b600054610100900460ff16620042155760405162461bcd60e51b815260040162000871906200559b565b62001303336200337c565b600054610100900460ff166200424a5760405162461bcd60e51b815260040162000871906200559b565b6200425462004280565b6200425e620042b4565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16620042aa5760405162461bcd60e51b815260040162000871906200559b565b62001303620042e8565b600054610100900460ff16620042de5760405162461bcd60e51b815260040162000871906200559b565b620013036200431e565b600054610100900460ff16620043125760405162461bcd60e51b815260040162000871906200559b565b6033805460ff19169055565b600054610100900460ff166200302e5760405162461bcd60e51b815260040162000871906200559b565b6106cc80620055e783390190565b6001600160a01b0381168114620017f357600080fd5b8035620043798162004356565b919050565b600080604083850312156200439257600080fd5b823591506020830135620043a68162004356565b809150509250929050565b6000815180845260005b81811015620043d957602081850181015186830182015201620043bb565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600062002b316020830184620043b1565b6000602082840312156200442157600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171562004463576200446362004428565b60405290565b604051601f8201601f191681016001600160401b038111828210171562004494576200449462004428565b604052919050565b60006001600160401b03831115620044b857620044b862004428565b620044cd601f8401601f191660200162004469565b9050828152838383011115620044e257600080fd5b828260208301376000602084830101529392505050565b6000604082840312156200450c57600080fd5b604051604081016001600160401b03828210818311171562004532576200453262004428565b8160405282935084359150808211156200454b57600080fd5b508301601f810185136200455e57600080fd5b6200456f858235602084016200449c565b825250602083013560208201525092915050565b6000806000606084860312156200459957600080fd5b8335620045a68162004356565b92506020840135915060408401356001600160401b03811115620045c957600080fd5b620045d786828701620044f9565b9150509250925092565b600082601f830112620045f357600080fd5b62002b31838335602085016200449c565b600080600080600060a086880312156200461d57600080fd5b85356001600160401b038111156200463457600080fd5b6200464288828901620045e1565b9550506020860135620046558162004356565b93506040860135620046678162004356565b92506060860135620046798162004356565b915060808601356200468b8162004356565b809150509295509295909350565b600060208284031215620046ac57600080fd5b813562002b318162004356565b60008060408385031215620046cd57600080fd5b8235620046da8162004356565b946020939093013593505050565b600080600060408486031215620046fe57600080fd5b83356200470b8162004356565b925060208401356001600160401b03808211156200472857600080fd5b818601915086601f8301126200473d57600080fd5b8135818111156200474d57600080fd5b8760208260051b85010111156200476357600080fd5b6020830194508093505050509250925092565b60006001600160401b0382111562004792576200479262004428565b5060051b60200190565b60006020808385031215620047b057600080fd5b82356001600160401b03811115620047c757600080fd5b8301601f81018513620047d957600080fd5b8035620047f0620047ea8262004776565b62004469565b81815260059190911b820183019083810190878311156200481057600080fd5b928401925b82841015620036ab5783356200482b8162004356565b8252928401929084019062004815565b6000602082840312156200484e57600080fd5b81356001600160401b038111156200486557600080fd5b6200301784828501620045e1565b600080600080608085870312156200488a57600080fd5b8435935060208501356200489e8162004356565b92506040850135915060608501356001600160401b03811115620048c157600080fd5b620048cf87828801620044f9565b91505092959194509250565b600080600060608486031215620048f157600080fd5b833592506020840135620049058162004356565b929592945050506040919091013590565b600081518084526020808501945080840160005b8381101562004948578151875295820195908201906001016200492a565b509495945050505050565b821515815260406020820152600062003017604083018462004916565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000b315762000b3162004970565b600060208284031215620049af57600080fd5b5051919050565b600181811c90821680620049cb57607f821691505b602082108103620049ec57634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526028908201527f456967656e4c6179657248616e646c65723a206f6e6c79206f70657261746f7260408201526708185b1b1bddd95960c21b606082015260800190565b60006020828403121562004a4d57600080fd5b815162002b318162004356565b6001600160a01b039586168152602081019490945263ffffffff9290921660408401529092166060820152608081019190915260a00190565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015620049485781516001600160a01b03168752958201959082019060010162004abd565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101562004b7657603f1989840301855281516060815181865262004b348287018262004aa9565b915050888201518582038a87015262004b4e828262004916565b928901516001600160a01b031695890195909552509487019492509086019060010162004b0b565b509098975050505050505050565b6000602080838503121562004b9857600080fd5b82516001600160401b0381111562004baf57600080fd5b8301601f8101851362004bc157600080fd5b805162004bd2620047ea8262004776565b81815260059190911b8201830190838101908783111562004bf257600080fd5b928401925b82841015620036ab5783518252928401929084019062004bf7565b8181038181111562000b315762000b3162004970565b60006020828403121562004c3b57600080fd5b8151801515811462002b3157600080fd5b60208152600062002b31602083018462004916565b803563ffffffff811681146200437957600080fd5b600082601f83011262004c8857600080fd5b8135602062004c9b620047ea8362004776565b82815260059290921b8401810191818101908684111562004cbb57600080fd5b8286015b8481101562004ce357803562004cd58162004356565b835291830191830162004cbf565b509695505050505050565b600082601f83011262004d0057600080fd5b8135602062004d13620047ea8362004776565b82815260059290921b8401810191818101908684111562004d3357600080fd5b8286015b8481101562004ce3578035835291830191830162004d37565b600062004d61620047ea8462004776565b80848252602080830192508560051b85013681111562004d8057600080fd5b855b8181101562004e775780356001600160401b038082111562004da45760008081fd5b818901915060e0823603121562004dbb5760008081fd5b62004dc56200443e565b62004dd0836200436c565b815262004ddf8684016200436c565b86820152604062004df28185016200436c565b9082015260608381013590820152608062004e0f81850162004c61565b9082015260a0838101358381111562004e285760008081fd5b62004e363682870162004c76565b82840152505060c0808401358381111562004e515760008081fd5b62004e5f3682870162004cee565b91830191909152508752505093820193820162004d82565b50919695505050505050565b6000808335601e1984360301811262004e9b57600080fd5b83016020810192503590506001600160401b0381111562004ebb57600080fd5b8060051b360382131562004ece57600080fd5b9250929050565b8183526000602080850194508260005b858110156200494857813562004efb8162004356565b6001600160a01b03168752958201959082019060010162004ee5565b81835260006001600160fb1b0383111562004f3157600080fd5b8260051b80836020870137939093016020019392505050565b600082825180855260208086019550808260051b8401018186016000805b8581101562004fc857868403601f19018a52825180518086529086019086860190845b8181101562004fb25783516001600160a01b03168352928801929188019160010162004f8b565b50509a86019a9450509184019160010162004f68565b509198975050505050505050565b600081518084526020808501945080840160005b838110156200494857815115158752958201959082019060010162004fea565b608080825281810186905260009060a0808401600589901b850182018a85805b8c8110156200512c57888403609f190185528235368f900360de1901811262005051578283fd5b8e0160e08135620050628162004356565b6001600160a01b031686526020828101356200507e8162004356565b6001600160a01b03168188015260406200509a8482016200436c565b6001600160a01b03169088015260608381013590880152620050be8a840162004c61565b63ffffffff168a880152620050d6838a018462004e83565b838b8a0152620050ea848a01828462004ed5565b9350505060c0620050fe8185018562004e83565b9450888403828a01526200511484868362004f17565b9983019998505050949094019350506001016200502a565b505050858103602087015262005143818a62004f4a565b935050505082810360408401526200515c818662004916565b9050828103606084015262005172818562004fd6565b98975050505050505050565b6040815260008084546200519281620049b6565b8060408601526060600180841660008114620051b75760018114620051d25762005205565b60ff1985168884015283151560051b88018301955062005205565b8960005260208060002060005b86811015620051fc5781548b8201870152908401908201620051df565b8a018501975050505b505050505082810360208401526200521e8185620043b1565b95945050505050565b601f82111562000c8757600081815260208120601f850160051c81016020861015620052505750805b601f850160051c820191505b8181101562000da8578281556001016200525c565b81516001600160401b038111156200528d576200528d62004428565b620052a5816200529e8454620049b6565b8462005227565b602080601f831160018114620052dd5760008415620052c45750858301515b600019600386901b1c1916600185901b17855562000da8565b600085815260208120601f198616915b828110156200530e57888601518255948401946001909101908401620052ed565b50858210156200532d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001820162005352576200535262004970565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008262005381576200538162005359565b500490565b60008262005398576200539862005359565b500690565b808202811582820484141762000b315762000b3162004970565b6000815160408452620053ce6040850182620043b1565b602093840151949093019390935250919050565b6001600160a01b03841681526060602082018190526000906200540890830185620053b7565b9050826040830152949350505050565b6000608080830181845280885180835260a092508286019150828160051b8701016020808c0160005b84811015620054e257898403609f19018652815180516001600160a01b0390811686528482015181168587015260408083015190911690860152606080820151908601528881015163ffffffff16898601528781015160e089870181905290620054ae8288018262004aa9565b91505060c08083015192508682038188015250620054cd818362004916565b97850197955050509082019060010162005441565b505087820390880152620054f7818b62004f4a565b945050505050828103604084015262005511818662004916565b90508281036060840152620036ab818562004fd6565b600080604083850312156200553b57600080fd5b505080516020909101519092909150565b6001600160a01b03831681526040602082018190526000906200301790830184620043b1565b60018060a01b03841681528260208201526060604082015260006200521e6060830184620053b7565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe60806040526040516106cc3803806106cc83398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106a5602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b61014c806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122044bae01418f8f4d3e2aa454c2b5942f4fa2dcacad01b2d54be1f93cf2feef3dc64736f6c63430008140033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b5fd1dcc945ce9d63256ce18c0a111a0877e8deaddd9b5b92efaa5be79c1946464736f6c63430008140033
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.