Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
InceptionVault_EL
Compiler Version
v0.8.24+commit.e11b9ed9
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.24; import "./InceptionVaultStorage_EL.sol"; /** * @title The InceptionVault_EL contract * @author The InceptionLRT team * @notice Aims to maximize the profit of EigenLayer for a certain asset. */ contract InceptionVault_EL is InceptionVaultStorage_EL { /// @custom:oz-upgrades-unsafe-allow constructor constructor() payable { _disableInitializers(); } function initialize( string memory vaultName, address operatorAddress, IStrategyManager _strategyManager, IInceptionToken _inceptionToken, IStrategy _assetStrategy ) external initializer { __InceptionVault_init( vaultName, operatorAddress, _strategyManager, _inceptionToken, _assetStrategy ); } function __InceptionVault_init( string memory vaultName, address operatorAddress, IStrategyManager _strategyManager, IInceptionToken _inceptionToken, IStrategy _assetStrategy ) internal { __EigenLayerHandler_init(_strategyManager, _assetStrategy); name = vaultName; _operator = operatorAddress; inceptionToken = _inceptionToken; minAmount = 100; protocolFee = 50 * 1e8; /// @dev deposit bonus depositUtilizationKink = 25 * 1e8; maxBonusRate = 15 * 1e7; optimalBonusRate = 25 * 1e6; /// @dev withdrawal fee withdrawUtilizationKink = 25 * 1e8; maxFlashFeeRate = 30 * 1e7; optimalWithdrawalRate = 5 * 1e7; treasury = msg.sender; /// rewards logic rewardsTimeline = 7 days; } function __EigenLayerHandler_init( IStrategyManager _strategyManager, IStrategy _assetStrategy ) internal onlyInitializing { strategyManager = _strategyManager; strategy = _assetStrategy; __InceptionVaultStorage_EL_init(_assetStrategy.underlyingToken()); // approve spending by strategyManager if (!_asset.approve(address(strategyManager), type(uint256).max)) revert ApproveError(); } /*////////////////////////// ////// SET functions ////// ////////////////////////*/ fallback() external { (address target, FuncAccess access) = _getSelectorToTarget(msg.sig); if (target == address(0)) revert FunctionNotSupported(); _verifyAccess(access); assembly { // copy function selector and any arguments calldatacopy(0, 0, calldatasize()) // execute function call using the facet let result := delegatecall(gas(), target, 0, calldatasize(), 0, 0) // get any return value returndatacopy(0, 0, returndatasize()) // return any return value or error back to the caller switch result case 0 { revert(0, returndatasize()) } default { // If the call succeeded, return the data to the caller return(0, returndatasize()) } } } /*/////////////////////////////// ////// Pausable functions ////// /////////////////////////////*/ function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }
// 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; interface IInceptionRatioFeed { function getRatioFor(address) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; 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; interface IInceptionVaultErrors { error ExceededMaxMint(address receiver, uint256 shares, uint256 maxShares); error MsgSenderIsNotOwner(); error FunctionNotSupported(); error TransferAssetFailed(address assetAddress); error TransferAssetFromFailed(address assetAddress); error InsufficientCapacity(uint256 capacity); error InvalidTargetFlashCapacity(); error InceptionOnPause(); error InconsistentData(); error ApproveError(); error NullParams(); error ParameterExceedsLimits(uint256 param); error NotContract(); error DepositInconsistentResultedState(); error OperatorNotRegistered(); error RestakerNotRegistered(); error ImplementationNotSet(); error OnlyOperatorAllowed(); error AlreadyDelegated(); error DelegationManagerImmutable(); error IsNotAbleToRedeem(); error LowerMinAmount(uint256 minAmount); error ZeroFlashWithdrawFee(); /// TVL errors error ExceedsMaxPerDeposit(uint256 max, uint256 amount); error ExceedsMaxTotalDeposited(uint256 max, uint256 amount); /// EigenLayer Operators error NotEigenLayerOperator(); error EigenLayerOperatorAlreadyExists(); error TimelineNotOver(); }
// 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; 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 "@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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {IDelegationManager, IStrategy, IERC20} from "./eigen-core/IDelegationManager.sol"; interface IInceptionEigenRestakerErrors { error OnlyTrusteeAllowed(); error InconsistentData(); error WrongClaimWithdrawalParams(); error NullParams(); } interface IInceptionEigenRestaker { 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 ); event RewardCoordinatorChanged( address indexed prevValue, address indexed newValue ); 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); function setRewardsCoordinator(address newRewardCoordinator) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {IStrategyManager, IStrategy} from "./eigen-core/IStrategyManager.sol"; import {IInceptionToken} from "../common/IInceptionToken.sol"; interface IInceptionVault_EL { /*///////////////////////////////////////////////////////////////////// ///////////////////////////// Structures ///////////////////////////// ///////////////////////////////////////////////////////////////////*/ enum FuncTarget { SETTER_FACET, EIGEN_LAYER_FACET, ERC4626_FACET } enum FuncAccess { EVERYONE, ONLY_OPERATOR, ONLY_OWNER } struct FuncData { FuncTarget facet; FuncAccess access; } /** * @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; } /*///////////////////////////////////////////////////////////////////// /////////////////////////////// Events /////////////////////////////// ///////////////////////////////////////////////////////////////////*/ 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, uint256 amount ); event WithdrawalClaimed(uint256 totalAmount); event DelegationManagerChanged(address prevValue, address newValue); event TargetCapacityChanged(uint256 prevValue, uint256 newValue); 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 FlashWithdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 amount, uint256 iShares, uint256 fee ); event Redeem( address indexed sender, address indexed receiver, uint256 amount ); event WithdrawalFee(uint256 fee); event RedeemedRequests(uint256[] withdrawals); event OperatorChanged(address prevValue, address newValue); event MinAmountChanged(uint256 prevValue, uint256 newValue); event ELOperatorAdded(address indexed newELOperator); event RestakerDeployed(address indexed restaker); event ImplementationUpgraded(address prevValue, address newValue); event RatioFeedChanged(address prevValue, address newValue); event NameChanged(string prevValue, string newValue); event TreasuryChanged(address prevValue, address newValue); event ReferralCode(bytes32 indexed code); event DepositBonus(uint256 amount); event DepositBonusParamsChanged( uint256 newMaxBonusRate, uint256 newOptimalBonusRate, uint256 newDepositUtilizationKink ); event WithdrawFeeParamsChanged( uint256 newMaxFlashFeeRate, uint256 newOptimalWithdrawalRate, uint256 newWithdrawUtilizationKink ); event ProtocolFeeChanged(uint256 prevValue, uint256 newValue); event RewardsTimelineChanged(uint256 prevValue, uint256 newValue); event RewardsAdded(uint256 amount, uint256 startTimeline); event EigenLayerFacetChanged(address prevValue, address newValue); event SetterFacetChanged(address prevValue, address newValue); event ERC4626FacetChanged(address prevValue, address newValue); event SignatureAdded( bytes4 indexed sig, FuncTarget target, FuncAccess access ); event RewardsCoordinatorChanged(address prevValue, address newValue); }
// 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.24; /// @author The InceptionLRT team /// @title The InceptionLibrary library /// @dev It serves two primary functions: /// 1. Flash vault-related logic for the calculations of deposit bonus and withdrawal fee /// 2. Conversions between shares and assets library InceptionLibrary { uint256 constant MAX_PERCENT = 100 * 1e8; /************************************************************ ************************ Flash Vault *********************** ************************************************************/ function calculateDepositBonus( uint256 amount, uint256 capacity, uint256 optimalCapacity, uint256 optimalBonusRate, uint256 maxDepositBonusRate, uint256 targetCapacity ) external pure returns (uint256 bonus) { /// @dev the utilization rate is in the range [0:25] % if (amount > 0 && capacity < optimalCapacity) { uint256 replenished = amount; if (optimalCapacity < capacity + amount) replenished = optimalCapacity - capacity; uint256 bonusSlope = ((maxDepositBonusRate - optimalBonusRate) * 1e18) / ((optimalCapacity * 1e18) / targetCapacity); uint256 bonusPercent = maxDepositBonusRate - (bonusSlope * (capacity + replenished / 2)) / targetCapacity; capacity += replenished; bonus += (replenished * bonusPercent) / MAX_PERCENT; amount -= replenished; } /// @dev the utilization rate is in the range [25: ] % if (amount > 0 && capacity <= targetCapacity) { uint256 replenished = targetCapacity > capacity + amount ? amount : targetCapacity - capacity; bonus += (replenished * optimalBonusRate) / MAX_PERCENT; } } function calculateWithdrawalFee( uint256 amount, uint256 capacity, uint256 optimalCapacity, uint256 optimaFeeRate, uint256 maxFlashWithdrawalFeeRate, uint256 targetCapacity ) external pure returns (uint256 fee) { /// @dev the utilization rate is in the range [100:25] % if (amount > 0 && capacity > optimalCapacity) { uint256 replenished = amount; if (capacity - amount < optimalCapacity) replenished = capacity - optimalCapacity; fee += (replenished * optimaFeeRate) / MAX_PERCENT; amount -= replenished; capacity -= replenished; if (fee == 0) ++fee; } /// @dev the utilization rate is in the range [25:0] % if (amount > 0) { uint256 feeSlope = ((maxFlashWithdrawalFeeRate - optimaFeeRate) * 1e18) / ((optimalCapacity * 1e18) / targetCapacity); uint256 bonusPercent = maxFlashWithdrawalFeeRate - (feeSlope * (capacity - amount / 2)) / targetCapacity; fee += (amount * bonusPercent) / MAX_PERCENT; if (fee == 0) ++fee; } if (fee == 0) ++fee; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {BeaconProxy, Address} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IOwnable} from "../../interfaces/common/IOwnable.sol"; import {IInceptionVault_EL} from "../../interfaces/eigenlayer-vault/IInceptionVault_EL.sol"; import {IInceptionToken} from "../../interfaces/common/IInceptionToken.sol"; import {IDelegationManager} from "../../interfaces/eigenlayer-vault/eigen-core/IDelegationManager.sol"; import {IInceptionRatioFeed} from "../../interfaces/common/IInceptionRatioFeed.sol"; import {IInceptionVaultErrors} from "../../interfaces/common/IInceptionVaultErrors.sol"; import {IInceptionEigenRestaker, IInceptionEigenRestakerErrors} from "../../interfaces/eigenlayer-vault/IInceptionEigenRestaker.sol"; import {IStrategyManager, IStrategy} from "../../interfaces/eigenlayer-vault/eigen-core/IStrategyManager.sol"; import {Convert} from "../../lib/Convert.sol"; import {InceptionLibrary} from "../../lib/InceptionLibrary.sol"; /** * @title InceptionVaultStorage_EL * @author The InceptionLRT team * @notice Manages the storage variables and getter functions for the Inception Vault, which interacts with EigenLayer and manages delegation, withdrawals, and rewards. * @dev This contract extends the Pausable, Ownable, and ReentrancyGuard patterns. */ contract InceptionVaultStorage_EL is PausableUpgradeable, ReentrancyGuardUpgradeable, OwnableUpgradeable, IInceptionVault_EL, IInceptionVaultErrors { IERC20 internal _asset; uint256[49] private __gap; IStrategyManager public strategyManager; IStrategy public strategy; uint256 public epoch; /// @dev Operator for the inception vault address internal _operator; /// @notice Represents the pending amount to be redeemed by claimers and to be undelegated from EigenLayer. uint256 public totalAmountToWithdraw; /// @dev Represents the amount pending processing until claimed. /// @notice Amount is measured in the vault's asset. uint256 internal _pendingWithdrawalAmount; IDelegationManager public delegationManager; Withdrawal[] public claimerWithdrawalsQueue; address internal constant _MOCK_ADDRESS = 0x0000000000000000000000000012345000000000; /// @dev Reserved for claimers' withdrawal requests. uint256 public redeemReservedAmount; /// @dev Maps EigenLayer operators to Inception stakers. mapping(address => address) internal _operatorRestakers; address[] public restakers; uint256 public depositBonusAmount; /// @dev Target capacity for the vault, represented in percentage terms (max 100%). uint256 public targetCapacity; uint256 public constant MAX_TARGET_PERCENT = 100 * 1e18; /// @dev constants are not stored in the storage uint256[50 - 13] private __reserver; IInceptionToken public inceptionToken; /// @dev Reduces rounding issues uint256 public minAmount; mapping(address => Withdrawal) internal _claimerWithdrawals; /// @dev Unique name of the InceptionVault. string public name; /// @dev Factory implementation address for creating stakers. address public stakerImplementation; // Flash withdrawal parameters /// @dev 100% uint64 public constant MAX_PERCENT = 100 * 1e8; IInceptionRatioFeed public ratioFeed; address public treasury; uint64 public protocolFee; uint64 public maxBonusRate; uint64 public optimalBonusRate; uint64 public depositUtilizationKink; uint64 public maxFlashFeeRate; uint64 public optimalWithdrawalRate; uint64 public withdrawUtilizationKink; address public rewardsCoordinator; address public eigenLayerFacet; address public erc4626Facet; address public setterFacet; uint256 public currentRewards; uint256 public startTimeline; uint256 public rewardsTimeline; mapping(bytes4 => FuncData) internal _selectorToTarget; /** * @notice Initializes the Inception Assets Handler * @dev This function is called during contract deployment. * @param assetAddress The address of the underlying ERC20 token. */ function __InceptionVaultStorage_EL_init( IERC20 assetAddress ) internal onlyInitializing { __Pausable_init(); __ReentrancyGuard_init(); __Ownable_init(); _asset = assetAddress; } /** * @notice Returns the total deposited amount in the vault strategy. * @return The total assets delegated, held in the vault, and pending withdrawal. */ function getTotalDeposited() public view returns (uint256) { return getTotalDelegated() + totalAssets() + _pendingWithdrawalAmount - depositBonusAmount; } /** * @notice Returns the total amount delegated to all restakers in EigenLayer. * @return total The total delegated amount. */ function getTotalDelegated() public view returns (uint256 total) { uint256 stakersNum = restakers.length; for (uint256 i = 0; i < stakersNum; ++i) { if (restakers[i] == address(0)) continue; total += strategy.userUnderlyingView(restakers[i]); } return total + strategy.userUnderlyingView(address(this)); } /** * @notice Returns the available balance that can be used for flash withdrawals. * @return total The total free balance available for flash withdrawals. */ function getFreeBalance() public view returns (uint256 total) { return getFlashCapacity() < _getTargetCapacity() ? 0 : getFlashCapacity() - _getTargetCapacity(); } /** * @notice Returns the amount pending withdrawal from EigenLayer. * @return total The pending withdrawal amount. */ function getPendingWithdrawalAmountFromEL() public view returns (uint256 total) { return _pendingWithdrawalAmount; } function implementation() external view returns (address) { return stakerImplementation; } /** * @notice Returns the current vault-to-underlying token ratio from the InceptionRatioFeed. * @return The ratio used for converting between vault shares and assets. */ function ratio() public view returns (uint256) { return ratioFeed.getRatioFor(address(inceptionToken)); } function getDelegatedTo( address elOperator ) external view returns (uint256) { return strategy.userUnderlyingView(_operatorRestakers[elOperator]); } function getPendingWithdrawalOf( address claimer ) external view returns (uint256) { return _claimerWithdrawals[claimer].amount; } /** * @notice Checks if the given claimer is able to redeem any withdrawals. * @param claimer The address of the claimer. * @return able Indicates whether the claimer can redeem withdrawals. * @return availableWithdrawals The array of indices where the claimer has available withdrawals. */ function isAbleToRedeem( address claimer ) public view returns (bool able, uint256[] memory) { // get the general request uint256 index; Withdrawal memory genRequest = _claimerWithdrawals[claimer]; uint256[] memory availableWithdrawals = new uint256[]( epoch - genRequest.epoch ); if (genRequest.amount == 0) return (false, availableWithdrawals); for (uint256 i = 0; i < epoch; ++i) { if (claimerWithdrawalsQueue[i].receiver == claimer) { able = true; availableWithdrawals[index] = i; ++index; } } // decrease arrays if (availableWithdrawals.length - index > 0) assembly { mstore(availableWithdrawals, index) } return (able, availableWithdrawals); } /********************************************************************* ****************************** ERC4626 ****************************** *********************************************************************/ /** * @notice Returns the address of the asset used in the vault. * @return The address of the underlying ERC20 token used for accounting, depositing, and withdrawing. */ function asset() public view returns (address) { return address(_asset); } /** * @notice Returns the total assets held by the vault. * @return The total balance of the vault in the underlying asset. */ function totalAssets() public view returns (uint256) { uint256 dayNum = (block.timestamp - startTimeline) / 1 days; uint256 totalDays = rewardsTimeline / 1 days; if (dayNum > totalDays) return _asset.balanceOf(address(this)); uint256 reservedRewards = (currentRewards / totalDays) * (totalDays - dayNum); return (_asset.balanceOf(address(this)) - reservedRewards); } /** * @dev See {IERC4626-convertToShares}. */ function convertToShares(uint256 assets) public view returns (uint256) { return _convertToShares(assets); } function _convertToShares( uint256 assets ) internal view returns (uint256 shares) { return Convert.multiplyAndDivideFloor(assets, ratio(), 1e18); } /** * @dev See {IERC4626-convertToAssets}. */ function convertToAssets(uint256 shares) public view returns (uint256) { return _convertToAssets(shares); } function _convertToAssets( uint256 iShares ) internal view returns (uint256 assets) { return Convert.multiplyAndDivideFloor(iShares, 1e18, ratio()); } /** * @dev See {IERC4626-maxDeposit}. * @dev The `maxDeposit` function is used to calculate the maximum deposit. * @notice If the vault is locked or paused, users are not allowed to deposit, the maxDeposit is 0. * @return Amount of the maximum underlying assets deposit amount. */ function maxDeposit(address receiver) public view returns (uint256) { return !paused() ? _asset.balanceOf(receiver) : 0; } /** * @dev See {IERC4626-maxMint} * @dev The `maxMint` function is used to calculate the maximum amount of shares you can mint. * @notice If the vault is locked or paused, the maxMint is 0. * @return Amount of the maximum shares mintable for the specified address. */ function maxMint(address receiver) public view returns (uint256) { return !paused() ? previewDeposit(_asset.balanceOf(receiver)) : 0; } /** * @dev See {IERC4626-maxRedeem}. * @notice If the function is called during the lock period the maxRedeem is `0`; * @param owner The address of the owner. * @return Amount of the maximum number of redeemable shares. */ function maxRedeem(address owner) public view returns (uint256) { if (paused()) { return 0; } else { uint256 ownerShares = IERC20(address(inceptionToken)).balanceOf( owner ); uint256 flashShares = convertToShares(getFlashCapacity()); return flashShares > ownerShares ? ownerShares : flashShares; } } /** * @dev See {IERC4626-previewDeposit}. */ function previewDeposit(uint256 assets) public view returns (uint256) { uint256 depositBonus; if (depositBonusAmount > 0) { depositBonus = calculateDepositBonus(assets); if (depositBonus > depositBonusAmount) depositBonus = depositBonusAmount; } return _convertToShares(assets + depositBonus); } /** * @notice Utilizes `inceptionToken.balanceOf()`. * @dev Returns the total amount of vault shares the owner currently has. * @dev See {IERC4626-balanceOf} */ function balanceOf(address owner) public view returns (uint256) { return IERC20(address(inceptionToken)).balanceOf(owner); } /** * @notice Utilizes `inceptionToken.totalSupply()`. * @dev Returns the total number of unredeemed vault shares in circulation. * @dev See {IERC4626-totalSupply} */ function totalSupply() public view returns (uint256) { return IERC20(address(inceptionToken)).totalSupply(); } /** * @dev This function allows users to simulate the effects of their redemption at the current block. * @dev See {IERC4626-previewRedeem} */ function previewRedeem( uint256 shares ) public view returns (uint256 assets) { return _convertToAssets(shares) - calculateFlashWithdrawFee(convertToAssets(shares)); } /*********************************************************************** ************************* FlashPool Functions ************************* ***********************************************************************/ /** * @notice Returns the flash withdrawal capacity. * @return total The total assets available for flash withdrawal. */ function getFlashCapacity() public view returns (uint256 total) { return totalAssets() - redeemReservedAmount - depositBonusAmount; } /// @notice Function to calculate deposit bonus based on the utilization rate function calculateDepositBonus( uint256 amount ) public view returns (uint256) { return InceptionLibrary.calculateDepositBonus( amount, getFlashCapacity(), (_getTargetCapacity() * depositUtilizationKink) / MAX_PERCENT, optimalBonusRate, maxBonusRate, _getTargetCapacity() ); } /// @dev Function to calculate flash withdrawal fee based on the utilization rate function calculateFlashWithdrawFee( uint256 amount ) public view returns (uint256) { uint256 capacity = getFlashCapacity(); if (amount > capacity) revert InsufficientCapacity(capacity); return InceptionLibrary.calculateWithdrawalFee( amount, capacity, (_getTargetCapacity() * withdrawUtilizationKink) / MAX_PERCENT, optimalWithdrawalRate, maxFlashFeeRate, _getTargetCapacity() ); } /** * @notice Sets the target and access level for a given function signature * @dev Updates the `_selectorToTarget` mapping with the provided function signature, target, and access level * @param sigs The function signature to configure * @param targets The target facet (contract) associated with the function signature * @param accesses The access level for the function signature */ function setSignaturesBatch( bytes4[] calldata sigs, FuncTarget[] calldata targets, FuncAccess[] calldata accesses ) external onlyOwner { uint256 num = sigs.length; if (num != targets.length || num != accesses.length) revert InconsistentData(); for (uint256 i = 0; i < num; ) { _selectorToTarget[sigs[i]] = FuncData({ facet: targets[i], access: accesses[i] }); unchecked { ++i; } } } /** * @notice Sets the target and access level for a given function signature * @dev Updates the `_selectorToTarget` mapping with the provided function signature, target, and access level * @param sig The function signature to configure * @param _target The target facet (contract) associated with the function signature * @param _access The access level for the function signature */ function setSignature( bytes4 sig, FuncTarget _target, FuncAccess _access ) external onlyOwner { _selectorToTarget[sig] = FuncData({facet: _target, access: _access}); emit SignatureAdded(sig, _target, _access); } function setEigenLayerFacet(address newEigenLayerFacet) external onlyOwner { if (!Address.isContract(newEigenLayerFacet)) revert NotContract(); emit EigenLayerFacetChanged(eigenLayerFacet, newEigenLayerFacet); eigenLayerFacet = newEigenLayerFacet; } function setERC4626Facet(address newERC4626Facet) external onlyOwner { if (!Address.isContract(newERC4626Facet)) revert NotContract(); emit ERC4626FacetChanged(erc4626Facet, newERC4626Facet); erc4626Facet = newERC4626Facet; } function setSetterFacet(address newSetterFacet) external onlyOwner { if (!Address.isContract(newSetterFacet)) revert NotContract(); emit SetterFacetChanged(setterFacet, newSetterFacet); setterFacet = newSetterFacet; } /********************************************************************* ************************* Internal function ************************* *********************************************************************/ /** * @notice Returns the target capacity based on the vault's configuration. * @dev This function calculates the vault's target capacity as a percentage of the total deposited amount. * @return The target capacity. */ function _getTargetCapacity() internal view returns (uint256) { return (targetCapacity * getTotalDeposited()) / MAX_TARGET_PERCENT; } function _getSelectorToTarget( bytes4 sig ) internal view returns (address, FuncAccess) { _requireNotPaused(); FuncData memory target = _selectorToTarget[sig]; if ( target.facet == FuncTarget.SETTER_FACET && target.access == FuncAccess.EVERYONE ) return (address(0), FuncAccess.EVERYONE); if (target.facet == FuncTarget.ERC4626_FACET) return (erc4626Facet, target.access); if (target.facet == FuncTarget.EIGEN_LAYER_FACET) return (eigenLayerFacet, target.access); if (target.facet == FuncTarget.SETTER_FACET) return (setterFacet, target.access); return (address(0), FuncAccess.EVERYONE); } function _verifyAccess(FuncAccess access) internal view { if (access == FuncAccess.ONLY_OWNER) { _checkOwner(); } else if (access == FuncAccess.ONLY_OPERATOR) { if (msg.sender != _operator) revert OnlyOperatorAllowed(); } } /** * @dev Internal function to transfer assets from the staker to the vault. * @param staker The address of the staker. * @param amount The amount to transfer. * @return The actual amount transferred. */ function _transferAssetFrom( address staker, uint256 amount ) internal returns (uint256) { uint256 depositedBefore = _asset.balanceOf(address(this)); if (!_asset.transferFrom(staker, address(this), amount)) revert TransferAssetFromFailed(address(_asset)); return _asset.balanceOf(address(this)) - depositedBefore; } /** * @dev Internal function to transfer assets from the vault to the receiver. * @param receiver The address to receive the assets. * @param amount The amount to transfer. */ function _transferAssetTo(address receiver, uint256 amount) internal { if (!_asset.transfer(receiver, amount)) revert TransferAssetFailed(address(_asset)); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": { "contracts/lib/InceptionLibrary.sol": { "InceptionLibrary": "0x8a6a8a7233b16d0ecaa7510bfd110464a0d69f66" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"AlreadyDelegated","type":"error"},{"inputs":[],"name":"ApproveError","type":"error"},{"inputs":[],"name":"DelegationManagerImmutable","type":"error"},{"inputs":[],"name":"DepositInconsistentResultedState","type":"error"},{"inputs":[],"name":"EigenLayerOperatorAlreadyExists","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"maxShares","type":"uint256"}],"name":"ExceededMaxMint","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":"FunctionNotSupported","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":"InvalidTargetFlashCapacity","type":"error"},{"inputs":[],"name":"IsNotAbleToRedeem","type":"error"},{"inputs":[{"internalType":"uint256","name":"minAmount","type":"uint256"}],"name":"LowerMinAmount","type":"error"},{"inputs":[],"name":"MsgSenderIsNotOwner","type":"error"},{"inputs":[],"name":"NotContract","type":"error"},{"inputs":[],"name":"NotEigenLayerOperator","type":"error"},{"inputs":[],"name":"NullParams","type":"error"},{"inputs":[],"name":"OnlyOperatorAllowed","type":"error"},{"inputs":[],"name":"OperatorNotRegistered","type":"error"},{"inputs":[{"internalType":"uint256","name":"param","type":"uint256"}],"name":"ParameterExceedsLimits","type":"error"},{"inputs":[],"name":"RestakerNotRegistered","type":"error"},{"inputs":[],"name":"TimelineNotOver","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":"ZeroFlashWithdrawFee","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakerAddress","type":"address"},{"indexed":true,"internalType":"address","name":"operatorAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"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":"amount","type":"uint256"}],"name":"DepositBonus","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxBonusRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newOptimalBonusRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDepositUtilizationKink","type":"uint256"}],"name":"DepositBonusParamsChanged","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":"ERC4626FacetChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"EigenLayerFacetChanged","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"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"FlashWithdraw","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":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"ProtocolFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"RatioFeedChanged","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":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTimeline","type":"uint256"}],"name":"RewardsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"RewardsCoordinatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"RewardsTimelineChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"SetterFacetChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":false,"internalType":"enum IInceptionVault_EL.FuncTarget","name":"target","type":"uint8"},{"indexed":false,"internalType":"enum IInceptionVault_EL.FuncAccess","name":"access","type":"uint8"}],"name":"SignatureAdded","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":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"TargetCapacityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"TreasuryChanged","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":"newMaxFlashFeeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newOptimalWithdrawalRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newWithdrawUtilizationKink","type":"uint256"}],"name":"WithdrawFeeParamsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"WithdrawalClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"WithdrawalFee","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"MAX_PERCENT","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TARGET_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateDepositBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateFlashWithdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationManager","outputs":[{"internalType":"contract IDelegationManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositBonusAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositUtilizationKink","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eigenLayerFacet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc4626Facet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"elOperator","type":"address"}],"name":"getDelegatedTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFlashCapacity","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFreeBalance","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingWithdrawalAmountFromEL","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"getPendingWithdrawalOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDelegated","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inceptionToken","outputs":[{"internalType":"contract IInceptionToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"vaultName","type":"string"},{"internalType":"address","name":"operatorAddress","type":"address"},{"internalType":"contract IStrategyManager","name":"_strategyManager","type":"address"},{"internalType":"contract IInceptionToken","name":"_inceptionToken","type":"address"},{"internalType":"contract IStrategy","name":"_assetStrategy","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"}],"name":"isAbleToRedeem","outputs":[{"internalType":"bool","name":"able","type":"bool"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBonusRate","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFlashFeeRate","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"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":"optimalBonusRate","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optimalWithdrawalRate","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"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":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ratio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ratioFeed","outputs":[{"internalType":"contract IInceptionRatioFeed","name":"","type":"address"}],"stateMutability":"view","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":[],"name":"rewardsCoordinator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsTimeline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newERC4626Facet","type":"address"}],"name":"setERC4626Facet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newEigenLayerFacet","type":"address"}],"name":"setEigenLayerFacet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSetterFacet","type":"address"}],"name":"setSetterFacet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"sig","type":"bytes4"},{"internalType":"enum IInceptionVault_EL.FuncTarget","name":"_target","type":"uint8"},{"internalType":"enum IInceptionVault_EL.FuncAccess","name":"_access","type":"uint8"}],"name":"setSignature","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4[]","name":"sigs","type":"bytes4[]"},{"internalType":"enum IInceptionVault_EL.FuncTarget[]","name":"targets","type":"uint8[]"},{"internalType":"enum IInceptionVault_EL.FuncAccess[]","name":"accesses","type":"uint8[]"}],"name":"setSignaturesBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setterFacet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakerImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startTimeline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"targetCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"totalSupply","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":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawUtilizationKink","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405261000c610011565b6100d0565b600054610100900460ff161561007d5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100ce576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61299580620000e06000396000f3fe608060405234801561001057600080fd5b50600436106103f05760003560e01c80637b487a6511610215578063c235fb1411610125578063e7807897116100b8578063eae43a4411610087578063eae43a44146108e6578063ef13b2c7146108f9578063ef8b30f71461091a578063f29768711461092d578063f2fde38b14610935576103f0565b8063e780789714610884578063e91bb84414610894578063e93c4f15146108ca578063ea4d3c9b146108d2576103f0565b8063cea6443a116100f4578063cea6443a14610837578063d1ef0c941461084a578063d8266c181461085e578063d905777e14610871576103f0565b8063c235fb14146107ea578063c63d75b6146107fe578063c6e6f59214610811578063ce5119ee14610824576103f0565b806396c8d48e116101a8578063b0e21e8a11610177578063b0e21e8a146107a0578063b637d669146107bb578063b68ef559146107c5578063c059a38e146107cd578063c137d8ad146107d7576103f0565b806396c8d48e1461073b5780639b2cb5d814610756578063a8c62e7614610760578063ab89b6af14610773576103f0565b80638e29ebb5116101e45780638e29ebb51461070c578063900cf0cf14610720578063901a7d53146107295780639669c7cf14610733576103f0565b80637b487a65146106cc5780638456cb59146106df5780638a2fc4e3146106e75780638da5cb5b146106fb576103f0565b80634886a9571161031057806366bcd641116102a357806370a082311161027257806370a0823114610682578063715018a61461069557806371ca337d1461069d578063779a6cdd146106a55780637839030f146106b9576103f0565b806366bcd641146106485780636a1ae053146106515780636b77b2f5146106655780636ba176c71461066f576103f0565b806353268ad0116102df57806353268ad0146106025780635c60da1b1461060c5780635c975abb1461061e57806361d027b314610634576103f0565b80634886a957146105b65780634a6b629d146105d15780634baa6193146105db5780634cdad506146105ef576103f0565b80632b6fd4f11161038857806339b70e381161035757806339b70e38146105755780633f4ba83a14610588578063402d267d14610590578063470a567c146105a3576103f0565b80632b6fd4f11461051b5780632df2228a1461054757806330e4cf3a1461055057806338d52e0f14610564576103f0565b80630b885ac3116103c45780630b885ac3146104d95780631036bbe2146104ec57806318160ddd146104f85780631f2ed36f14610500576103f0565b80629289171461046357806301e1d1141461049b57806306fdde03146104b157806307a2d13a146104c6575b6000806104086000356001600160e01b031916610948565b90925090506001600160a01b038216610434576040516369bd111d60e11b815260040160405180910390fd5b61043d81610ad4565b3660008037600080366000855af43d6000803e80801561045c573d6000f35b3d6000fd5b005b6101345461047e90600160c01b90046001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b6104a3610b3c565b604051908152602001610492565b6104b9610c97565b60405161049291906122d2565b6104a36104d4366004612321565b610d26565b6104616104e7366004612370565b610d37565b61047e6402540be40081565b6104a3610e57565b6101345461047e90600160401b90046001600160401b031681565b6101385461052f906001600160a01b031681565b6040516001600160a01b039091168152602001610492565b610100546104a3565b6101375461052f906001600160a01b031681565b60c9546001600160a01b031661052f565b60fb5461052f906001600160a01b031681565b610461610ecb565b6104a361059e366004612463565b610edd565b6104616105b13660046124cb565b610f66565b6101345461047e90600160801b90046001600160401b031681565b6104a36101075481565b6101315461052f906001600160a01b031681565b6104a36105fd366004612321565b6110ce565b6104a36101035481565b610131546001600160a01b031661052f565b60335460ff166040519015158152602001610492565b6101335461052f906001600160a01b031681565b6104a360ff5481565b6101355461047e906001600160401b031681565b6104a361013b5481565b6104a361067d366004612321565b6110ef565b6104a3610690366004612463565b6111d1565b610461611205565b6104a3611217565b6101345461047e906001600160401b031681565b6104616106c7366004612463565b61126a565b6104616106da366004612463565b611305565b6104616113a0565b6101365461052f906001600160a01b031681565b6097546001600160a01b031661052f565b6101325461052f906001600160a01b031681565b6104a360fd5481565b6104a361013a5481565b6104a36113b0565b6101355461047e90600160401b90046001600160401b031681565b6104a361012e5481565b60fc5461052f906001600160a01b031681565b6104a3610781366004612463565b6001600160a01b0316600090815261012f602052604090206002015490565b6101335461047e90600160a01b90046001600160401b031681565b6104a361013c5481565b6104a36113d6565b6104a36101065481565b6104616107e5366004612589565b611404565b61012d5461052f906001600160a01b031681565b6104a361080c366004612463565b6114f3565b6104a361081f366004612321565b61157d565b6104a3610832366004612463565b611588565b6104a3610845366004612321565b6115d0565b6101395461052f906001600160a01b031681565b61046161086c366004612463565b61170f565b6104a361087f366004612463565b6117aa565b6104a368056bc75e2d6310000081565b6108a76108a2366004612321565b611862565b604080519384526001600160a01b03909216602084015290820152606001610492565b6104a36118a2565b6101015461052f906001600160a01b031681565b61052f6108f4366004612321565b6118cf565b61090c610907366004612463565b6118fa565b6040516104929291906125d2565b6104a3610928366004612321565b611a59565b6104a3611a96565b610461610943366004612463565b611c11565b600080610953611c87565b6001600160e01b03198316600090815261013d602052604080822081518083019092528054829060ff16600281111561098e5761098e612624565b600281111561099f5761099f612624565b81528154602090910190610100900460ff1660028111156109c2576109c2612624565b60028111156109d3576109d3612624565b90525090506000815160028111156109ed576109ed612624565b148015610a0f5750600081602001516002811115610a0d57610a0d612624565b145b15610a205750600093849350915050565b600281516002811115610a3557610a35612624565b03610a5857610138546020909101516001600160a01b0390911694909350915050565b600181516002811115610a6d57610a6d612624565b03610a9057610137546020909101516001600160a01b0390911694909350915050565b600081516002811115610aa557610aa5612624565b03610ac857610139546020909101516001600160a01b0390911694909350915050565b50600093849350915050565b6002816002811115610ae857610ae8612624565b03610af857610af5611ccd565b50565b6001816002811115610b0c57610b0c612624565b03610af55760fe546001600160a01b03163314610af557604051633734611360e01b815260040160405180910390fd5b6000806201518061013b5442610b529190612650565b610b5c9190612679565b905060006201518061013c54610b729190612679565b905080821115610bef5760c9546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be8919061268d565b9250505090565b6000610bfb8383612650565b8261013a54610c0a9190612679565b610c1491906126a6565b60c9546040516370a0823160e01b815230600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015610c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c85919061268d565b610c8f9190612650565b935050505090565b6101308054610ca5906126bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd1906126bd565b8015610d1e5780601f10610cf357610100808354040283529160200191610d1e565b820191906000526020600020905b815481529060010190602001808311610d0157829003601f168201915b505050505081565b6000610d3182611d27565b92915050565b600054610100900460ff1615808015610d575750600054600160ff909116105b80610d715750303b158015610d71575060005460ff166001145b610dd95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610dfc576000805461ff0019166101001790555b610e098686868686611d43565b8015610e4f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b61012d54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610ea2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec6919061268d565b905090565b610ed3611ccd565b610edb611e02565b565b6000610eeb60335460ff1690565b15610ef7576000610d31565b60c9546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024015b602060405180830381865afa158015610f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d31919061268d565b610f6e611ccd565b848381141580610f7e5750808214155b15610f9c5760405163afff5f7760e01b815260040160405180910390fd5b60005b818110156110c4576040518060400160405280878784818110610fc457610fc46126f7565b9050602002016020810190610fd9919061270d565b6002811115610fea57610fea612624565b8152602001858584818110611001576110016126f7565b9050602002016020810190611016919061270d565b600281111561102757611027612624565b905261013d60008a8a85818110611040576110406126f7565b9050602002016020810190611055919061272a565b6001600160e01b0319168152602081019190915260400160002081518154829060ff1916600183600281111561108d5761108d612624565b021790555060208201518154829061ff0019166101008360028111156110b5576110b5612624565b02179055505050600101610f9f565b5050505050505050565b60006110dc61084583610d26565b6110e583611d27565b610d319190612650565b6000738a6a8a7233b16d0ecaa7510bfd110464a0d69f6663fea65f72836111146113b0565b610134546402540be40090600160801b90046001600160401b0316611137611e54565b61114191906126a6565b61114b9190612679565b610134546001600160401b03600160401b82048116911661116a611e54565b6040516001600160e01b031960e089901b1681526004810196909652602486019490945260448501929092526001600160401b03908116606485015216608483015260a482015260c401602060405180830381865af4158015610f42573d6000803e3d6000fd5b61012d546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a0823190602401610f25565b61120d611ccd565b610edb6000611e80565b6101325461012d5460405163a1f1d48d60e01b81526001600160a01b039182166004820152600092919091169063a1f1d48d90602401602060405180830381865afa158015610ea2573d6000803e3d6000fd5b611272611ccd565b6001600160a01b0381163b61129a57604051636f7c43f160e01b815260040160405180910390fd5b61013954604080516001600160a01b03928316815291831660208301527f16b3a5b47cfc3418106cb8fd15fc5df8b17ea324464f7655b052d9e4a3a14df2910160405180910390a161013980546001600160a01b0319166001600160a01b0392909216919091179055565b61130d611ccd565b6001600160a01b0381163b61133557604051636f7c43f160e01b815260040160405180910390fd5b61013754604080516001600160a01b03928316815291831660208301527fe6b9ab4b050c05a6c2d41e35b5c0112bb6c563134cc0daccc29a7a44d5da47fe910160405180910390a161013780546001600160a01b0319166001600160a01b0392909216919091179055565b6113a8611ccd565b610edb611ed2565b600061010654610103546113c2610b3c565b6113cc9190612650565b610ec69190612650565b600061010654610100546113e8610b3c565b6113f0611a96565b6113fa9190612745565b6113cc9190612745565b61140c611ccd565b604051806040016040528083600281111561142957611429612624565b815260200182600281111561144057611440612624565b90526001600160e01b03198416600090815261013d6020526040902081518154829060ff1916600183600281111561147a5761147a612624565b021790555060208201518154829061ff0019166101008360028111156114a2576114a2612624565b0217905550905050826001600160e01b0319167ffc2ae1ef55404e9b12cfaca1546ea9cdcac8ae491f101a407462bc926655c15783836040516114e6929190612776565b60405180910390a2505050565b600061150160335460ff1690565b1561150d576000610d31565b60c9546040516370a0823160e01b81526001600160a01b038481166004830152610d319216906370a0823190602401602060405180830381865afa158015611559573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610928919061268d565b6000610d3182611f0f565b60fc546001600160a01b0382811660009081526101046020526040808220549051630aa794bf60e31b815290831660048201529092919091169063553ca5f890602401610f25565b6000806115db6113b0565b90508083111561160157604051636688dd2d60e11b815260048101829052602401610dd0565b61013554738a6a8a7233b16d0ecaa7510bfd110464a0d69f669063cfe6424490859084906402540be40090600160401b90046001600160401b0316611644611e54565b61164e91906126a6565b6116589190612679565b61013554610134546001600160401b0391821691600160c01b9091041661167d611e54565b6040516001600160e01b031960e089901b1681526004810196909652602486019490945260448501929092526001600160401b03908116606485015216608483015260a482015260c401602060405180830381865af41580156116e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611708919061268d565b9392505050565b611717611ccd565b6001600160a01b0381163b61173f57604051636f7c43f160e01b815260040160405180910390fd5b61013854604080516001600160a01b03928316815291831660208301527f86214bbaa96d45f51d9923d72e74002d58b5554ccd07b1dbf67a6781adfa9e7c910160405180910390a161013880546001600160a01b0319166001600160a01b0392909216919091179055565b60006117b860335460ff1690565b156117c557506000919050565b61012d546040516370a0823160e01b81526001600160a01b03848116600483015260009216906370a0823190602401602060405180830381865afa158015611811573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611835919061268d565b9050600061184461081f6113b0565b90508181116118535780611855565b815b949350505050565b919050565b610102818154811061187357600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b039091169083565b60006118ac611e54565b6118b46113b0565b106118c9576118c1611e54565b6113cc6113b0565b50600090565b61010581815481106118e057600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03808216600090815261012f6020908152604080832081516060818101845282548083526001840154909716948201949094526002909101549181019190915260fd5492939192849283916119569190612650565b6001600160401b0381111561196d5761196d61233a565b604051908082528060200260200182016040528015611996578160200160208202803683370190505b50905081604001516000036119b2576000969095509350505050565b60005b60fd54811015611a3557866001600160a01b031661010282815481106119dd576119dd6126f7565b60009182526020909120600160039092020101546001600160a01b031603611a2d576001955080828581518110611a1657611a166126f7565b6020908102919091010152611a2a8461279c565b93505b6001016119b5565b506000838251611a459190612650565b1115611a4f578281525b9395939450505050565b6000806000610106541115611a8457611a71836110ef565b905061010654811115611a845750610106545b611708611a918285612745565b611f0f565b61010554600090815b81811015611b945760006001600160a01b03166101058281548110611ac657611ac66126f7565b6000918252602090912001546001600160a01b031614611b8c5760fc5461010580546001600160a01b039092169163553ca5f8919084908110611b0b57611b0b6126f7565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015611b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7f919061268d565b611b899084612745565b92505b600101611a9f565b5060fc54604051630aa794bf60e31b81523060048201526001600160a01b039091169063553ca5f890602401602060405180830381865afa158015611bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c01919061268d565b611c0b9083612745565b91505090565b611c19611ccd565b6001600160a01b038116611c7e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610dd0565b610af581611e80565b60335460ff1615610edb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610dd0565b6097546001600160a01b03163314610edb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610dd0565b6000610d3182670de0b6b3a7640000611d3e611217565b611f27565b611d4d8382611f64565b610130611d5a8682612802565b505060fe80546001600160a01b039485166001600160a01b03199182161790915561012d8054929094169116179091555050606461012e55610133805461013580547b11e1a300000000009502f90000000000017d78400000000008f0d180610134556b9502f9000000000002faf0806fffffffffffffffffffffffffffffffff199091161790556001600160e01b0319163317629502f960a91b17905562093a8061013c55565b611e0a6120bc565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600068056bc75e2d63100000611e686113d6565b61010754611e7691906126a6565b610ec69190612679565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611eda611c87565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611e373390565b6000610d3182611f1d611217565b670de0b6b3a76400005b6000611855611f3f611f398487612679565b85612105565b8385611f4b82896128c1565b611f5591906126a6565b611f5f9190612679565b61213b565b600054610100900460ff16611f8b5760405162461bcd60e51b8152600401610dd0906128d5565b60fb80546001600160a01b038085166001600160a01b03199283161790925560fc8054928416929091168217905560408051632495a59960e01b815290516120219291632495a5999160048083019260209291908290030181865afa158015611ff8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201c9190612920565b612153565b60c95460fb5460405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015612077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209b919061293d565b6120b857604051636822769b60e11b815260040160405180910390fd5b5050565b60335460ff16610edb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610dd0565b60008260000361211757506000610d31565b8282028284828161212a5761212a612663565b041461170857600019915050610d31565b60008282018381101561170857600019915050610d31565b600054610100900460ff1661217a5760405162461bcd60e51b8152600401610dd0906128d5565b6121826121b4565b61218a6121e3565b612192612212565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166121db5760405162461bcd60e51b8152600401610dd0906128d5565b610edb612241565b600054610100900460ff1661220a5760405162461bcd60e51b8152600401610dd0906128d5565b610edb612274565b600054610100900460ff166122395760405162461bcd60e51b8152600401610dd0906128d5565b610edb6122a2565b600054610100900460ff166122685760405162461bcd60e51b8152600401610dd0906128d5565b6033805460ff19169055565b600054610100900460ff1661229b5760405162461bcd60e51b8152600401610dd0906128d5565b6001606555565b600054610100900460ff166122c95760405162461bcd60e51b8152600401610dd0906128d5565b610edb33611e80565b60006020808352835180602085015260005b81811015612300578581018301518582016040015282016122e4565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561233357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610af557600080fd5b803561185d81612350565b600080600080600060a0868803121561238857600080fd5b85356001600160401b038082111561239f57600080fd5b818801915088601f8301126123b357600080fd5b8135818111156123c5576123c561233a565b604051601f8201601f19908116603f011681019083821181831017156123ed576123ed61233a565b816040528281528b602084870101111561240657600080fd5b82602086016020830137600060208483010152809950505050505061242d60208701612365565b935061243b60408701612365565b925061244960608701612365565b915061245760808701612365565b90509295509295909350565b60006020828403121561247557600080fd5b813561170881612350565b60008083601f84011261249257600080fd5b5081356001600160401b038111156124a957600080fd5b6020830191508360208260051b85010111156124c457600080fd5b9250929050565b600080600080600080606087890312156124e457600080fd5b86356001600160401b03808211156124fb57600080fd5b6125078a838b01612480565b9098509650602089013591508082111561252057600080fd5b61252c8a838b01612480565b9096509450604089013591508082111561254557600080fd5b5061255289828a01612480565b979a9699509497509295939492505050565b80356001600160e01b03198116811461185d57600080fd5b60038110610af557600080fd5b60008060006060848603121561259e57600080fd5b6125a784612564565b925060208401356125b78161257c565b915060408401356125c78161257c565b809150509250925092565b600060408201841515835260206040602085015281855180845260608601915060208701935060005b81811015612617578451835293830193918301916001016125fb565b5090979650505050505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610d3157610d3161263a565b634e487b7160e01b600052601260045260246000fd5b60008261268857612688612663565b500490565b60006020828403121561269f57600080fd5b5051919050565b8082028115828204841417610d3157610d3161263a565b600181811c908216806126d157607f821691505b6020821081036126f157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561271f57600080fd5b81356117088161257c565b60006020828403121561273c57600080fd5b61170882612564565b80820180821115610d3157610d3161263a565b60038110610af557634e487b7160e01b600052602160045260246000fd5b6040810161278384612758565b83825261278f83612758565b8260208301529392505050565b6000600182016127ae576127ae61263a565b5060010190565b601f8211156127fd576000816000526020600020601f850160051c810160208610156127de5750805b601f850160051c820191505b81811015610e4f578281556001016127ea565b505050565b81516001600160401b0381111561281b5761281b61233a565b61282f8161282984546126bd565b846127b5565b602080601f831160018114612864576000841561284c5750858301515b600019600386901b1c1916600185901b178555610e4f565b600085815260208120601f198616915b8281101561289357888601518255948401946001909101908401612874565b50858210156128b15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000826128d0576128d0612663565b500690565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006020828403121561293257600080fd5b815161170881612350565b60006020828403121561294f57600080fd5b8151801515811461170857600080fdfea26469706673582212207e84050282d67970944d83bf410c4857ee73cf712baf1cac67b78cde6eb72bba64736f6c63430008180033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103f05760003560e01c80637b487a6511610215578063c235fb1411610125578063e7807897116100b8578063eae43a4411610087578063eae43a44146108e6578063ef13b2c7146108f9578063ef8b30f71461091a578063f29768711461092d578063f2fde38b14610935576103f0565b8063e780789714610884578063e91bb84414610894578063e93c4f15146108ca578063ea4d3c9b146108d2576103f0565b8063cea6443a116100f4578063cea6443a14610837578063d1ef0c941461084a578063d8266c181461085e578063d905777e14610871576103f0565b8063c235fb14146107ea578063c63d75b6146107fe578063c6e6f59214610811578063ce5119ee14610824576103f0565b806396c8d48e116101a8578063b0e21e8a11610177578063b0e21e8a146107a0578063b637d669146107bb578063b68ef559146107c5578063c059a38e146107cd578063c137d8ad146107d7576103f0565b806396c8d48e1461073b5780639b2cb5d814610756578063a8c62e7614610760578063ab89b6af14610773576103f0565b80638e29ebb5116101e45780638e29ebb51461070c578063900cf0cf14610720578063901a7d53146107295780639669c7cf14610733576103f0565b80637b487a65146106cc5780638456cb59146106df5780638a2fc4e3146106e75780638da5cb5b146106fb576103f0565b80634886a9571161031057806366bcd641116102a357806370a082311161027257806370a0823114610682578063715018a61461069557806371ca337d1461069d578063779a6cdd146106a55780637839030f146106b9576103f0565b806366bcd641146106485780636a1ae053146106515780636b77b2f5146106655780636ba176c71461066f576103f0565b806353268ad0116102df57806353268ad0146106025780635c60da1b1461060c5780635c975abb1461061e57806361d027b314610634576103f0565b80634886a957146105b65780634a6b629d146105d15780634baa6193146105db5780634cdad506146105ef576103f0565b80632b6fd4f11161038857806339b70e381161035757806339b70e38146105755780633f4ba83a14610588578063402d267d14610590578063470a567c146105a3576103f0565b80632b6fd4f11461051b5780632df2228a1461054757806330e4cf3a1461055057806338d52e0f14610564576103f0565b80630b885ac3116103c45780630b885ac3146104d95780631036bbe2146104ec57806318160ddd146104f85780631f2ed36f14610500576103f0565b80629289171461046357806301e1d1141461049b57806306fdde03146104b157806307a2d13a146104c6575b6000806104086000356001600160e01b031916610948565b90925090506001600160a01b038216610434576040516369bd111d60e11b815260040160405180910390fd5b61043d81610ad4565b3660008037600080366000855af43d6000803e80801561045c573d6000f35b3d6000fd5b005b6101345461047e90600160c01b90046001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b6104a3610b3c565b604051908152602001610492565b6104b9610c97565b60405161049291906122d2565b6104a36104d4366004612321565b610d26565b6104616104e7366004612370565b610d37565b61047e6402540be40081565b6104a3610e57565b6101345461047e90600160401b90046001600160401b031681565b6101385461052f906001600160a01b031681565b6040516001600160a01b039091168152602001610492565b610100546104a3565b6101375461052f906001600160a01b031681565b60c9546001600160a01b031661052f565b60fb5461052f906001600160a01b031681565b610461610ecb565b6104a361059e366004612463565b610edd565b6104616105b13660046124cb565b610f66565b6101345461047e90600160801b90046001600160401b031681565b6104a36101075481565b6101315461052f906001600160a01b031681565b6104a36105fd366004612321565b6110ce565b6104a36101035481565b610131546001600160a01b031661052f565b60335460ff166040519015158152602001610492565b6101335461052f906001600160a01b031681565b6104a360ff5481565b6101355461047e906001600160401b031681565b6104a361013b5481565b6104a361067d366004612321565b6110ef565b6104a3610690366004612463565b6111d1565b610461611205565b6104a3611217565b6101345461047e906001600160401b031681565b6104616106c7366004612463565b61126a565b6104616106da366004612463565b611305565b6104616113a0565b6101365461052f906001600160a01b031681565b6097546001600160a01b031661052f565b6101325461052f906001600160a01b031681565b6104a360fd5481565b6104a361013a5481565b6104a36113b0565b6101355461047e90600160401b90046001600160401b031681565b6104a361012e5481565b60fc5461052f906001600160a01b031681565b6104a3610781366004612463565b6001600160a01b0316600090815261012f602052604090206002015490565b6101335461047e90600160a01b90046001600160401b031681565b6104a361013c5481565b6104a36113d6565b6104a36101065481565b6104616107e5366004612589565b611404565b61012d5461052f906001600160a01b031681565b6104a361080c366004612463565b6114f3565b6104a361081f366004612321565b61157d565b6104a3610832366004612463565b611588565b6104a3610845366004612321565b6115d0565b6101395461052f906001600160a01b031681565b61046161086c366004612463565b61170f565b6104a361087f366004612463565b6117aa565b6104a368056bc75e2d6310000081565b6108a76108a2366004612321565b611862565b604080519384526001600160a01b03909216602084015290820152606001610492565b6104a36118a2565b6101015461052f906001600160a01b031681565b61052f6108f4366004612321565b6118cf565b61090c610907366004612463565b6118fa565b6040516104929291906125d2565b6104a3610928366004612321565b611a59565b6104a3611a96565b610461610943366004612463565b611c11565b600080610953611c87565b6001600160e01b03198316600090815261013d602052604080822081518083019092528054829060ff16600281111561098e5761098e612624565b600281111561099f5761099f612624565b81528154602090910190610100900460ff1660028111156109c2576109c2612624565b60028111156109d3576109d3612624565b90525090506000815160028111156109ed576109ed612624565b148015610a0f5750600081602001516002811115610a0d57610a0d612624565b145b15610a205750600093849350915050565b600281516002811115610a3557610a35612624565b03610a5857610138546020909101516001600160a01b0390911694909350915050565b600181516002811115610a6d57610a6d612624565b03610a9057610137546020909101516001600160a01b0390911694909350915050565b600081516002811115610aa557610aa5612624565b03610ac857610139546020909101516001600160a01b0390911694909350915050565b50600093849350915050565b6002816002811115610ae857610ae8612624565b03610af857610af5611ccd565b50565b6001816002811115610b0c57610b0c612624565b03610af55760fe546001600160a01b03163314610af557604051633734611360e01b815260040160405180910390fd5b6000806201518061013b5442610b529190612650565b610b5c9190612679565b905060006201518061013c54610b729190612679565b905080821115610bef5760c9546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610bc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be8919061268d565b9250505090565b6000610bfb8383612650565b8261013a54610c0a9190612679565b610c1491906126a6565b60c9546040516370a0823160e01b815230600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015610c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c85919061268d565b610c8f9190612650565b935050505090565b6101308054610ca5906126bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd1906126bd565b8015610d1e5780601f10610cf357610100808354040283529160200191610d1e565b820191906000526020600020905b815481529060010190602001808311610d0157829003601f168201915b505050505081565b6000610d3182611d27565b92915050565b600054610100900460ff1615808015610d575750600054600160ff909116105b80610d715750303b158015610d71575060005460ff166001145b610dd95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610dfc576000805461ff0019166101001790555b610e098686868686611d43565b8015610e4f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b61012d54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610ea2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec6919061268d565b905090565b610ed3611ccd565b610edb611e02565b565b6000610eeb60335460ff1690565b15610ef7576000610d31565b60c9546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024015b602060405180830381865afa158015610f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d31919061268d565b610f6e611ccd565b848381141580610f7e5750808214155b15610f9c5760405163afff5f7760e01b815260040160405180910390fd5b60005b818110156110c4576040518060400160405280878784818110610fc457610fc46126f7565b9050602002016020810190610fd9919061270d565b6002811115610fea57610fea612624565b8152602001858584818110611001576110016126f7565b9050602002016020810190611016919061270d565b600281111561102757611027612624565b905261013d60008a8a85818110611040576110406126f7565b9050602002016020810190611055919061272a565b6001600160e01b0319168152602081019190915260400160002081518154829060ff1916600183600281111561108d5761108d612624565b021790555060208201518154829061ff0019166101008360028111156110b5576110b5612624565b02179055505050600101610f9f565b5050505050505050565b60006110dc61084583610d26565b6110e583611d27565b610d319190612650565b6000738a6a8a7233b16d0ecaa7510bfd110464a0d69f6663fea65f72836111146113b0565b610134546402540be40090600160801b90046001600160401b0316611137611e54565b61114191906126a6565b61114b9190612679565b610134546001600160401b03600160401b82048116911661116a611e54565b6040516001600160e01b031960e089901b1681526004810196909652602486019490945260448501929092526001600160401b03908116606485015216608483015260a482015260c401602060405180830381865af4158015610f42573d6000803e3d6000fd5b61012d546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a0823190602401610f25565b61120d611ccd565b610edb6000611e80565b6101325461012d5460405163a1f1d48d60e01b81526001600160a01b039182166004820152600092919091169063a1f1d48d90602401602060405180830381865afa158015610ea2573d6000803e3d6000fd5b611272611ccd565b6001600160a01b0381163b61129a57604051636f7c43f160e01b815260040160405180910390fd5b61013954604080516001600160a01b03928316815291831660208301527f16b3a5b47cfc3418106cb8fd15fc5df8b17ea324464f7655b052d9e4a3a14df2910160405180910390a161013980546001600160a01b0319166001600160a01b0392909216919091179055565b61130d611ccd565b6001600160a01b0381163b61133557604051636f7c43f160e01b815260040160405180910390fd5b61013754604080516001600160a01b03928316815291831660208301527fe6b9ab4b050c05a6c2d41e35b5c0112bb6c563134cc0daccc29a7a44d5da47fe910160405180910390a161013780546001600160a01b0319166001600160a01b0392909216919091179055565b6113a8611ccd565b610edb611ed2565b600061010654610103546113c2610b3c565b6113cc9190612650565b610ec69190612650565b600061010654610100546113e8610b3c565b6113f0611a96565b6113fa9190612745565b6113cc9190612745565b61140c611ccd565b604051806040016040528083600281111561142957611429612624565b815260200182600281111561144057611440612624565b90526001600160e01b03198416600090815261013d6020526040902081518154829060ff1916600183600281111561147a5761147a612624565b021790555060208201518154829061ff0019166101008360028111156114a2576114a2612624565b0217905550905050826001600160e01b0319167ffc2ae1ef55404e9b12cfaca1546ea9cdcac8ae491f101a407462bc926655c15783836040516114e6929190612776565b60405180910390a2505050565b600061150160335460ff1690565b1561150d576000610d31565b60c9546040516370a0823160e01b81526001600160a01b038481166004830152610d319216906370a0823190602401602060405180830381865afa158015611559573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610928919061268d565b6000610d3182611f0f565b60fc546001600160a01b0382811660009081526101046020526040808220549051630aa794bf60e31b815290831660048201529092919091169063553ca5f890602401610f25565b6000806115db6113b0565b90508083111561160157604051636688dd2d60e11b815260048101829052602401610dd0565b61013554738a6a8a7233b16d0ecaa7510bfd110464a0d69f669063cfe6424490859084906402540be40090600160401b90046001600160401b0316611644611e54565b61164e91906126a6565b6116589190612679565b61013554610134546001600160401b0391821691600160c01b9091041661167d611e54565b6040516001600160e01b031960e089901b1681526004810196909652602486019490945260448501929092526001600160401b03908116606485015216608483015260a482015260c401602060405180830381865af41580156116e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611708919061268d565b9392505050565b611717611ccd565b6001600160a01b0381163b61173f57604051636f7c43f160e01b815260040160405180910390fd5b61013854604080516001600160a01b03928316815291831660208301527f86214bbaa96d45f51d9923d72e74002d58b5554ccd07b1dbf67a6781adfa9e7c910160405180910390a161013880546001600160a01b0319166001600160a01b0392909216919091179055565b60006117b860335460ff1690565b156117c557506000919050565b61012d546040516370a0823160e01b81526001600160a01b03848116600483015260009216906370a0823190602401602060405180830381865afa158015611811573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611835919061268d565b9050600061184461081f6113b0565b90508181116118535780611855565b815b949350505050565b919050565b610102818154811061187357600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b039091169083565b60006118ac611e54565b6118b46113b0565b106118c9576118c1611e54565b6113cc6113b0565b50600090565b61010581815481106118e057600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03808216600090815261012f6020908152604080832081516060818101845282548083526001840154909716948201949094526002909101549181019190915260fd5492939192849283916119569190612650565b6001600160401b0381111561196d5761196d61233a565b604051908082528060200260200182016040528015611996578160200160208202803683370190505b50905081604001516000036119b2576000969095509350505050565b60005b60fd54811015611a3557866001600160a01b031661010282815481106119dd576119dd6126f7565b60009182526020909120600160039092020101546001600160a01b031603611a2d576001955080828581518110611a1657611a166126f7565b6020908102919091010152611a2a8461279c565b93505b6001016119b5565b506000838251611a459190612650565b1115611a4f578281525b9395939450505050565b6000806000610106541115611a8457611a71836110ef565b905061010654811115611a845750610106545b611708611a918285612745565b611f0f565b61010554600090815b81811015611b945760006001600160a01b03166101058281548110611ac657611ac66126f7565b6000918252602090912001546001600160a01b031614611b8c5760fc5461010580546001600160a01b039092169163553ca5f8919084908110611b0b57611b0b6126f7565b60009182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015611b5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7f919061268d565b611b899084612745565b92505b600101611a9f565b5060fc54604051630aa794bf60e31b81523060048201526001600160a01b039091169063553ca5f890602401602060405180830381865afa158015611bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c01919061268d565b611c0b9083612745565b91505090565b611c19611ccd565b6001600160a01b038116611c7e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610dd0565b610af581611e80565b60335460ff1615610edb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610dd0565b6097546001600160a01b03163314610edb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610dd0565b6000610d3182670de0b6b3a7640000611d3e611217565b611f27565b611d4d8382611f64565b610130611d5a8682612802565b505060fe80546001600160a01b039485166001600160a01b03199182161790915561012d8054929094169116179091555050606461012e55610133805461013580547b11e1a300000000009502f90000000000017d78400000000008f0d180610134556b9502f9000000000002faf0806fffffffffffffffffffffffffffffffff199091161790556001600160e01b0319163317629502f960a91b17905562093a8061013c55565b611e0a6120bc565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600068056bc75e2d63100000611e686113d6565b61010754611e7691906126a6565b610ec69190612679565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611eda611c87565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611e373390565b6000610d3182611f1d611217565b670de0b6b3a76400005b6000611855611f3f611f398487612679565b85612105565b8385611f4b82896128c1565b611f5591906126a6565b611f5f9190612679565b61213b565b600054610100900460ff16611f8b5760405162461bcd60e51b8152600401610dd0906128d5565b60fb80546001600160a01b038085166001600160a01b03199283161790925560fc8054928416929091168217905560408051632495a59960e01b815290516120219291632495a5999160048083019260209291908290030181865afa158015611ff8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201c9190612920565b612153565b60c95460fb5460405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af1158015612077573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209b919061293d565b6120b857604051636822769b60e11b815260040160405180910390fd5b5050565b60335460ff16610edb5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610dd0565b60008260000361211757506000610d31565b8282028284828161212a5761212a612663565b041461170857600019915050610d31565b60008282018381101561170857600019915050610d31565b600054610100900460ff1661217a5760405162461bcd60e51b8152600401610dd0906128d5565b6121826121b4565b61218a6121e3565b612192612212565b60c980546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff166121db5760405162461bcd60e51b8152600401610dd0906128d5565b610edb612241565b600054610100900460ff1661220a5760405162461bcd60e51b8152600401610dd0906128d5565b610edb612274565b600054610100900460ff166122395760405162461bcd60e51b8152600401610dd0906128d5565b610edb6122a2565b600054610100900460ff166122685760405162461bcd60e51b8152600401610dd0906128d5565b6033805460ff19169055565b600054610100900460ff1661229b5760405162461bcd60e51b8152600401610dd0906128d5565b6001606555565b600054610100900460ff166122c95760405162461bcd60e51b8152600401610dd0906128d5565b610edb33611e80565b60006020808352835180602085015260005b81811015612300578581018301518582016040015282016122e4565b506000604082860101526040601f19601f8301168501019250505092915050565b60006020828403121561233357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610af557600080fd5b803561185d81612350565b600080600080600060a0868803121561238857600080fd5b85356001600160401b038082111561239f57600080fd5b818801915088601f8301126123b357600080fd5b8135818111156123c5576123c561233a565b604051601f8201601f19908116603f011681019083821181831017156123ed576123ed61233a565b816040528281528b602084870101111561240657600080fd5b82602086016020830137600060208483010152809950505050505061242d60208701612365565b935061243b60408701612365565b925061244960608701612365565b915061245760808701612365565b90509295509295909350565b60006020828403121561247557600080fd5b813561170881612350565b60008083601f84011261249257600080fd5b5081356001600160401b038111156124a957600080fd5b6020830191508360208260051b85010111156124c457600080fd5b9250929050565b600080600080600080606087890312156124e457600080fd5b86356001600160401b03808211156124fb57600080fd5b6125078a838b01612480565b9098509650602089013591508082111561252057600080fd5b61252c8a838b01612480565b9096509450604089013591508082111561254557600080fd5b5061255289828a01612480565b979a9699509497509295939492505050565b80356001600160e01b03198116811461185d57600080fd5b60038110610af557600080fd5b60008060006060848603121561259e57600080fd5b6125a784612564565b925060208401356125b78161257c565b915060408401356125c78161257c565b809150509250925092565b600060408201841515835260206040602085015281855180845260608601915060208701935060005b81811015612617578451835293830193918301916001016125fb565b5090979650505050505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610d3157610d3161263a565b634e487b7160e01b600052601260045260246000fd5b60008261268857612688612663565b500490565b60006020828403121561269f57600080fd5b5051919050565b8082028115828204841417610d3157610d3161263a565b600181811c908216806126d157607f821691505b6020821081036126f157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561271f57600080fd5b81356117088161257c565b60006020828403121561273c57600080fd5b61170882612564565b80820180821115610d3157610d3161263a565b60038110610af557634e487b7160e01b600052602160045260246000fd5b6040810161278384612758565b83825261278f83612758565b8260208301529392505050565b6000600182016127ae576127ae61263a565b5060010190565b601f8211156127fd576000816000526020600020601f850160051c810160208610156127de5750805b601f850160051c820191505b81811015610e4f578281556001016127ea565b505050565b81516001600160401b0381111561281b5761281b61233a565b61282f8161282984546126bd565b846127b5565b602080601f831160018114612864576000841561284c5750858301515b600019600386901b1c1916600185901b178555610e4f565b600085815260208120601f198616915b8281101561289357888601518255948401946001909101908401612874565b50858210156128b15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000826128d0576128d0612663565b500690565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006020828403121561293257600080fd5b815161170881612350565b60006020828403121561294f57600080fd5b8151801515811461170857600080fdfea26469706673582212207e84050282d67970944d83bf410c4857ee73cf712baf1cac67b78cde6eb72bba64736f6c63430008180033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.