Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ERC20OmniVault_E2
Compiler Version
v0.8.27+commit.40a35a09
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.27;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {InceptionERC20OmniVault, IInceptionToken} from "../InceptionERC20OmniVault.sol";
import {IERC20CrossChainBridge} from "../../interfaces/IERC20CrossChainBridge.sol";
/// @author The InceptionLRT team
/// @title The ERC20OmniVault_E2, specifically designed for the Fraxtal Staked ETH omnichain restaking
contract ERC20OmniVault_E2 is InceptionERC20OmniVault {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() payable{
_disableInitializers();
}
function initialize(
string memory vaultName,
address _operator,
address _inceptionToken,
address _underlyingAsset,
IERC20CrossChainBridge _crossChainAdapter
) external initializer {
__InceptionERC20OmniVault_init(vaultName, _operator, IInceptionToken(_inceptionToken), IERC20(_underlyingAsset), _crossChainAdapter);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.0;
import "./OwnableUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides 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} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function __Ownable2Step_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable2Step_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
_transferOwnership(sender);
}
/**
* @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) (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.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
pragma solidity ^0.8.20;
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.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 {IInceptionERC20OmniVault} from "../interfaces/IInceptionERC20OmniVault.sol";
import {IInceptionAssetHandler} from "../interfaces/IInceptionAssetHandler.sol";
/// @author The InceptionLRT team
/// @title The InceptionERC20OmniAssetsHandler contract
/// @dev Handles operations with the corresponding asset (erc20 base token)
abstract contract InceptionERC20OmniAssetsHandler is
PausableUpgradeable,
ReentrancyGuardUpgradeable,
Ownable2StepUpgradeable,
IInceptionERC20OmniVault,
IInceptionAssetHandler
{
using SafeERC20 for IERC20;
IERC20 internal _asset;
uint256[50 - 1] private __reserver;
function __InceptionERC20OmniAssetsHandler_init(
IERC20 assetAddress
) internal onlyInitializing {
__Pausable_init();
__ReentrancyGuard_init();
_asset = assetAddress;
}
/// @dev returns the address of the underlying token used for the vault for accounting, depositing, flash-withdrawing.
function asset() public view returns (address) {
return address(_asset);
}
/// @dev returns the balance of iVault in underlying ERC20 token
function totalAssets() public view override returns (uint256) {
return _asset.balanceOf(address(this));
}
function _transferAssetFrom(address staker, uint256 amount) internal {
_asset.safeTransferFrom(staker, address(this), amount);
}
function _approve(address spender, uint256 amount) internal {
if(!_asset.approve(spender, amount)) revert AssetApprovalFailed();
}
function _transferAssetTo(address receiver, uint256 amount) internal {
_asset.safeTransfer(receiver, amount);
}
}// 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 RebalancerChanged(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.27;
import {ICrossChainBridge} from "./ICrossChainBridge.sol";
interface ICrossChainBridgeL2 is ICrossChainBridge {
function quote(
bytes calldata _payload,
bytes memory _options
) external view returns (uint256);
function sendDataL1(
bytes calldata _payload,
bytes memory _options
) external payable returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
interface ICrossChainBridge {
event TargetReceiverChanged(
address prevTargetReceiver,
address newTargetReceiver
);
event RecoverFundsInitiated(uint256 amount);
event ReceiveTriggered(address caller, uint256 amount);
event CrossChainEthDeposit(uint256 chainId, uint256 amount);
event ChainIdAdded(uint256 _chainId);
event CrossChainMessageReceived(
uint256 indexed chainId,
uint256 value,
bytes data
);
event CrossChainMessageSent(
uint256 indexed chainId,
uint256 value,
bytes data,
uint256 fee
);
error TargetReceiverNotSet();
error TransferToTargetReceiverFailed();
error SettingZeroAddress();
error NotTargetReceiver(address caller);
error ChainIdNotFound(uint256 chainId);
function setTargetReceiver(address _newTargetReceiver) external;
function recoverFunds() external;
function quoteSendEth(
uint256 _chainId,
bytes memory _options
) external view returns (uint256);
function sendEthCrossChain(
uint256 _chainId,
bytes memory _options
) external payable returns (uint256);
function getValueFromOpts(
bytes calldata _options
) external view returns (uint256);
receive() external payable;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
import {ICrossChainBridgeL2} from "./ICrossChainAdapterL2.sol";
interface IERC20CrossChainBridge is ICrossChainBridgeL2 {
function sendTokens(uint256 amount) external returns (uint256); // return value = what was returned (dust, etc)
function quoteSendTokens(uint256 amount) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IInceptionAssetHandler {
/*//////////////////////////
////// GET functions //////
////////////////////////*/
/// @dev returns total balance of Vault in the asset
function totalAssets() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IInceptionERC20OmniVault {
/*///////////////////////////////////////////////////
/ ******************** Errors ******************** /
/////////////////////////////////////////////////*/
error TransferAssetFromFailed();
error TransferAssetFailed();
error AssetApprovalFailed();
error InsufficientCapacity(uint256 capacity);
error MessageToL1Failed(uint256 tokenAmount, uint256 ethAmount);
error EthToL1Failed(uint256 ethAmount);
error CrossChainAdapterNotSet();
error OnlyOwnerOrOperator();
error ResultISharesZero();
error RatioFeedNotSet();
error FreeBalanceTooLow(uint256 freeBalance, uint256 msgValue);
error NullParams();
error ParameterExceedsLimits(uint256 param);
error BonusHigherThanFWFee(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);
error FeesAboveMsgValue(uint256 msgValue);
/*///////////////////////////////////////////////////
/ ******************** Events ******************** /
/////////////////////////////////////////////////*/
event Deposit(
address indexed sender,
address indexed receiver,
uint256 amount,
uint256 iShares
);
event FlashWithdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 amount,
uint256 iShares,
uint256 fee
);
event OperatorChanged(address prevValue, address newValue);
event DepositFeeChanged(uint256 prevValue, uint256 newValue);
event MinAmountChanged(uint256 prevValue, uint256 newValue);
event ProtocolFeeChanged(uint256 prevValue, uint256 newValue);
event TreasuryUpdated(
address indexed prevTreasury,
address indexed newTreasury
);
event RestakerDeployed(address indexed restaker);
event ImplementationUpgraded(address prevValue, address newValue);
event RatioFeedChanged(address prevValue, address newValue);
event NameChanged(string prevValue, string newValue);
event ReferralCode(address indexed sender, bytes32 indexed code);
event DepositBonus(uint256 amount);
event CrossChainAdapterChanged(
address prevCrossChainAdapter,
address newCrossChainAdapter
);
event MessageToL1Sent(
uint256 indexed tokensAmount,
uint256 indexed ethAmount
);
event ERC20CrossChainSent(uint256 amount, uint256 indexed chainId);
event DepositBonusParamsChanged(
uint256 newMaxBonusRate,
uint256 newOptimalBonusRate,
uint256 newDepositUtilizationKink
);
event WithdrawFeeParamsChanged(
uint256 newMaxFlashFeeRate,
uint256 newOptimalWithdrawalRate,
uint256 newWithdrawUtilizationKink
);
event AssetsInfoSentToL1(uint256 tokensAmount, uint256 ethAmount);
event ERC20SentToL1(uint256 amount);
event TargetCapacityChanged(uint256 prevValue, uint256 newValue);
event UnusedFeesSentBackToOperator(uint256 unusedFees);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "./common/IInceptionToken.sol";
interface IInceptionVault {
/*///////////////////
////// Events //////
/////////////////*/
event Deposit(
address indexed sender,
address indexed receiver,
uint256 amount,
uint256 iShares
);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 amount,
uint256 iShares
);
event 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 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 TreasuryUpdated(address indexed prevTreasury, address indexed newTreasury);
event MessageToL1Sent(
uint256 indexed tokensAmount,
uint256 indexed ethAmount
);
event EthToL1Sent(uint256 callValue);
error OnlyOwnerOrOperator();
error ResultISharesZero();
error RatioFeedNotSet();
error FreeBalanceIsZero();
error EthToL1Failed(uint256 amount);
error MessageToL1Failed(uint256 tokensAmount, uint256 ethAmount);
error CrossChainAdapterNotSet();
function inceptionToken() external view returns (IInceptionToken);
function ratio() external view returns (uint256);
}// 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 InternalInceptionLibrary 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 InternalInceptionLibrary {
uint256 constant MAX_PERCENT = 100 * 1e8;
/************************************************************
************************ Flash Vault ***********************
************************************************************/
function calculateDepositBonus(
uint256 amount,
uint256 capacity,
uint256 optimalCapacity,
uint256 optimalBonusRate,
uint256 maxDepositBonusRate,
uint256 targetCapacity
) internal pure returns (uint256 bonus) {
// uint256 optimalCapacity = (targetCapacity * depositUtilizationKink) /
// MAX_PERCENT;
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
) internal pure returns (uint256 fee) {
/// @dev the utilization rate is greater 1, [ :100] %
if (amount > 0 && capacity > targetCapacity) {
uint256 replenished = amount;
if (capacity - amount < targetCapacity)
replenished = capacity - targetCapacity;
amount -= replenished;
capacity -= replenished;
}
/// @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; // 0.5%
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;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {InceptionERC20OmniAssetsHandler} from "../assets-handler/InceptionERC20OmniAssetsHandler.sol";
import {IInceptionVault} from "../interfaces/IInceptionVault.sol";
import {IInceptionToken} from "../interfaces/common/IInceptionToken.sol";
import {IInceptionRatioFeed} from "../interfaces/common/IInceptionRatioFeed.sol";
import {IERC20CrossChainBridge} from "../interfaces/IERC20CrossChainBridge.sol";
import {InternalInceptionLibrary} from "../lib/InternalInceptionLibrary.sol";
import {Convert} from "../lib/Convert.sol";
/**
* @title InceptionERC20OmniVault
* @author The InceptionLRT team
* @dev A vault that handles deposits, withdrawals, and cross-chain operations for the Inception protocol.
* @notice Allows users to deposit an ERC20 asset (e.g. sfrxETH), receive inception tokens, and handle asset transfers between L1 and L2.
*/
abstract contract InceptionERC20OmniVault is InceptionERC20OmniAssetsHandler {
/// @dev Inception restaking token
IInceptionToken public inceptionToken;
/// @dev Reduces rounding issues
uint256 public minAmount;
/// @dev the unique InceptionVault name
string public name;
address public operator;
IInceptionRatioFeed public ratioFeed;
IERC20CrossChainBridge public crossChainAdapterERC20;
/**
* @dev Flash withdrawal params
*/
uint256 public constant MAX_TARGET_PERCENT = 100 * 1e18;
uint256 public constant MAX_PERCENT = 100 * 1e8;
uint256 public depositBonusAmount;
uint256 public targetCapacity;
address public treasuryAddress;
uint64 public protocolFee;
/// @dev deposit bonus
uint64 public maxBonusRate;
uint64 public optimalBonusRate;
uint64 public depositUtilizationKink;
/// @dev flash withdrawal fee
uint64 public maxFlashFeeRate;
uint64 public optimalWithdrawalRate;
uint64 public withdrawUtilizationKink;
/// @dev Modifier to restrict functions to owner or operator.
modifier onlyOwnerOrOperator() {
if (msg.sender != owner() && msg.sender != operator)
revert OnlyOwnerOrOperator();
_;
}
function __InceptionERC20OmniVault_init(
string memory vaultName,
address _operator,
IInceptionToken _inceptionToken,
IERC20 _underlyingAsset,
IERC20CrossChainBridge _crossChainAdapter
) internal {
__Ownable2Step_init();
__InceptionERC20OmniAssetsHandler_init(_underlyingAsset);
name = vaultName;
operator = _operator;
treasuryAddress = msg.sender;
inceptionToken = _inceptionToken;
crossChainAdapterERC20 = _crossChainAdapter;
minAmount = 1e8;
targetCapacity = 0.5 ether;
protocolFee = 50 * 1e8;
/// @dev deposit bonus
depositUtilizationKink = 25 * 1e8;
maxBonusRate = 1.5 * 1e8;
optimalBonusRate = 0.25 * 1e8;
/// @dev withdrawal fee
withdrawUtilizationKink = 25 * 1e8;
maxFlashFeeRate = 3 * 1e8;
optimalWithdrawalRate = 0.5 * 1e8;
}
/*//////////////////////////////
////// Deposit functions //////
////////////////////////////*/
/**
* @dev Ensures deposit parameters are valid.
* @param receiver Address receiving the deposit.
* @param amount Amount of assets to be deposited.
*/
function __beforeDeposit(address receiver, uint256 amount) internal view {
if (receiver == address(0)) revert NullParams();
if (amount < minAmount) revert LowerMinAmount(minAmount);
}
/**
* @dev Ensures the calculated iShares is valid post-deposit.
* @param iShares Number of shares issued after the deposit.
*/
function __afterDeposit(uint256 iShares) internal pure {
if (iShares == 0) revert DepositInconsistentResultedState();
}
/// @dev Transfers the msg.sender's assets to the vault.
/// @dev Mints Inception tokens in accordance with the current ratio.
/// @dev Issues the tokens to the specified receiver address.
function deposit(
uint256 amount,
address receiver
) external nonReentrant whenNotPaused returns (uint256) {
return _deposit(amount, msg.sender, receiver);
}
/// @notice The deposit function but with a referral code
function depositWithReferral(
uint256 amount,
address receiver,
bytes32 code
) external nonReentrant whenNotPaused returns (uint256) {
emit ReferralCode(msg.sender, code);
return _deposit(amount, msg.sender, receiver);
}
function _deposit(
uint256 amount,
address sender,
address receiver
) internal returns (uint256) {
uint256 currentRatio = ratio();
// transfers assets from the sender and returns the received amount
// the actual received amount might slightly differ from the specified amount,
// approximately by -2 wei
__beforeDeposit(receiver, amount);
uint256 depositedBefore = totalAssets();
uint256 depositBonus;
if (depositBonusAmount > 0) {
depositBonus = calculateDepositBonus(amount);
if (depositBonus > depositBonusAmount) {
depositBonus = depositBonusAmount;
depositBonusAmount = 0;
} else {
depositBonusAmount -= depositBonus;
}
emit DepositBonus(depositBonus);
}
// pull the amount from the sender
_transferAssetFrom(sender, amount);
amount = totalAssets() - depositedBefore;
uint256 iShares = Convert.multiplyAndDivideFloor(
amount + depositBonus,
currentRatio,
1e18
);
inceptionToken.mint(receiver, iShares);
__afterDeposit(iShares);
emit Deposit(sender, receiver, amount, iShares);
return iShares;
}
/*/////////////////////////////////////////////
///////// Flash Withdrawal functions /////////
///////////////////////////////////////////*/
/**
* @dev Ensures withdrawal parameters are valid.
* @param receiver Address receiving the withdrawal.
* @param iShares Number of shares to be withdrawn.
*/
function __beforeWithdraw(address receiver, uint256 iShares) internal pure {
if (iShares == 0) revert NullParams();
if (receiver == address(0)) revert NullParams();
}
/// @dev Performs burning iToken from msg.sender
/// @dev Creates a withdrawal requests based on the current ratio
/// @param iShares is measured in Inception token(shares)
function flashWithdraw(
uint256 iShares,
address receiver
) external whenNotPaused nonReentrant {
__beforeWithdraw(receiver, iShares);
address claimer = msg.sender;
uint256 currentRatio = ratio();
uint256 amount = Convert.multiplyAndDivideFloor(
iShares,
1e18,
currentRatio
);
uint256 capacity = getFlashCapacity();
if (amount < minAmount) revert LowerMinAmount(minAmount);
if (amount > capacity) revert InsufficientCapacity(capacity);
// burn Inception token in view of the current ratio
inceptionToken.burn(claimer, iShares);
uint256 fee = calculateFlashWithdrawFee(amount);
if (fee == 0) revert ZeroFlashWithdrawFee();
amount -= fee;
uint256 protocolWithdrawalFee = (fee * protocolFee) / MAX_PERCENT;
depositBonusAmount += (fee - protocolWithdrawalFee);
/// @notice instant transfer fee to the treasuryAddress
_transferAssetTo(treasuryAddress, protocolWithdrawalFee);
/// @notice instant transfer amount to the receiver
_transferAssetTo(receiver, amount);
emit FlashWithdraw(claimer, receiver, claimer, amount, iShares, fee);
}
/*//////////////////////////////
////// Cross-chain functions ///
//////////////////////////////*/
/**
* @notice Sends asset information (total Inception and underlying token balances) to Layer 1.
*/
function sendAssetsInfoToL1(
bytes memory _options
) external payable onlyOwnerOrOperator {
require(
address(crossChainAdapterERC20) != address(0),
CrossChainAdapterNotSet()
);
/// @dev fees are still paid in ETH
uint256 msgValue = msg.value;
uint256 tokensAmount = _inceptionTokenSupply();
uint256 erc20Amount = getFlashCapacity();
bytes memory payload = abi.encode(
block.timestamp,
tokensAmount,
erc20Amount
);
require(
msgValue >= quoteSendAssetsInfoToL1(_options),
FeesAboveMsgValue(msgValue)
);
uint256 fees = crossChainAdapterERC20.sendDataL1{value: msgValue}(
payload,
_options
);
uint256 unusedFees = msgValue - fees;
if (unusedFees > 0) {
(bool success, ) = msg.sender.call{value: unusedFees}("");
if (success) emit UnusedFeesSentBackToOperator(unusedFees);
}
emit MessageToL1Sent(tokensAmount, erc20Amount);
}
/**
* @notice Calculates price to send data message to Layer 1.
*/
function quoteSendAssetsInfoToL1(
bytes memory _options
) public view returns (uint256) {
require(
address(crossChainAdapterERC20) != address(0),
CrossChainAdapterNotSet()
);
uint256 tokensAmount = _inceptionTokenSupply();
uint256 erc20Amount = getFlashCapacity();
bytes memory payload = abi.encode(
block.timestamp,
tokensAmount,
erc20Amount
);
return crossChainAdapterERC20.quote(payload, _options);
}
/**
* @notice Sends available ERC20 to another chain via cross-chain adapter.
* @dev msg.value is used to pay for the cross-chain fees
*/
function sendERC20ToL1(
uint256 _chainId
) external payable onlyOwnerOrOperator {
uint256 freeBalance = getFreeBalance();
require(
freeBalance >= quoteSendERC20CrossChain(freeBalance),
FeesAboveMsgValue(freeBalance)
);
_approve(address(crossChainAdapterERC20), freeBalance);
uint256 returnedDust = crossChainAdapterERC20.sendTokens(freeBalance);
emit ERC20CrossChainSent(freeBalance - returnedDust, _chainId);
}
/**
* @notice Calculates fees to send ERC20 to other chain. The `SEND_VALUE` encoded in options is not included in the return
* @param _amount amount of token to be sent
*/
function quoteSendERC20CrossChain(
uint256 _amount
) public view returns (uint256) {
require(
address(crossChainAdapterERC20) != address(0),
CrossChainAdapterNotSet()
);
return crossChainAdapterERC20.quoteSendTokens(_amount); // this is just the ferry fee
}
/*//////////////////////////////
////// Utility functions ///////
//////////////////////////////*/
/**
* @notice Calculates the bonus for a deposit based on the current utilization rate.
* @param amount Amount of the deposit.
* @return bonus Calculated bonus.
*/
function calculateDepositBonus(
uint256 amount
) public view returns (uint256) {
return
InternalInceptionLibrary.calculateDepositBonus(
amount,
getFlashCapacity(),
(targetCapacity * depositUtilizationKink) / MAX_PERCENT,
optimalBonusRate,
maxBonusRate,
targetCapacity
);
}
/// @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
InternalInceptionLibrary.calculateWithdrawalFee(
amount,
capacity,
(targetCapacity * withdrawUtilizationKink) / MAX_PERCENT,
optimalWithdrawalRate,
maxFlashFeeRate,
targetCapacity
);
}
function getFreeBalance() public view returns (uint256) {
return
getFlashCapacity() < targetCapacity
? 0
: getFlashCapacity() - targetCapacity;
}
function _inceptionTokenSupply() internal view returns (uint256) {
return IERC20(address(inceptionToken)).totalSupply();
}
function ratio() public view returns (uint256) {
return ratioFeed.getRatioFor(address(inceptionToken));
}
function getTotalDeposited() public view returns (uint256) {
return totalAssets() - depositBonusAmount;
}
function getFlashCapacity() public view returns (uint256 total) {
return totalAssets() - depositBonusAmount;
}
function _getTargetCapacity() internal view returns (uint256) {
return (targetCapacity * getTotalDeposited()) / MAX_TARGET_PERCENT;
}
/*//////////////////////////////
////// Convert functions //////
////////////////////////////*/
function convertToShares(
uint256 assets
) public view returns (uint256 shares) {
return Convert.multiplyAndDivideFloor(assets, ratio(), 1e18);
}
function convertToAssets(
uint256 iShares
) public view returns (uint256 assets) {
return Convert.multiplyAndDivideFloor(iShares, 1e18, ratio());
}
/*//////////////////////////
////// SET functions //////
////////////////////////*/
function setDepositBonusParams(
uint64 newMaxBonusRate,
uint64 newOptimalBonusRate,
uint64 newDepositUtilizationKink
) external onlyOwner {
if (newMaxBonusRate > MAX_PERCENT)
revert ParameterExceedsLimits(newMaxBonusRate);
if (newOptimalBonusRate > MAX_PERCENT)
revert ParameterExceedsLimits(newOptimalBonusRate);
if (newDepositUtilizationKink > MAX_PERCENT)
revert ParameterExceedsLimits(newDepositUtilizationKink);
if (newMaxBonusRate > maxFlashFeeRate)
revert BonusHigherThanFWFee(newMaxBonusRate);
if (newOptimalBonusRate > optimalWithdrawalRate)
revert BonusHigherThanFWFee(newOptimalBonusRate);
if (newDepositUtilizationKink > withdrawUtilizationKink)
revert BonusHigherThanFWFee(newDepositUtilizationKink);
maxBonusRate = newMaxBonusRate;
optimalBonusRate = newOptimalBonusRate;
depositUtilizationKink = newDepositUtilizationKink;
emit DepositBonusParamsChanged(
newMaxBonusRate,
newOptimalBonusRate,
newDepositUtilizationKink
);
}
function setFlashWithdrawFeeParams(
uint64 newMaxFlashFeeRate,
uint64 newOptimalWithdrawalRate,
uint64 newWithdrawUtilizationKink
) external onlyOwner {
if (newMaxFlashFeeRate > MAX_PERCENT)
revert ParameterExceedsLimits(newMaxFlashFeeRate);
if (newOptimalWithdrawalRate > MAX_PERCENT)
revert ParameterExceedsLimits(newOptimalWithdrawalRate);
if (newWithdrawUtilizationKink > MAX_PERCENT)
revert ParameterExceedsLimits(newWithdrawUtilizationKink);
if (newMaxFlashFeeRate < maxBonusRate)
revert BonusHigherThanFWFee(newMaxFlashFeeRate);
if (newOptimalWithdrawalRate < optimalBonusRate)
revert BonusHigherThanFWFee(newOptimalWithdrawalRate);
if (newWithdrawUtilizationKink < depositUtilizationKink)
revert BonusHigherThanFWFee(newWithdrawUtilizationKink);
maxFlashFeeRate = newMaxFlashFeeRate;
optimalWithdrawalRate = newOptimalWithdrawalRate;
withdrawUtilizationKink = newWithdrawUtilizationKink;
emit WithdrawFeeParamsChanged(
newMaxFlashFeeRate,
newOptimalWithdrawalRate,
newWithdrawUtilizationKink
);
}
function setProtocolFee(uint64 newProtocolFee) external onlyOwner {
if (newProtocolFee >= MAX_PERCENT)
revert ParameterExceedsLimits(newProtocolFee);
emit ProtocolFeeChanged(protocolFee, newProtocolFee);
protocolFee = newProtocolFee;
}
function setRatioFeed(IInceptionRatioFeed newRatioFeed) external onlyOwner {
if (address(newRatioFeed) == address(0)) revert NullParams();
emit RatioFeedChanged(address(ratioFeed), address(newRatioFeed));
ratioFeed = newRatioFeed;
}
function setMinAmount(uint256 newMinAmount) external onlyOwner {
emit MinAmountChanged(minAmount, newMinAmount);
minAmount = newMinAmount;
}
function setTreasuryAddress(address _newTreasury) external onlyOwner {
if (_newTreasury == address(0)) revert NullParams();
emit TreasuryUpdated(treasuryAddress, _newTreasury);
treasuryAddress = _newTreasury;
}
function setTargetFlashCapacity(
uint256 newTargetCapacity
) external onlyOwner {
if (newTargetCapacity == 0) revert NullParams();
emit TargetCapacityChanged(targetCapacity, newTargetCapacity);
targetCapacity = newTargetCapacity;
}
function setName(string memory newVaultName) external onlyOwner {
if (bytes(newVaultName).length == 0) revert NullParams();
emit NameChanged(name, newVaultName);
name = newVaultName;
}
/*///////////////////////////////
////// Pausable functions //////
/////////////////////////////*/
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"AlreadyDelegated","type":"error"},{"inputs":[],"name":"AssetApprovalFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"param","type":"uint256"}],"name":"BonusHigherThanFWFee","type":"error"},{"inputs":[],"name":"CrossChainAdapterNotSet","type":"error"},{"inputs":[],"name":"DelegationManagerImmutable","type":"error"},{"inputs":[],"name":"DepositInconsistentResultedState","type":"error"},{"inputs":[{"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"EthToL1Failed","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":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"FeesAboveMsgValue","type":"error"},{"inputs":[{"internalType":"uint256","name":"freeBalance","type":"uint256"},{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"FreeBalanceTooLow","type":"error"},{"inputs":[],"name":"ImplementationNotSet","type":"error"},{"inputs":[{"internalType":"uint256","name":"capacity","type":"uint256"}],"name":"InsufficientCapacity","type":"error"},{"inputs":[],"name":"IsNotAbleToRedeem","type":"error"},{"inputs":[{"internalType":"uint256","name":"minAmount","type":"uint256"}],"name":"LowerMinAmount","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"MessageToL1Failed","type":"error"},{"inputs":[],"name":"NotContract","type":"error"},{"inputs":[],"name":"NullParams","type":"error"},{"inputs":[],"name":"OnlyOperatorAllowed","type":"error"},{"inputs":[],"name":"OnlyOwnerOrOperator","type":"error"},{"inputs":[],"name":"OperatorNotRegistered","type":"error"},{"inputs":[{"internalType":"uint256","name":"param","type":"uint256"}],"name":"ParameterExceedsLimits","type":"error"},{"inputs":[],"name":"RatioFeedNotSet","type":"error"},{"inputs":[],"name":"RestakerNotRegistered","type":"error"},{"inputs":[],"name":"ResultISharesZero","type":"error"},{"inputs":[],"name":"TransferAssetFailed","type":"error"},{"inputs":[],"name":"TransferAssetFromFailed","type":"error"},{"inputs":[],"name":"ZeroFlashWithdrawFee","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"AssetsInfoSentToL1","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"prevCrossChainAdapter","type":"address"},{"indexed":false,"internalType":"address","name":"newCrossChainAdapter","type":"address"}],"name":"CrossChainAdapterChanged","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":false,"internalType":"uint256","name":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"DepositFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"ERC20CrossChainSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20SentToL1","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":true,"internalType":"uint256","name":"tokensAmount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"MessageToL1Sent","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":"OwnershipTransferStarted","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":"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":"prevValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"TargetCapacityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"prevTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"unusedFees","type":"uint256"}],"name":"UnusedFeesSentBackToOperator","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"},{"inputs":[],"name":"MAX_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TARGET_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"iShares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crossChainAdapterERC20","outputs":[{"internalType":"contract IERC20CrossChainBridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"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":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"depositWithReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"iShares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"flashWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getFlashCapacity","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFreeBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"_operator","type":"address"},{"internalType":"address","name":"_inceptionToken","type":"address"},{"internalType":"address","name":"_underlyingAsset","type":"address"},{"internalType":"contract IERC20CrossChainBridge","name":"_crossChainAdapter","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxBonusRate","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFlashFeeRate","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"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":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"quoteSendAssetsInfoToL1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"quoteSendERC20CrossChain","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"sendAssetsInfoToL1","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"}],"name":"sendERC20ToL1","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newMaxBonusRate","type":"uint64"},{"internalType":"uint64","name":"newOptimalBonusRate","type":"uint64"},{"internalType":"uint64","name":"newDepositUtilizationKink","type":"uint64"}],"name":"setDepositBonusParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newMaxFlashFeeRate","type":"uint64"},{"internalType":"uint64","name":"newOptimalWithdrawalRate","type":"uint64"},{"internalType":"uint64","name":"newWithdrawUtilizationKink","type":"uint64"}],"name":"setFlashWithdrawFeeParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinAmount","type":"uint256"}],"name":"setMinAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newVaultName","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newProtocolFee","type":"uint64"}],"name":"setProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IInceptionRatioFeed","name":"newRatioFeed","type":"address"}],"name":"setRatioFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTargetCapacity","type":"uint256"}],"name":"setTargetFlashCapacity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTreasury","type":"address"}],"name":"setTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"targetCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryAddress","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
6080604052600a600e565b60cb565b600054610100900460ff161560795760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161460c9576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6131e4806100da6000396000f3fe6080604052600436106102fe5760003560e01c80638456cb5911610190578063c0bf8167116100dc578063e30c397811610095578063edb594fc1161006f578063edb594fc146108c8578063f0e35a9a146108e8578063f2fde38b14610908578063fba9402f1461092857600080fd5b8063e30c397814610878578063e780789714610896578063e93c4f15146108b357600080fd5b8063c0bf8167146107b6578063c235fb14146107d6578063c47f0027146107f7578063c5f956af14610817578063c6e6f59214610838578063cea6443a1461085857600080fd5b806396c8d48e11610149578063b0e21e8a11610123578063b0e21e8a14610757578063b3cdfce11461077f578063b68ef559146106e3578063c059a38e1461079f57600080fd5b806396c8d48e146106f85780639b2cb5d814610720578063a45b208a1461073757600080fd5b80638456cb591461064f578063897b0637146106645780638da5cb5b146106845780638e29ebb5146106a257806390fed28d146106c35780639669c7cf146106e357600080fd5b80634a6b629d1161024f5780636ba176c71161020857806371ca337d116101e257806371ca337d146105e4578063779a6cdd146105f957806379ba50971461061a5780638239bbba1461062f57600080fd5b80636ba176c71461058f5780636e553f65146105af578063715018a6146105cf57600080fd5b80634a6b629d146104d2578063570ca735146104e95780635c975abb1461050a5780636605bfda1461052d57806367ea18a01461054d5780636a1ae0531461056e57600080fd5b80631f2ed36f116102bc57806338d52e0f1161029657806338d52e0f146104435780633f4ba83a1461047557806343bc42d31461048a5780634886a957146104aa57600080fd5b80631f2ed36f146103e85780632c260f9b1461041057806335c16b401461043057600080fd5b80629289171461030357806301e1d1141461034857806306fdde031461036b57806307a2d13a1461038d5780630b885ac3146103ad5780631036bbe2146103cf575b600080fd5b34801561030f57600080fd5b506101365461032b90600160c01b90046001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b34801561035457600080fd5b5061035d61093b565b60405190815260200161033f565b34801561037757600080fd5b506103806109ae565b60405161033f9190612b6e565b34801561039957600080fd5b5061035d6103a8366004612b81565b610a3d565b3480156103b957600080fd5b506103cd6103c8366004612c5d565b610a5f565b005b3480156103db57600080fd5b5061035d6402540be40081565b3480156103f457600080fd5b506101365461032b90600160401b90046001600160401b031681565b34801561041c57600080fd5b506103cd61042b366004612b81565b610b7f565b6103cd61043e366004612ce6565b610beb565b34801561044f57600080fd5b5060fb546001600160a01b03165b6040516001600160a01b03909116815260200161033f565b34801561048157600080fd5b506103cd610e1d565b34801561049657600080fd5b506103cd6104a5366004612d4a565b610e2f565b3480156104b657600080fd5b506101365461032b90600160801b90046001600160401b031681565b3480156104de57600080fd5b5061035d6101345481565b3480156104f557600080fd5b506101305461045d906001600160a01b031681565b34801561051657600080fd5b5060335460ff16604051901515815260200161033f565b34801561053957600080fd5b506103cd610548366004612d65565b610eed565b34801561055957600080fd5b506101325461045d906001600160a01b031681565b34801561057a57600080fd5b506101375461032b906001600160401b031681565b34801561059b57600080fd5b5061035d6105aa366004612b81565b610f7a565b3480156105bb57600080fd5b5061035d6105ca366004612d82565b610fdd565b3480156105db57600080fd5b506103cd611006565b3480156105f057600080fd5b5061035d611018565b34801561060557600080fd5b506101365461032b906001600160401b031681565b34801561062657600080fd5b506103cd611053565b34801561063b57600080fd5b506103cd61064a366004612db2565b6110cd565b34801561065b57600080fd5b506103cd6112d7565b34801561067057600080fd5b506103cd61067f366004612b81565b6112e7565b34801561069057600080fd5b506097546001600160a01b031661045d565b3480156106ae57600080fd5b506101315461045d906001600160a01b031681565b3480156106cf57600080fd5b506103cd6106de366004612d82565b611332565b3480156106ef57600080fd5b5061035d61154a565b34801561070457600080fd5b506101375461032b90600160401b90046001600160401b031681565b34801561072c57600080fd5b5061035d61012e5481565b34801561074357600080fd5b5061035d610752366004612ce6565b611562565b34801561076357600080fd5b506101355461032b90600160a01b90046001600160401b031681565b34801561078b57600080fd5b506103cd61079a366004612db2565b611651565b3480156107ab57600080fd5b5061035d6101335481565b3480156107c257600080fd5b5061035d6107d1366004612b81565b611852565b3480156107e257600080fd5b5061012d5461045d906001600160a01b031681565b34801561080357600080fd5b506103cd610812366004612df5565b6118ed565b34801561082357600080fd5b506101355461045d906001600160a01b031681565b34801561084457600080fd5b5061035d610853366004612b81565b61195f565b34801561086457600080fd5b5061035d610873366004612b81565b61197b565b34801561088457600080fd5b5060c9546001600160a01b031661045d565b3480156108a257600080fd5b5061035d68056bc75e2d6310000081565b3480156108bf57600080fd5b5061035d611a17565b3480156108d457600080fd5b5061035d6108e3366004612e29565b611a3c565b3480156108f457600080fd5b506103cd610903366004612d65565b611a92565b34801561091457600080fd5b506103cd610923366004612d65565b611b2c565b6103cd610936366004612b81565b611b9d565b60fb546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a99190612e61565b905090565b61012f80546109bc90612e7a565b80601f01602080910402602001604051908101604052809291908181526020018280546109e890612e7a565b8015610a355780601f10610a0a57610100808354040283529160200191610a35565b820191906000526020600020905b815481529060010190602001808311610a1857829003601f168201915b505050505081565b6000610a5982670de0b6b3a7640000610a54611018565b611ce9565b92915050565b600054610100900460ff1615808015610a7f5750600054600160ff909116105b80610a995750303b158015610a99575060005460ff166001145b610b015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610b24576000805461ff0019166101001790555b610b318686868686611d2e565b8015610b77576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b610b87611e13565b80600003610ba85760405163a22b4cd760e01b815260040160405180910390fd5b6101345460408051918252602082018390527fbf127022ae43ce46c7042f13c6e64c507f75f20314c2aee1b03b0cf208a10f39910160405180910390a161013455565b6097546001600160a01b03163314801590610c125750610130546001600160a01b03163314155b15610c305760405163089b7a0760e41b815260040160405180910390fd5b610132546001600160a01b0316610c5a5760405163280fa2b360e21b815260040160405180910390fd5b346000610c65611e6d565b90506000610c7161154a565b60408051426020820152908101849052606081018290529091506000906080016040516020818303038152906040529050610cab85611562565b8410158490610cd05760405163c539f6fd60e01b8152600401610af891815260200190565b506101325460405163afba65a160e01b81526000916001600160a01b03169063afba65a1908790610d079086908b90600401612eb4565b60206040518083038185885af1158015610d25573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610d4a9190612e61565b90506000610d588287612eef565b90508015610de757604051600090339083908381818185875af1925050503d8060008114610da2576040519150601f19603f3d011682016040523d82523d6000602084013e610da7565b606091505b505090508015610de5576040518281527f7093420f1fc6637579d9eef92e6aa786340ce1f8b17fdb88f730b486479412739060200160405180910390a15b505b604051849086907fcbaf5895b96fa8e4e261bfb479452a788f800e8756f2672b7d3c6b04694621f790600090a350505050505050565b610e25611e13565b610e2d611eb8565b565b610e37611e13565b6402540be400816001600160401b031610610e7057604051630513fb8f60e31b81526001600160401b0382166004820152602401610af8565b61013554604080516001600160401b03600160a01b9093048316815291831660208301527fb51bef650ff5ad43303dbe2e500a74d4fd1bdc9ae05f046bece330e82ae0ba87910160405180910390a161013580546001600160401b03909216600160a01b0267ffffffffffffffff60a01b19909216919091179055565b610ef5611e13565b6001600160a01b038116610f1c5760405163a22b4cd760e01b815260040160405180910390fd5b610135546040516001600160a01b038084169216907f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a90600090a361013580546001600160a01b0319166001600160a01b0392909216919091179055565b6000610a5982610f8861154a565b61013654610134546402540be40091610fb291600160801b9091046001600160401b031690612f02565b610fbc9190612f2f565b61013654610134546001600160401b03600160401b83048116921690611f0a565b6000610fe761206b565b610fef6120c4565b610ffa83338461210a565b9050610a596001606555565b61100e611e13565b610e2d60006122c4565b6101315461012d5460405163a1f1d48d60e01b81526001600160a01b039182166004820152600092919091169063a1f1d48d90602401610968565b60c95433906001600160a01b031681146110c15760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610af8565b6110ca816122c4565b50565b6110d5611e13565b6402540be400836001600160401b0316111561110f57604051630513fb8f60e31b81526001600160401b0384166004820152602401610af8565b6402540be400826001600160401b0316111561114957604051630513fb8f60e31b81526001600160401b0383166004820152602401610af8565b6402540be400816001600160401b0316111561118357604051630513fb8f60e31b81526001600160401b0382166004820152602401610af8565b610136546001600160401b0390811690841610156111bf57604051630c9edf0b60e21b81526001600160401b0384166004820152602401610af8565b610136546001600160401b03600160401b9091048116908316101561120257604051630c9edf0b60e21b81526001600160401b0383166004820152602401610af8565b610136546001600160401b03600160801b9091048116908216101561124557604051630c9edf0b60e21b81526001600160401b0382166004820152602401610af8565b61013680546001600160c01b0316600160c01b6001600160401b038681169182029290921790925561013780548583166001600160801b03199091168117600160401b938616938402179091556040805193845260208401919091528201527fdf581e326481322cb561c04ad7b524314bfe80a9d0a418461dbd65c6c1c39e2c906060015b60405180910390a1505050565b6112df611e13565b610e2d6122dd565b6112ef611e13565b61012e5460408051918252602082018390527f633c1a71f1236c727d460906a677e5c96556b3f5ad34c9b64072540f1c2eddea910160405180910390a161012e55565b61133a6120c4565b61134261206b565b61134c818361231a565b336000611357611018565b9050600061136e85670de0b6b3a764000084611ce9565b9050600061137a61154a565b905061012e548210156113a75761012e5460405163279dbb3d60e11b8152600401610af891815260200190565b808211156113cb57604051636688dd2d60e11b815260048101829052602401610af8565b61012d54604051632770a7eb60e21b81526001600160a01b0386811660048301526024820189905290911690639dc29fac90604401600060405180830381600087803b15801561141a57600080fd5b505af115801561142e573d6000803e3d6000fd5b50505050600061143d8361197b565b90508060000361146057604051636a21a0e160e11b815260040160405180910390fd5b61146a8184612eef565b610135549093506000906402540be4009061149590600160a01b90046001600160401b031684612f02565b61149f9190612f2f565b90506114ab8183612eef565b61013360008282546114bd9190612f43565b9091555050610135546114d9906001600160a01b031682612362565b6114e38785612362565b60408051858152602081018a90529081018390526001600160a01b03808816919089169082907f22b8f008297894112d5322d194442062aad3c25bbcdd07d2b0fa30a9e026e53c9060600160405180910390a45050505050506115466001606555565b5050565b60006101335461155861093b565b6109a99190612eef565b610132546000906001600160a01b031661158f5760405163280fa2b360e21b815260040160405180910390fd5b6000611599611e6d565b905060006115a561154a565b604080514260208201529081018490526060810182905290915060009060800160408051601f1981840301815290829052610132546341d88d6960e01b83529092506001600160a01b0316906341d88d69906116079084908990600401612eb4565b602060405180830381865afa158015611624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116489190612e61565b95945050505050565b611659611e13565b6402540be400836001600160401b0316111561169357604051630513fb8f60e31b81526001600160401b0384166004820152602401610af8565b6402540be400826001600160401b031611156116cd57604051630513fb8f60e31b81526001600160401b0383166004820152602401610af8565b6402540be400816001600160401b0316111561170757604051630513fb8f60e31b81526001600160401b0382166004820152602401610af8565b610136546001600160401b03600160c01b9091048116908416111561174a57604051630c9edf0b60e21b81526001600160401b0384166004820152602401610af8565b610137546001600160401b03908116908316111561178657604051630c9edf0b60e21b81526001600160401b0383166004820152602401610af8565b610137546001600160401b03600160401b909104811690821611156117c957604051630c9edf0b60e21b81526001600160401b0382166004820152602401610af8565b61013680546001600160401b03838116600160801b810267ffffffffffffffff60801b19878416600160401b81026001600160801b0319909616948a16948517959095171617909355604080519182526020820192909252908101919091527f66900954b1537bc8d2b5fe469c603d0d96f37cd974bfe0714b3b5f7d48ae15f3906060016112ca565b610132546000906001600160a01b031661187f5760405163280fa2b360e21b815260040160405180910390fd5b610132546040516317942ea760e31b8152600481018490526001600160a01b039091169063bca1753890602401602060405180830381865afa1580156118c9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a599190612e61565b6118f5611e13565b80516000036119175760405163a22b4cd760e01b815260040160405180910390fd5b7f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a61012f8260405161194a929190612f56565b60405180910390a161012f611546828261303a565b6000610a598261196d611018565b670de0b6b3a7640000611ce9565b60008061198661154a565b9050808311156119ac57604051636688dd2d60e11b815260048101829052602401610af8565b6101375461013454611a1091859184916402540be400916119dd91600160401b90046001600160401b031690612f02565b6119e79190612f2f565b6101375461013654610134546001600160401b0392831692600160c01b90920490911690612379565b9392505050565b600061013454611a2561154a565b10611a36576101345461155861154a565b50600090565b6000611a4661206b565b611a4e6120c4565b604051829033907fc7eedc3cf8cfad9a1c83fa8dafc30e8114f13deeb844dfe3ede8b8bbf24f793790600090a3611a8684338561210a565b9050611a106001606555565b611a9a611e13565b6001600160a01b038116611ac15760405163a22b4cd760e01b815260040160405180910390fd5b61013154604080516001600160a01b03928316815291831660208301527fdb29c30d5fa0d3da86f28fcd1e16611171e924d291c7ef82f03cffb0bfa05652910160405180910390a161013180546001600160a01b0319166001600160a01b0392909216919091179055565b611b34611e13565b60c980546001600160a01b0383166001600160a01b03199091168117909155611b656097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6097546001600160a01b03163314801590611bc45750610130546001600160a01b03163314155b15611be25760405163089b7a0760e41b815260040160405180910390fd5b6000611bec611a17565b9050611bf781611852565b8110158190611c1c5760405163c539f6fd60e01b8152600401610af891815260200190565b5061013254611c34906001600160a01b031682612518565b61013254604051631eb8d94160e31b8152600481018390526000916001600160a01b03169063f5c6ca08906024016020604051808303816000875af1158015611c81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca59190612e61565b9050827ff075481911df01f7464d999ae5652f1fcae85ddcdbc8ccf025bc659d72d9fcb5611cd38385612eef565b60405190815260200160405180910390a2505050565b6000611d26611d01611cfb8487612f2f565b856125ac565b8385611d0d82896130f8565b611d179190612f02565b611d219190612f2f565b6125e2565b949350505050565b611d366125fa565b611d3f82612629565b61012f611d4c868261303a565b5061013080546001600160a01b03199081166001600160a01b0396871617909155610135805461012d8054841696881696909617909555610132805490921692909516919091179055506305f5e10061012e556706f05b59d3b20000610134556001600160e01b0319163367ffffffffffffffff60a01b191617629502f960a91b1790555061013780547b11e1a300000000009502f90000000000017d78400000000008f0d180610136556001600160801b0319166b9502f9000000000002faf080179055565b6097546001600160a01b03163314610e2d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610af8565b61012d54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610985573d6000803e3d6000fd5b611ec0612682565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008087118015611f1a57508486105b15611fff5786611f2a8188612f43565b861015611f3e57611f3b8787612eef565b90505b600083611f5388670de0b6b3a7640000612f02565b611f5d9190612f2f565b611f678787612eef565b611f7990670de0b6b3a7640000612f02565b611f839190612f2f565b9050600084611f93600285612f2f565b611f9d908b612f43565b611fa79084612f02565b611fb19190612f2f565b611fbb9087612eef565b9050611fc7838a612f43565b98506402540be400611fd98285612f02565b611fe39190612f2f565b611fed9085612f43565b9350611ff9838b612eef565b99505050505b60008711801561200f5750818611155b156120615760006120208888612f43565b8311612035576120308784612eef565b612037565b875b90506402540be4006120498683612f02565b6120539190612f2f565b61205d9083612f43565b9150505b9695505050505050565b6002606554036120bd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610af8565b6002606555565b60335460ff1615610e2d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610af8565b600080612115611018565b905061212183866126cb565b600061212b61093b565b90506000806101335411156121ad5761214387610f7a565b905061013354811115612160575061013380546000909155612179565b8061013360008282546121739190612eef565b90915550505b6040518181527f077077dea12adfa76313c61094bf1bc51a7e07cba7ea862339145674988e8a079060200160405180910390a15b6121b7868861271d565b816121c061093b565b6121ca9190612eef565b965060006121ea6121db838a612f43565b85670de0b6b3a7640000611ce9565b61012d546040516340c10f1960e01b81526001600160a01b038981166004830152602482018490529293509116906340c10f1990604401600060405180830381600087803b15801561223b57600080fd5b505af115801561224f573d6000803e3d6000fd5b5050505061225c81612735565b856001600160a01b0316876001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d78a846040516122aa929190918252602082015260400190565b60405180910390a3979650505050505050565b6001606555565b60c980546001600160a01b03191690556110ca81612756565b6122e56120c4565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611eed3390565b8060000361233b5760405163a22b4cd760e01b815260040160405180910390fd5b6001600160a01b0382166115465760405163a22b4cd760e01b815260040160405180910390fd5b60fb54611546906001600160a01b031683836127a8565b6000808711801561238957508186115b156123c757868261239a8289612eef565b10156123ad576123aa8388612eef565b90505b6123b78189612eef565b97506123c38188612eef565b9650505b6000871180156123d657508486115b1561244e5786856123e78289612eef565b10156123fa576123f78688612eef565b90505b6402540be40061240a8683612f02565b6124149190612f2f565b61241e9083612f43565b915061242a8189612eef565b97506124368188612eef565b96508160000361244c576124498261310c565b91505b505b86156124fc5760008261246987670de0b6b3a7640000612f02565b6124739190612f2f565b61247d8686612eef565b61248f90670de0b6b3a7640000612f02565b6124999190612f2f565b90506000836124a960028b612f2f565b6124b3908a612eef565b6124bd9084612f02565b6124c79190612f2f565b6124d19086612eef565b90506402540be4006124e3828b612f02565b6124ed9190612f2f565b6124f79084612f43565b925050505b806000036120615761250d8161310c565b979650505050505050565b60fb5460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af115801561256b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258f9190613125565b611546576040516370a5391160e01b815260040160405180910390fd5b6000826000036125be57506000610a59565b828202828482816125d1576125d1612f19565b0414611a1057600019915050610a59565b600082820183811015611a1057600019915050610a59565b600054610100900460ff166126215760405162461bcd60e51b8152600401610af890613147565b610e2d612810565b600054610100900460ff166126505760405162461bcd60e51b8152600401610af890613147565b612658612840565b61266061286f565b60fb80546001600160a01b0319166001600160a01b0392909216919091179055565b60335460ff16610e2d5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610af8565b6001600160a01b0382166126f25760405163a22b4cd760e01b815260040160405180910390fd5b61012e548110156115465761012e5460405163279dbb3d60e11b8152600401610af891815260200190565b60fb54611546906001600160a01b031683308461289e565b806000036110ca5760405163fa86b6d160e01b815260040160405180910390fd5b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b03831660248201526044810182905261280b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526128dc565b505050565b600054610100900460ff166128375760405162461bcd60e51b8152600401610af890613147565b610e2d336122c4565b600054610100900460ff166128675760405162461bcd60e51b8152600401610af890613147565b610e2d6129b1565b600054610100900460ff166128965760405162461bcd60e51b8152600401610af890613147565b610e2d6129e4565b6040516001600160a01b03808516602483015283166044820152606481018290526128d69085906323b872dd60e01b906084016127d4565b50505050565b6000612931826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612a0b9092919063ffffffff16565b90508051600014806129525750808060200190518101906129529190613125565b61280b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610af8565b600054610100900460ff166129d85760405162461bcd60e51b8152600401610af890613147565b6033805460ff19169055565b600054610100900460ff166122bd5760405162461bcd60e51b8152600401610af890613147565b6060611d26848460008585600080866001600160a01b03168587604051612a329190613192565b60006040518083038185875af1925050503d8060008114612a6f576040519150601f19603f3d011682016040523d82523d6000602084013e612a74565b606091505b509150915061250d8783838760608315612aef578251600003612ae8576001600160a01b0385163b612ae85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610af8565b5081611d26565b611d268383815115612b045781518083602001fd5b8060405162461bcd60e51b8152600401610af89190612b6e565b60005b83811015612b39578181015183820152602001612b21565b50506000910152565b60008151808452612b5a816020860160208601612b1e565b601f01601f19169290920160200192915050565b602081526000611a106020830184612b42565b600060208284031215612b9357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806001600160401b03841115612bca57612bca612b9a565b50604051601f19601f85018116603f011681018181106001600160401b0382111715612bf857612bf8612b9a565b604052838152905080828401851015612c1057600080fd5b83836020830137600060208583010152509392505050565b600082601f830112612c3957600080fd5b611a1083833560208501612bb0565b6001600160a01b03811681146110ca57600080fd5b600080600080600060a08688031215612c7557600080fd5b85356001600160401b03811115612c8b57600080fd5b612c9788828901612c28565b9550506020860135612ca881612c48565b93506040860135612cb881612c48565b92506060860135612cc881612c48565b91506080860135612cd881612c48565b809150509295509295909350565b600060208284031215612cf857600080fd5b81356001600160401b03811115612d0e57600080fd5b8201601f81018413612d1f57600080fd5b611d2684823560208401612bb0565b80356001600160401b0381168114612d4557600080fd5b919050565b600060208284031215612d5c57600080fd5b611a1082612d2e565b600060208284031215612d7757600080fd5b8135611a1081612c48565b60008060408385031215612d9557600080fd5b823591506020830135612da781612c48565b809150509250929050565b600080600060608486031215612dc757600080fd5b612dd084612d2e565b9250612dde60208501612d2e565b9150612dec60408501612d2e565b90509250925092565b600060208284031215612e0757600080fd5b81356001600160401b03811115612e1d57600080fd5b611d2684828501612c28565b600080600060608486031215612e3e57600080fd5b833592506020840135612e5081612c48565b929592945050506040919091013590565b600060208284031215612e7357600080fd5b5051919050565b600181811c90821680612e8e57607f821691505b602082108103612eae57634e487b7160e01b600052602260045260246000fd5b50919050565b604081526000612ec76040830185612b42565b82810360208401526116488185612b42565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a5957610a59612ed9565b8082028115828204841417610a5957610a59612ed9565b634e487b7160e01b600052601260045260246000fd5b600082612f3e57612f3e612f19565b500490565b80820180821115610a5957610a59612ed9565b604081526000808454612f6881612e7a565b8060408601526001821660008114612f875760018114612fa357612fd7565b60ff1983166060870152606082151560051b8701019350612fd7565b87600052602060002060005b83811015612fce57815488820160600152600190910190602001612faf565b87016060019450505b50505082810360208401526116488185612b42565b601f82111561280b57806000526020600020601f840160051c810160208510156130135750805b601f840160051c820191505b81811015613033576000815560010161301f565b5050505050565b81516001600160401b0381111561305357613053612b9a565b613067816130618454612e7a565b84612fec565b6020601f82116001811461309b57600083156130835750848201515b600019600385901b1c1916600184901b178455613033565b600084815260208120601f198516915b828110156130cb57878501518255602094850194600190920191016130ab565b50848210156130e95786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60008261310757613107612f19565b500690565b60006001820161311e5761311e612ed9565b5060010190565b60006020828403121561313757600080fd5b81518015158114611a1057600080fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600082516131a4818460208701612b1e565b919091019291505056fea2646970667358221220129933b5414336a8f46f19e0ddc77f89d76135e6c2c847abc608fd2af948a5a864736f6c634300081b0033
Deployed Bytecode
0x6080604052600436106102fe5760003560e01c80638456cb5911610190578063c0bf8167116100dc578063e30c397811610095578063edb594fc1161006f578063edb594fc146108c8578063f0e35a9a146108e8578063f2fde38b14610908578063fba9402f1461092857600080fd5b8063e30c397814610878578063e780789714610896578063e93c4f15146108b357600080fd5b8063c0bf8167146107b6578063c235fb14146107d6578063c47f0027146107f7578063c5f956af14610817578063c6e6f59214610838578063cea6443a1461085857600080fd5b806396c8d48e11610149578063b0e21e8a11610123578063b0e21e8a14610757578063b3cdfce11461077f578063b68ef559146106e3578063c059a38e1461079f57600080fd5b806396c8d48e146106f85780639b2cb5d814610720578063a45b208a1461073757600080fd5b80638456cb591461064f578063897b0637146106645780638da5cb5b146106845780638e29ebb5146106a257806390fed28d146106c35780639669c7cf146106e357600080fd5b80634a6b629d1161024f5780636ba176c71161020857806371ca337d116101e257806371ca337d146105e4578063779a6cdd146105f957806379ba50971461061a5780638239bbba1461062f57600080fd5b80636ba176c71461058f5780636e553f65146105af578063715018a6146105cf57600080fd5b80634a6b629d146104d2578063570ca735146104e95780635c975abb1461050a5780636605bfda1461052d57806367ea18a01461054d5780636a1ae0531461056e57600080fd5b80631f2ed36f116102bc57806338d52e0f1161029657806338d52e0f146104435780633f4ba83a1461047557806343bc42d31461048a5780634886a957146104aa57600080fd5b80631f2ed36f146103e85780632c260f9b1461041057806335c16b401461043057600080fd5b80629289171461030357806301e1d1141461034857806306fdde031461036b57806307a2d13a1461038d5780630b885ac3146103ad5780631036bbe2146103cf575b600080fd5b34801561030f57600080fd5b506101365461032b90600160c01b90046001600160401b031681565b6040516001600160401b0390911681526020015b60405180910390f35b34801561035457600080fd5b5061035d61093b565b60405190815260200161033f565b34801561037757600080fd5b506103806109ae565b60405161033f9190612b6e565b34801561039957600080fd5b5061035d6103a8366004612b81565b610a3d565b3480156103b957600080fd5b506103cd6103c8366004612c5d565b610a5f565b005b3480156103db57600080fd5b5061035d6402540be40081565b3480156103f457600080fd5b506101365461032b90600160401b90046001600160401b031681565b34801561041c57600080fd5b506103cd61042b366004612b81565b610b7f565b6103cd61043e366004612ce6565b610beb565b34801561044f57600080fd5b5060fb546001600160a01b03165b6040516001600160a01b03909116815260200161033f565b34801561048157600080fd5b506103cd610e1d565b34801561049657600080fd5b506103cd6104a5366004612d4a565b610e2f565b3480156104b657600080fd5b506101365461032b90600160801b90046001600160401b031681565b3480156104de57600080fd5b5061035d6101345481565b3480156104f557600080fd5b506101305461045d906001600160a01b031681565b34801561051657600080fd5b5060335460ff16604051901515815260200161033f565b34801561053957600080fd5b506103cd610548366004612d65565b610eed565b34801561055957600080fd5b506101325461045d906001600160a01b031681565b34801561057a57600080fd5b506101375461032b906001600160401b031681565b34801561059b57600080fd5b5061035d6105aa366004612b81565b610f7a565b3480156105bb57600080fd5b5061035d6105ca366004612d82565b610fdd565b3480156105db57600080fd5b506103cd611006565b3480156105f057600080fd5b5061035d611018565b34801561060557600080fd5b506101365461032b906001600160401b031681565b34801561062657600080fd5b506103cd611053565b34801561063b57600080fd5b506103cd61064a366004612db2565b6110cd565b34801561065b57600080fd5b506103cd6112d7565b34801561067057600080fd5b506103cd61067f366004612b81565b6112e7565b34801561069057600080fd5b506097546001600160a01b031661045d565b3480156106ae57600080fd5b506101315461045d906001600160a01b031681565b3480156106cf57600080fd5b506103cd6106de366004612d82565b611332565b3480156106ef57600080fd5b5061035d61154a565b34801561070457600080fd5b506101375461032b90600160401b90046001600160401b031681565b34801561072c57600080fd5b5061035d61012e5481565b34801561074357600080fd5b5061035d610752366004612ce6565b611562565b34801561076357600080fd5b506101355461032b90600160a01b90046001600160401b031681565b34801561078b57600080fd5b506103cd61079a366004612db2565b611651565b3480156107ab57600080fd5b5061035d6101335481565b3480156107c257600080fd5b5061035d6107d1366004612b81565b611852565b3480156107e257600080fd5b5061012d5461045d906001600160a01b031681565b34801561080357600080fd5b506103cd610812366004612df5565b6118ed565b34801561082357600080fd5b506101355461045d906001600160a01b031681565b34801561084457600080fd5b5061035d610853366004612b81565b61195f565b34801561086457600080fd5b5061035d610873366004612b81565b61197b565b34801561088457600080fd5b5060c9546001600160a01b031661045d565b3480156108a257600080fd5b5061035d68056bc75e2d6310000081565b3480156108bf57600080fd5b5061035d611a17565b3480156108d457600080fd5b5061035d6108e3366004612e29565b611a3c565b3480156108f457600080fd5b506103cd610903366004612d65565b611a92565b34801561091457600080fd5b506103cd610923366004612d65565b611b2c565b6103cd610936366004612b81565b611b9d565b60fb546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a08231906024015b602060405180830381865afa158015610985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a99190612e61565b905090565b61012f80546109bc90612e7a565b80601f01602080910402602001604051908101604052809291908181526020018280546109e890612e7a565b8015610a355780601f10610a0a57610100808354040283529160200191610a35565b820191906000526020600020905b815481529060010190602001808311610a1857829003601f168201915b505050505081565b6000610a5982670de0b6b3a7640000610a54611018565b611ce9565b92915050565b600054610100900460ff1615808015610a7f5750600054600160ff909116105b80610a995750303b158015610a99575060005460ff166001145b610b015760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610b24576000805461ff0019166101001790555b610b318686868686611d2e565b8015610b77576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b610b87611e13565b80600003610ba85760405163a22b4cd760e01b815260040160405180910390fd5b6101345460408051918252602082018390527fbf127022ae43ce46c7042f13c6e64c507f75f20314c2aee1b03b0cf208a10f39910160405180910390a161013455565b6097546001600160a01b03163314801590610c125750610130546001600160a01b03163314155b15610c305760405163089b7a0760e41b815260040160405180910390fd5b610132546001600160a01b0316610c5a5760405163280fa2b360e21b815260040160405180910390fd5b346000610c65611e6d565b90506000610c7161154a565b60408051426020820152908101849052606081018290529091506000906080016040516020818303038152906040529050610cab85611562565b8410158490610cd05760405163c539f6fd60e01b8152600401610af891815260200190565b506101325460405163afba65a160e01b81526000916001600160a01b03169063afba65a1908790610d079086908b90600401612eb4565b60206040518083038185885af1158015610d25573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610d4a9190612e61565b90506000610d588287612eef565b90508015610de757604051600090339083908381818185875af1925050503d8060008114610da2576040519150601f19603f3d011682016040523d82523d6000602084013e610da7565b606091505b505090508015610de5576040518281527f7093420f1fc6637579d9eef92e6aa786340ce1f8b17fdb88f730b486479412739060200160405180910390a15b505b604051849086907fcbaf5895b96fa8e4e261bfb479452a788f800e8756f2672b7d3c6b04694621f790600090a350505050505050565b610e25611e13565b610e2d611eb8565b565b610e37611e13565b6402540be400816001600160401b031610610e7057604051630513fb8f60e31b81526001600160401b0382166004820152602401610af8565b61013554604080516001600160401b03600160a01b9093048316815291831660208301527fb51bef650ff5ad43303dbe2e500a74d4fd1bdc9ae05f046bece330e82ae0ba87910160405180910390a161013580546001600160401b03909216600160a01b0267ffffffffffffffff60a01b19909216919091179055565b610ef5611e13565b6001600160a01b038116610f1c5760405163a22b4cd760e01b815260040160405180910390fd5b610135546040516001600160a01b038084169216907f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a90600090a361013580546001600160a01b0319166001600160a01b0392909216919091179055565b6000610a5982610f8861154a565b61013654610134546402540be40091610fb291600160801b9091046001600160401b031690612f02565b610fbc9190612f2f565b61013654610134546001600160401b03600160401b83048116921690611f0a565b6000610fe761206b565b610fef6120c4565b610ffa83338461210a565b9050610a596001606555565b61100e611e13565b610e2d60006122c4565b6101315461012d5460405163a1f1d48d60e01b81526001600160a01b039182166004820152600092919091169063a1f1d48d90602401610968565b60c95433906001600160a01b031681146110c15760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610af8565b6110ca816122c4565b50565b6110d5611e13565b6402540be400836001600160401b0316111561110f57604051630513fb8f60e31b81526001600160401b0384166004820152602401610af8565b6402540be400826001600160401b0316111561114957604051630513fb8f60e31b81526001600160401b0383166004820152602401610af8565b6402540be400816001600160401b0316111561118357604051630513fb8f60e31b81526001600160401b0382166004820152602401610af8565b610136546001600160401b0390811690841610156111bf57604051630c9edf0b60e21b81526001600160401b0384166004820152602401610af8565b610136546001600160401b03600160401b9091048116908316101561120257604051630c9edf0b60e21b81526001600160401b0383166004820152602401610af8565b610136546001600160401b03600160801b9091048116908216101561124557604051630c9edf0b60e21b81526001600160401b0382166004820152602401610af8565b61013680546001600160c01b0316600160c01b6001600160401b038681169182029290921790925561013780548583166001600160801b03199091168117600160401b938616938402179091556040805193845260208401919091528201527fdf581e326481322cb561c04ad7b524314bfe80a9d0a418461dbd65c6c1c39e2c906060015b60405180910390a1505050565b6112df611e13565b610e2d6122dd565b6112ef611e13565b61012e5460408051918252602082018390527f633c1a71f1236c727d460906a677e5c96556b3f5ad34c9b64072540f1c2eddea910160405180910390a161012e55565b61133a6120c4565b61134261206b565b61134c818361231a565b336000611357611018565b9050600061136e85670de0b6b3a764000084611ce9565b9050600061137a61154a565b905061012e548210156113a75761012e5460405163279dbb3d60e11b8152600401610af891815260200190565b808211156113cb57604051636688dd2d60e11b815260048101829052602401610af8565b61012d54604051632770a7eb60e21b81526001600160a01b0386811660048301526024820189905290911690639dc29fac90604401600060405180830381600087803b15801561141a57600080fd5b505af115801561142e573d6000803e3d6000fd5b50505050600061143d8361197b565b90508060000361146057604051636a21a0e160e11b815260040160405180910390fd5b61146a8184612eef565b610135549093506000906402540be4009061149590600160a01b90046001600160401b031684612f02565b61149f9190612f2f565b90506114ab8183612eef565b61013360008282546114bd9190612f43565b9091555050610135546114d9906001600160a01b031682612362565b6114e38785612362565b60408051858152602081018a90529081018390526001600160a01b03808816919089169082907f22b8f008297894112d5322d194442062aad3c25bbcdd07d2b0fa30a9e026e53c9060600160405180910390a45050505050506115466001606555565b5050565b60006101335461155861093b565b6109a99190612eef565b610132546000906001600160a01b031661158f5760405163280fa2b360e21b815260040160405180910390fd5b6000611599611e6d565b905060006115a561154a565b604080514260208201529081018490526060810182905290915060009060800160408051601f1981840301815290829052610132546341d88d6960e01b83529092506001600160a01b0316906341d88d69906116079084908990600401612eb4565b602060405180830381865afa158015611624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116489190612e61565b95945050505050565b611659611e13565b6402540be400836001600160401b0316111561169357604051630513fb8f60e31b81526001600160401b0384166004820152602401610af8565b6402540be400826001600160401b031611156116cd57604051630513fb8f60e31b81526001600160401b0383166004820152602401610af8565b6402540be400816001600160401b0316111561170757604051630513fb8f60e31b81526001600160401b0382166004820152602401610af8565b610136546001600160401b03600160c01b9091048116908416111561174a57604051630c9edf0b60e21b81526001600160401b0384166004820152602401610af8565b610137546001600160401b03908116908316111561178657604051630c9edf0b60e21b81526001600160401b0383166004820152602401610af8565b610137546001600160401b03600160401b909104811690821611156117c957604051630c9edf0b60e21b81526001600160401b0382166004820152602401610af8565b61013680546001600160401b03838116600160801b810267ffffffffffffffff60801b19878416600160401b81026001600160801b0319909616948a16948517959095171617909355604080519182526020820192909252908101919091527f66900954b1537bc8d2b5fe469c603d0d96f37cd974bfe0714b3b5f7d48ae15f3906060016112ca565b610132546000906001600160a01b031661187f5760405163280fa2b360e21b815260040160405180910390fd5b610132546040516317942ea760e31b8152600481018490526001600160a01b039091169063bca1753890602401602060405180830381865afa1580156118c9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a599190612e61565b6118f5611e13565b80516000036119175760405163a22b4cd760e01b815260040160405180910390fd5b7f6c20b91d1723b78732eba64ff11ebd7966a6e4af568a00fa4f6b72c20f58b02a61012f8260405161194a929190612f56565b60405180910390a161012f611546828261303a565b6000610a598261196d611018565b670de0b6b3a7640000611ce9565b60008061198661154a565b9050808311156119ac57604051636688dd2d60e11b815260048101829052602401610af8565b6101375461013454611a1091859184916402540be400916119dd91600160401b90046001600160401b031690612f02565b6119e79190612f2f565b6101375461013654610134546001600160401b0392831692600160c01b90920490911690612379565b9392505050565b600061013454611a2561154a565b10611a36576101345461155861154a565b50600090565b6000611a4661206b565b611a4e6120c4565b604051829033907fc7eedc3cf8cfad9a1c83fa8dafc30e8114f13deeb844dfe3ede8b8bbf24f793790600090a3611a8684338561210a565b9050611a106001606555565b611a9a611e13565b6001600160a01b038116611ac15760405163a22b4cd760e01b815260040160405180910390fd5b61013154604080516001600160a01b03928316815291831660208301527fdb29c30d5fa0d3da86f28fcd1e16611171e924d291c7ef82f03cffb0bfa05652910160405180910390a161013180546001600160a01b0319166001600160a01b0392909216919091179055565b611b34611e13565b60c980546001600160a01b0383166001600160a01b03199091168117909155611b656097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6097546001600160a01b03163314801590611bc45750610130546001600160a01b03163314155b15611be25760405163089b7a0760e41b815260040160405180910390fd5b6000611bec611a17565b9050611bf781611852565b8110158190611c1c5760405163c539f6fd60e01b8152600401610af891815260200190565b5061013254611c34906001600160a01b031682612518565b61013254604051631eb8d94160e31b8152600481018390526000916001600160a01b03169063f5c6ca08906024016020604051808303816000875af1158015611c81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca59190612e61565b9050827ff075481911df01f7464d999ae5652f1fcae85ddcdbc8ccf025bc659d72d9fcb5611cd38385612eef565b60405190815260200160405180910390a2505050565b6000611d26611d01611cfb8487612f2f565b856125ac565b8385611d0d82896130f8565b611d179190612f02565b611d219190612f2f565b6125e2565b949350505050565b611d366125fa565b611d3f82612629565b61012f611d4c868261303a565b5061013080546001600160a01b03199081166001600160a01b0396871617909155610135805461012d8054841696881696909617909555610132805490921692909516919091179055506305f5e10061012e556706f05b59d3b20000610134556001600160e01b0319163367ffffffffffffffff60a01b191617629502f960a91b1790555061013780547b11e1a300000000009502f90000000000017d78400000000008f0d180610136556001600160801b0319166b9502f9000000000002faf080179055565b6097546001600160a01b03163314610e2d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610af8565b61012d54604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610985573d6000803e3d6000fd5b611ec0612682565b6033805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008087118015611f1a57508486105b15611fff5786611f2a8188612f43565b861015611f3e57611f3b8787612eef565b90505b600083611f5388670de0b6b3a7640000612f02565b611f5d9190612f2f565b611f678787612eef565b611f7990670de0b6b3a7640000612f02565b611f839190612f2f565b9050600084611f93600285612f2f565b611f9d908b612f43565b611fa79084612f02565b611fb19190612f2f565b611fbb9087612eef565b9050611fc7838a612f43565b98506402540be400611fd98285612f02565b611fe39190612f2f565b611fed9085612f43565b9350611ff9838b612eef565b99505050505b60008711801561200f5750818611155b156120615760006120208888612f43565b8311612035576120308784612eef565b612037565b875b90506402540be4006120498683612f02565b6120539190612f2f565b61205d9083612f43565b9150505b9695505050505050565b6002606554036120bd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610af8565b6002606555565b60335460ff1615610e2d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610af8565b600080612115611018565b905061212183866126cb565b600061212b61093b565b90506000806101335411156121ad5761214387610f7a565b905061013354811115612160575061013380546000909155612179565b8061013360008282546121739190612eef565b90915550505b6040518181527f077077dea12adfa76313c61094bf1bc51a7e07cba7ea862339145674988e8a079060200160405180910390a15b6121b7868861271d565b816121c061093b565b6121ca9190612eef565b965060006121ea6121db838a612f43565b85670de0b6b3a7640000611ce9565b61012d546040516340c10f1960e01b81526001600160a01b038981166004830152602482018490529293509116906340c10f1990604401600060405180830381600087803b15801561223b57600080fd5b505af115801561224f573d6000803e3d6000fd5b5050505061225c81612735565b856001600160a01b0316876001600160a01b03167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d78a846040516122aa929190918252602082015260400190565b60405180910390a3979650505050505050565b6001606555565b60c980546001600160a01b03191690556110ca81612756565b6122e56120c4565b6033805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611eed3390565b8060000361233b5760405163a22b4cd760e01b815260040160405180910390fd5b6001600160a01b0382166115465760405163a22b4cd760e01b815260040160405180910390fd5b60fb54611546906001600160a01b031683836127a8565b6000808711801561238957508186115b156123c757868261239a8289612eef565b10156123ad576123aa8388612eef565b90505b6123b78189612eef565b97506123c38188612eef565b9650505b6000871180156123d657508486115b1561244e5786856123e78289612eef565b10156123fa576123f78688612eef565b90505b6402540be40061240a8683612f02565b6124149190612f2f565b61241e9083612f43565b915061242a8189612eef565b97506124368188612eef565b96508160000361244c576124498261310c565b91505b505b86156124fc5760008261246987670de0b6b3a7640000612f02565b6124739190612f2f565b61247d8686612eef565b61248f90670de0b6b3a7640000612f02565b6124999190612f2f565b90506000836124a960028b612f2f565b6124b3908a612eef565b6124bd9084612f02565b6124c79190612f2f565b6124d19086612eef565b90506402540be4006124e3828b612f02565b6124ed9190612f2f565b6124f79084612f43565b925050505b806000036120615761250d8161310c565b979650505050505050565b60fb5460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044016020604051808303816000875af115801561256b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258f9190613125565b611546576040516370a5391160e01b815260040160405180910390fd5b6000826000036125be57506000610a59565b828202828482816125d1576125d1612f19565b0414611a1057600019915050610a59565b600082820183811015611a1057600019915050610a59565b600054610100900460ff166126215760405162461bcd60e51b8152600401610af890613147565b610e2d612810565b600054610100900460ff166126505760405162461bcd60e51b8152600401610af890613147565b612658612840565b61266061286f565b60fb80546001600160a01b0319166001600160a01b0392909216919091179055565b60335460ff16610e2d5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610af8565b6001600160a01b0382166126f25760405163a22b4cd760e01b815260040160405180910390fd5b61012e548110156115465761012e5460405163279dbb3d60e11b8152600401610af891815260200190565b60fb54611546906001600160a01b031683308461289e565b806000036110ca5760405163fa86b6d160e01b815260040160405180910390fd5b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b03831660248201526044810182905261280b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526128dc565b505050565b600054610100900460ff166128375760405162461bcd60e51b8152600401610af890613147565b610e2d336122c4565b600054610100900460ff166128675760405162461bcd60e51b8152600401610af890613147565b610e2d6129b1565b600054610100900460ff166128965760405162461bcd60e51b8152600401610af890613147565b610e2d6129e4565b6040516001600160a01b03808516602483015283166044820152606481018290526128d69085906323b872dd60e01b906084016127d4565b50505050565b6000612931826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612a0b9092919063ffffffff16565b90508051600014806129525750808060200190518101906129529190613125565b61280b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610af8565b600054610100900460ff166129d85760405162461bcd60e51b8152600401610af890613147565b6033805460ff19169055565b600054610100900460ff166122bd5760405162461bcd60e51b8152600401610af890613147565b6060611d26848460008585600080866001600160a01b03168587604051612a329190613192565b60006040518083038185875af1925050503d8060008114612a6f576040519150601f19603f3d011682016040523d82523d6000602084013e612a74565b606091505b509150915061250d8783838760608315612aef578251600003612ae8576001600160a01b0385163b612ae85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610af8565b5081611d26565b611d268383815115612b045781518083602001fd5b8060405162461bcd60e51b8152600401610af89190612b6e565b60005b83811015612b39578181015183820152602001612b21565b50506000910152565b60008151808452612b5a816020860160208601612b1e565b601f01601f19169290920160200192915050565b602081526000611a106020830184612b42565b600060208284031215612b9357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806001600160401b03841115612bca57612bca612b9a565b50604051601f19601f85018116603f011681018181106001600160401b0382111715612bf857612bf8612b9a565b604052838152905080828401851015612c1057600080fd5b83836020830137600060208583010152509392505050565b600082601f830112612c3957600080fd5b611a1083833560208501612bb0565b6001600160a01b03811681146110ca57600080fd5b600080600080600060a08688031215612c7557600080fd5b85356001600160401b03811115612c8b57600080fd5b612c9788828901612c28565b9550506020860135612ca881612c48565b93506040860135612cb881612c48565b92506060860135612cc881612c48565b91506080860135612cd881612c48565b809150509295509295909350565b600060208284031215612cf857600080fd5b81356001600160401b03811115612d0e57600080fd5b8201601f81018413612d1f57600080fd5b611d2684823560208401612bb0565b80356001600160401b0381168114612d4557600080fd5b919050565b600060208284031215612d5c57600080fd5b611a1082612d2e565b600060208284031215612d7757600080fd5b8135611a1081612c48565b60008060408385031215612d9557600080fd5b823591506020830135612da781612c48565b809150509250929050565b600080600060608486031215612dc757600080fd5b612dd084612d2e565b9250612dde60208501612d2e565b9150612dec60408501612d2e565b90509250925092565b600060208284031215612e0757600080fd5b81356001600160401b03811115612e1d57600080fd5b611d2684828501612c28565b600080600060608486031215612e3e57600080fd5b833592506020840135612e5081612c48565b929592945050506040919091013590565b600060208284031215612e7357600080fd5b5051919050565b600181811c90821680612e8e57607f821691505b602082108103612eae57634e487b7160e01b600052602260045260246000fd5b50919050565b604081526000612ec76040830185612b42565b82810360208401526116488185612b42565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a5957610a59612ed9565b8082028115828204841417610a5957610a59612ed9565b634e487b7160e01b600052601260045260246000fd5b600082612f3e57612f3e612f19565b500490565b80820180821115610a5957610a59612ed9565b604081526000808454612f6881612e7a565b8060408601526001821660008114612f875760018114612fa357612fd7565b60ff1983166060870152606082151560051b8701019350612fd7565b87600052602060002060005b83811015612fce57815488820160600152600190910190602001612faf565b87016060019450505b50505082810360208401526116488185612b42565b601f82111561280b57806000526020600020601f840160051c810160208510156130135750805b601f840160051c820191505b81811015613033576000815560010161301f565b5050505050565b81516001600160401b0381111561305357613053612b9a565b613067816130618454612e7a565b84612fec565b6020601f82116001811461309b57600083156130835750848201515b600019600385901b1c1916600184901b178455613033565b600084815260208120601f198516915b828110156130cb57878501518255602094850194600190920191016130ab565b50848210156130e95786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60008261310757613107612f19565b500690565b60006001820161311e5761311e612ed9565b5060010190565b60006020828403121561313757600080fd5b81518015158114611a1057600080fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600082516131a4818460208701612b1e565b919091019291505056fea2646970667358221220129933b5414336a8f46f19e0ddc77f89d76135e6c2c847abc608fd2af948a5a864736f6c634300081b0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.