Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 19580013 | 115 days ago | IN | 0 ETH | 0.01350833 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
LRTOracle
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; import { UtilLib } from "./utils/UtilLib.sol"; import { LRTConstants } from "./utils/LRTConstants.sol"; import { LRTConfigRoleChecker, ILRTConfig } from "./utils/LRTConfigRoleChecker.sol"; import { IRSETH } from "./interfaces/IRSETH.sol"; import { IPriceFetcher } from "./interfaces/IPriceFetcher.sol"; import { ILRTOracle } from "./interfaces/ILRTOracle.sol"; import { ILRTDepositPool } from "./interfaces/ILRTDepositPool.sol"; import { INodeDelegator } from "./interfaces/INodeDelegator.sol"; import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /// @title LRTOracle Contract /// @notice oracle contract that calculates the exchange rate of assets contract LRTOracle is ILRTOracle, LRTConfigRoleChecker, Initializable { error AssetOracleNotSupported(); mapping(address asset => address priceOracle) public override assetPriceOracle; modifier onlySupportedOracle(address asset) { if (assetPriceOracle[asset] == address(0)) { revert AssetOracleNotSupported(); } _; } uint256 public override rsETHPrice; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @dev Initializes the contract /// @param lrtConfigAddr LRT config address function initialize(address lrtConfigAddr) external initializer { UtilLib.checkNonZeroAddress(lrtConfigAddr); lrtConfig = ILRTConfig(lrtConfigAddr); emit UpdatedLRTConfig(lrtConfigAddr); } /*////////////////////////////////////////////////////////////// view functions //////////////////////////////////////////////////////////////*/ /// @notice Provides Asset/ETH exchange rate /// @dev reads from priceFetcher interface which may fetch price from any supported oracle /// @param asset the asset for which exchange rate is required /// @return assetPrice exchange rate of asset function getAssetPrice(address asset) public view onlySupportedOracle(asset) returns (uint256) { return IPriceFetcher(assetPriceOracle[asset]).getAssetPrice(asset); } /*////////////////////////////////////////////////////////////// write functions //////////////////////////////////////////////////////////////*/ /// @notice updates RSETH/ETH exchange rate /// @dev calculates based on stakedAsset value received from eigen layer function updateRSETHPrice() external { address rsETHTokenAddress = lrtConfig.rsETH(); uint256 rsEthSupply = IRSETH(rsETHTokenAddress).totalSupply(); if (rsEthSupply == 0) { rsETHPrice = 1 ether; return; } uint256 totalETHInPool; address lrtDepositPoolAddr = lrtConfig.getContract(LRTConstants.LRT_DEPOSIT_POOL); address[] memory supportedAssets = lrtConfig.getSupportedAssetList(); uint256 supportedAssetCount = supportedAssets.length; for (uint16 asset_idx; asset_idx < supportedAssetCount;) { address asset = supportedAssets[asset_idx]; uint256 assetER = getAssetPrice(asset); uint256 totalAssetAmt = ILRTDepositPool(lrtDepositPoolAddr).getTotalAssetDeposits(asset); totalETHInPool += totalAssetAmt * assetER; unchecked { ++asset_idx; } } rsETHPrice = totalETHInPool / rsEthSupply; } /// @dev add/update the price oracle of any asset /// @dev only onlyLRTAdmin is allowed /// @param asset asset address for which oracle price needs to be added/updated function updatePriceOracleFor(address asset, address priceOracle) external onlyLRTAdmin { UtilLib.checkNonZeroAddress(priceOracle); assetPriceOracle[asset] = priceOracle; emit AssetPriceOracleUpdate(asset, priceOracle); } }
// 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.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 v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// 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: BUSL-1.1 pragma solidity 0.8.21; interface ILRTConfig { // Errors error ValueAlreadyInUse(); error AssetAlreadySupported(); error AssetNotSupported(); error CallerNotLRTConfigAdmin(); error CallerNotLRTConfigManager(); error CallerNotLRTConfigOperator(); error CallerNotLRTConfigAllowedRole(string role); error CannotUpdateStrategyAsItHasFundsNDCFunds(address ndc, uint256 amount); error InvalidMaxRewardAmount(); // Events event SetToken(bytes32 key, address indexed tokenAddr); event SetContract(bytes32 key, address indexed contractAddr); event AddedNewSupportedAsset(address indexed asset, uint256 depositLimit); event RemovedSupportedAsset(address indexed asset); event AssetDepositLimitUpdate(address indexed asset, uint256 depositLimit); event AssetStrategyUpdate(address indexed asset, address indexed strategy); event SetRSETH(address indexed rsETH); event UpdateMaxRewardAmount(uint256 maxRewardAmount); // methods function rsETH() external view returns (address); function assetStrategy(address asset) external view returns (address); function isSupportedAsset(address asset) external view returns (bool); function getLSTToken(bytes32 tokenId) external view returns (address); function getContract(bytes32 contractId) external view returns (address); function getSupportedAssetList() external view returns (address[] memory); function depositLimitByAsset(address asset) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; interface ILRTDepositPool { //errors error TokenTransferFailed(); error InvalidAmountToDeposit(); error NotEnoughAssetToTransfer(); error MaximumDepositLimitReached(); error MaximumNodeDelegatorLimitReached(); error InvalidMaximumNodeDelegatorLimit(); error MinimumAmountToReceiveNotMet(); error NodeDelegatorNotFound(); error NodeDelegatorHasAssetBalance(address assetAddress, uint256 assetBalance); error NodeDelegatorHasETH(); //events event MaxNodeDelegatorLimitUpdated(uint256 maxNodeDelegatorLimit); event NodeDelegatorAddedinQueue(address[] nodeDelegatorContracts); event NodeDelegatorRemovedFromQueue(address nodeDelegatorContracts); event AssetDeposit( address indexed depositor, address indexed asset, uint256 depositAmount, uint256 rsethMintAmount, string referralId ); event ETHDeposit(address indexed depositor, uint256 depositAmount, uint256 rsethMintAmount, string referralId); event MinAmountToDepositUpdated(uint256 minAmountToDeposit); event ETHSwappedForLST(uint256 ethAmount, address indexed toAsset, uint256 returnAmount); function depositAsset( address asset, uint256 depositAmount, uint256 minRSETHAmountExpected, string calldata referralId ) external; function getSwapETHToAssetReturnAmount( address toAsset, uint256 ethAmountToSend ) external view returns (uint256 returnAmount); function getTotalAssetDeposits(address asset) external view returns (uint256); function getAssetCurrentLimit(address asset) external view returns (uint256); function getRsETHAmountToMint(address asset, uint256 depositAmount) external view returns (uint256); function addNodeDelegatorContractToQueue(address[] calldata nodeDelegatorContract) external; function transferAssetToNodeDelegator(uint256 ndcIndex, address asset, uint256 amount) external; function updateMaxNodeDelegatorLimit(uint256 maxNodeDelegatorLimit) external; function getNodeDelegatorQueue() external view returns (address[] memory); function getAssetDistributionData(address asset) external view returns ( uint256 assetLyingInDepositPool, uint256 assetLyingInNDCs, uint256 assetStakedInEigenLayer, uint256 assetUnstakingFromEigenLayer, uint256 assetLyingInConverter, uint256 assetLyingUnstakingVault ); function getETHDistributionData() external view returns ( uint256 ethLyingInDepositPool, uint256 ethLyingInNDCs, uint256 ethStakedInEigenLayer, uint256 ethUnstakingFromEigenLayer, uint256 ethLyingInConverter, uint256 ethLyingInUnstakingVault ); function isNodeDelegator(address nodeDelegatorContract) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; interface ILRTOracle { // events event AssetPriceOracleUpdate(address indexed asset, address indexed priceOracle); // methods function getAssetPrice(address asset) external view returns (uint256); function assetPriceOracle(address asset) external view returns (address); function rsETHPrice() external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; import "./IStrategy.sol"; interface INodeDelegator { // event event AssetDepositIntoStrategy(address indexed asset, address indexed strategy, uint256 depositAmount); event ETHDepositFromDepositPool(uint256 depositAmount); event EigenPodCreated(address indexed eigenPod, address indexed podOwner); event ETHStaked(bytes valPubKey, uint256 amount); event ETHExitValidatorsReceived(uint256 amount); event ETHExtraStakeReceived(uint256 amount); event ETHRewardsReceived(uint256 amount); event WithdrawalQueued(uint96 nonce, address withdrawer, bytes32 withdrawalRoot); event NativeETHWithdrawInitiated(uint256 amount); event EthTransferred(address to, uint256 amount); event ETHExtraStakeToReceiveIncremented(uint256 amount); event ETHExitValidatorsToReceiveIncremented(uint256 amount); // errors error TokenTransferFailed(); error StrategyIsNotSetForAsset(); error InvalidETHSender(); error InvalidDepositRoot(bytes32 expectedDepositRoot, bytes32 actualDepositRoot); error StrategyIsNotPresentInStakerStrategyList(); error StrategyMustNotBeBeaconChain(); error AssetLengthMustBeOne(); error InsufficientStakedButUnverifiedNativeETH(); // getter function stakedButUnverifiedNativeETH() external view returns (uint256); // write functions function depositAssetIntoStrategy(address asset) external; function maxApproveToEigenStrategyManager(address asset) external; function initiateUnstaking( uint256[] calldata strategyIndexes, IStrategy[] calldata strategyArray, uint256[] calldata shareAmounts ) external returns (bytes32 withdrawalRoot); // view functions function getAssetBalances() external view returns (address[] memory, uint256[] memory); function getAssetBalance(address asset) external view returns (uint256); function getETHEigenPodBalance() external view returns (uint256); function ethToStake() external view returns (uint256); function transferBackToLRTDepositPool(address asset, uint256 amount) external; function sendETHFromDepositPoolToNDC() external payable; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; interface IPriceFetcher { function getAssetPrice(address asset) external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; interface IRSETH is IERC20 { function mint(address account, uint256 amount) external; function burnFrom(address account, uint256 amount) external; function pause() external; function unpause() external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @title Minimal interface for an `Strategy` contract. * @author Layr Labs, Inc. * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service * @notice Custom `Strategy` implementations may expand extensively on this interface. */ interface IStrategy { // packed struct for queued withdrawals; helps deal with stack-too-deep errors struct WithdrawerAndNonce { address withdrawer; uint96 nonce; } struct QueuedWithdrawal { IStrategy[] strategies; uint256[] shares; address depositor; WithdrawerAndNonce withdrawerAndNonce; uint32 withdrawalStartBlock; address delegatedAddress; } /** * @notice Used to deposit tokens into this Strategy * @param token is the ERC20 token being deposited * @param amount is the amount of token being deposited * @dev This function is only callable by the strategyManager contract. It is invoked inside of the * strategyManager's * `depositIntoStrategy` function, and individual share balances are recorded in the strategyManager as well. * @return newShares is the number of new shares issued at the current exchange ratio. */ function deposit(IERC20 token, uint256 amount) external returns (uint256); /** * @notice Used to withdraw tokens from this Strategy, to the `depositor`'s address * @param depositor is the address to receive the withdrawn funds * @param token is the ERC20 token being transferred out * @param amountShares is the amount of shares being withdrawn * @dev This function is only callable by the strategyManager contract. It is invoked inside of the * strategyManager's * other functions, and individual share balances are recorded in the strategyManager as well. */ function withdraw(address depositor, IERC20 token, uint256 amountShares) external; /** * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy. * @notice In contrast to `sharesToUnderlyingView`, this function **may** make state modifications * @param amountShares is the amount of shares to calculate its conversion into the underlying token * @return The amount of underlying tokens corresponding to the input `amountShares` * @dev Implementation for these functions in particular may vary significantly for different strategies */ function sharesToUnderlying(uint256 amountShares) external returns (uint256); /** * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy. * @notice In contrast to `underlyingToSharesView`, this function **may** make state modifications * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares * @return The amount of underlying tokens corresponding to the input `amountShares` * @dev Implementation for these functions in particular may vary significantly for different strategies */ function underlyingToShares(uint256 amountUnderlying) external returns (uint256); /** * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in * this strategy. In contrast to `userUnderlyingView`, this function **may** make state modifications */ function userUnderlying(address user) external returns (uint256); /** * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy. * @notice In contrast to `sharesToUnderlying`, this function guarantees no state modifications * @param amountShares is the amount of shares to calculate its conversion into the underlying token * @return The amount of shares corresponding to the input `amountUnderlying` * @dev Implementation for these functions in particular may vary significantly for different strategies */ function sharesToUnderlyingView(uint256 amountShares) external view returns (uint256); /** * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy. * @notice In contrast to `underlyingToShares`, this function guarantees no state modifications * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares * @return The amount of shares corresponding to the input `amountUnderlying` * @dev Implementation for these functions in particular may vary significantly for different strategies */ function underlyingToSharesView(uint256 amountUnderlying) external view returns (uint256); /** * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in * this strategy. In contrast to `userUnderlying`, this function guarantees no state modifications */ function userUnderlyingView(address user) external view returns (uint256); /// @notice The underlying token for shares in this Strategy function underlyingToken() external view returns (IERC20); /// @notice The total number of extant shares in this Strategy function totalShares() external view returns (uint256); /// @notice Returns either a brief string explaining the strategy's goal & purpose, or a link to metadata that /// explains in more detail. function explanation() external view returns (string memory); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; import { UtilLib } from "./UtilLib.sol"; import { LRTConstants } from "./LRTConstants.sol"; import { ILRTConfig } from "../interfaces/ILRTConfig.sol"; import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; /// @title LRTConfigRoleChecker - LRT Config Role Checker Contract /// @notice Handles LRT config role checks abstract contract LRTConfigRoleChecker { ILRTConfig public lrtConfig; // events event UpdatedLRTConfig(address indexed lrtConfig); // modifiers modifier onlyRole(bytes32 role) { if (!IAccessControl(address(lrtConfig)).hasRole(role, msg.sender)) { string memory roleStr = string(abi.encodePacked(role)); revert ILRTConfig.CallerNotLRTConfigAllowedRole(roleStr); } _; } modifier onlyLRTManager() { if (!IAccessControl(address(lrtConfig)).hasRole(LRTConstants.MANAGER, msg.sender)) { revert ILRTConfig.CallerNotLRTConfigManager(); } _; } modifier onlyLRTOperator() { if (!IAccessControl(address(lrtConfig)).hasRole(LRTConstants.OPERATOR_ROLE, msg.sender)) { revert ILRTConfig.CallerNotLRTConfigOperator(); } _; } modifier onlyLRTAdmin() { if (!IAccessControl(address(lrtConfig)).hasRole(LRTConstants.DEFAULT_ADMIN_ROLE, msg.sender)) { revert ILRTConfig.CallerNotLRTConfigAdmin(); } _; } modifier onlySupportedAsset(address asset) { if (!lrtConfig.isSupportedAsset(asset)) { revert ILRTConfig.AssetNotSupported(); } _; } // setters /// @notice Updates the LRT config contract /// @dev only callable by LRT admin /// @param lrtConfigAddr the new LRT config contract Address function updateLRTConfig(address lrtConfigAddr) external virtual onlyLRTAdmin { if (address(lrtConfig) != address(0)) revert ILRTConfig.ValueAlreadyInUse(); UtilLib.checkNonZeroAddress(lrtConfigAddr); lrtConfig = ILRTConfig(lrtConfigAddr); emit UpdatedLRTConfig(lrtConfigAddr); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; library LRTConstants { //tokens //rETH token bytes32 public constant R_ETH_TOKEN = keccak256("R_ETH_TOKEN"); //stETH token bytes32 public constant ST_ETH_TOKEN = keccak256("ST_ETH_TOKEN"); //cbETH token bytes32 public constant CB_ETH_TOKEN = keccak256("CB_ETH_TOKEN"); //ETHX token bytes32 public constant ETHX_TOKEN = keccak256("ETHX_TOKEN"); //sfrxETH bytes32 public constant SFRX_ETH_TOKEN = keccak256("SFRX_ETH_TOKEN"); //nativeETH this is used to represent ETH bytes32 public constant NATIVE_ETH = keccak256("NATIVE_ETH"); bytes32 public constant BEACON_CHAIN_ETH_STRATEGY = keccak256("BEACON_CHAIN_ETH_STRATEGY"); //contracts bytes32 public constant LRT_ORACLE = keccak256("LRT_ORACLE"); bytes32 public constant LRT_DEPOSIT_POOL = keccak256("LRT_DEPOSIT_POOL"); bytes32 public constant LRT_WITHDRAW_MANAGER = keccak256("LRT_WITHDRAW_MANAGER"); bytes32 public constant LRT_UNSTAKING_VAULT = keccak256("LRT_UNSTAKING_VAULT"); bytes32 public constant LRT_CONVERTER = keccak256("LRT_CONVERTER"); bytes32 public constant EIGEN_STRATEGY_MANAGER = keccak256("EIGEN_STRATEGY_MANAGER"); //Roles bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; bytes32 public constant MANAGER = keccak256("MANAGER"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); // updated library variables bytes32 public constant SFRXETH_TOKEN = keccak256("SFRXETH_TOKEN"); // add new vars below bytes32 public constant EIGEN_POD_MANAGER = keccak256("EIGEN_POD_MANAGER"); // native ETH as ERC20 for ease of implementation address public constant ETH_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // Operator Role bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); // reward receiver contract bytes32 public constant REWARD_RECEIVER = keccak256("REWARD_RECEIVER"); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.21; /// @title UtilLib - Utility library /// @notice Utility functions library UtilLib { error ZeroAddressNotAllowed(); /// @dev zero address check modifier /// @param address_ address to check function checkNonZeroAddress(address address_) internal pure { if (address_ == address(0)) revert ZeroAddressNotAllowed(); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AssetOracleNotSupported","type":"error"},{"inputs":[],"name":"CallerNotLRTConfigAdmin","type":"error"},{"inputs":[],"name":"ValueAlreadyInUse","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"priceOracle","type":"address"}],"name":"AssetPriceOracleUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lrtConfig","type":"address"}],"name":"UpdatedLRTConfig","type":"event"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"assetPriceOracle","outputs":[{"internalType":"address","name":"priceOracle","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getAssetPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lrtConfigAddr","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lrtConfig","outputs":[{"internalType":"contract ILRTConfig","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rsETHPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lrtConfigAddr","type":"address"}],"name":"updateLRTConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"priceOracle","type":"address"}],"name":"updatePriceOracleFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateRSETHPrice","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001961001e565b6100ea565b600054600160a81b900460ff161561008c5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b600054600160a01b900460ff908116146100e8576000805460ff60a01b191660ff60a01b17905560405160ff81527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b610b01806100f96000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b3596f071161005b578063b3596f0714610103578063b4b4643414610124578063c4d66de81461012d578063f1650a461461014057600080fd5b806310e50dfa1461008d57806315864e0a146100a257806351ce226a146100b5578063903e8c61146100bd575b600080fd5b6100a061009b3660046108b4565b610153565b005b6100a06100b03660046108ed565b610243565b6100a061034e565b6100e66100cb3660046108ed565b6001602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101166101113660046108ed565b61063d565b6040519081526020016100fa565b61011660025481565b6100a061013b3660046108ed565b6106fe565b6000546100e6906001600160a01b031681565b60008054604051632474521560e21b815260048101929092523360248301526001600160a01b0316906391d1485490604401602060405180830381865afa1580156101a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c6919061090a565b6101e3576040516305924c7d60e21b815260040160405180910390fd5b6101ec81610875565b6001600160a01b0382811660008181526001602052604080822080546001600160a01b0319169486169485179055517f72ac677bb38d8bb6988cfebe29d6caef19753725c2dc2c54edc2c22ed79dcaa69190a35050565b60008054604051632474521560e21b815260048101929092523360248301526001600160a01b0316906391d1485490604401602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061090a565b6102d3576040516305924c7d60e21b815260040160405180910390fd5b6000546001600160a01b0316156102fd576040516318e6d51960e01b815260040160405180910390fd5b61030681610875565b600080546001600160a01b0319166001600160a01b038316908117825560405190917f9cf19cefd9aab739c33b95716ee3f3f921f219dc6d7aae25e1f9497b3788915091a250565b60008060009054906101000a90046001600160a01b03166001600160a01b031662b83bce6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c5919061093c565b90506000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042b9190610959565b905080600003610445575050670de0b6b3a7640000600255565b60008054604051631c2d8fb360e31b81527f7a8fe1bac8d7638862c53b62ffada56d0a56c381287c35f66503b5b86fa88b85600482015282916001600160a01b03169063e16c7d9890602401602060405180830381865afa1580156104ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d2919061093c565b905060008060009054906101000a90046001600160a01b03166001600160a01b031663770672a66040518163ffffffff1660e01b8152600401600060405180830381865afa158015610528573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105509190810190610988565b805190915060005b818161ffff161015610627576000838261ffff168151811061057c5761057c610a4d565b6020026020010151905060006105918261063d565b6040516352c4889f60e01b81526001600160a01b0384811660048301529192506000918816906352c4889f90602401602060405180830381865afa1580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610959565b905061060d8282610a79565b6106179089610a96565b9750836001019350505050610558565b506106328585610aa9565b600255505050505050565b6001600160a01b0380821660009081526001602052604081205490918391166106795760405163762798e160e01b815260040160405180910390fd5b6001600160a01b038381166000818152600160205260409081902054905163b3596f0760e01b815260048101929092529091169063b3596f0790602401602060405180830381865afa1580156106d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f79190610959565b9392505050565b600054600160a81b900460ff161580801561072657506000546001600160a01b90910460ff16105b806107475750303b1580156107475750600054600160a01b900460ff166001145b6107ae5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff60a01b1916600160a01b17905580156107db576000805460ff60a81b1916600160a81b1790555b6107e482610875565b600080546001600160a01b0319166001600160a01b038416908117825560405190917f9cf19cefd9aab739c33b95716ee3f3f921f219dc6d7aae25e1f9497b3788915091a28015610871576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03811661089c576040516342bcdf7f60e11b815260040160405180910390fd5b50565b6001600160a01b038116811461089c57600080fd5b600080604083850312156108c757600080fd5b82356108d28161089f565b915060208301356108e28161089f565b809150509250929050565b6000602082840312156108ff57600080fd5b81356106f78161089f565b60006020828403121561091c57600080fd5b815180151581146106f757600080fd5b80516109378161089f565b919050565b60006020828403121561094e57600080fd5b81516106f78161089f565b60006020828403121561096b57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561099b57600080fd5b825167ffffffffffffffff808211156109b357600080fd5b818501915085601f8301126109c757600080fd5b8151818111156109d9576109d9610972565b8060051b604051601f19603f830116810181811085821117156109fe576109fe610972565b604052918252848201925083810185019188831115610a1c57600080fd5b938501935b82851015610a4157610a328561092c565b84529385019392850192610a21565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a9057610a90610a63565b92915050565b80820180821115610a9057610a90610a63565b600082610ac657634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220ea458048d24ace84614b8f924471a1779beec89121ff6c983ed0dd018f58e0fe64736f6c63430008150033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063b3596f071161005b578063b3596f0714610103578063b4b4643414610124578063c4d66de81461012d578063f1650a461461014057600080fd5b806310e50dfa1461008d57806315864e0a146100a257806351ce226a146100b5578063903e8c61146100bd575b600080fd5b6100a061009b3660046108b4565b610153565b005b6100a06100b03660046108ed565b610243565b6100a061034e565b6100e66100cb3660046108ed565b6001602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101166101113660046108ed565b61063d565b6040519081526020016100fa565b61011660025481565b6100a061013b3660046108ed565b6106fe565b6000546100e6906001600160a01b031681565b60008054604051632474521560e21b815260048101929092523360248301526001600160a01b0316906391d1485490604401602060405180830381865afa1580156101a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c6919061090a565b6101e3576040516305924c7d60e21b815260040160405180910390fd5b6101ec81610875565b6001600160a01b0382811660008181526001602052604080822080546001600160a01b0319169486169485179055517f72ac677bb38d8bb6988cfebe29d6caef19753725c2dc2c54edc2c22ed79dcaa69190a35050565b60008054604051632474521560e21b815260048101929092523360248301526001600160a01b0316906391d1485490604401602060405180830381865afa158015610292573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b6919061090a565b6102d3576040516305924c7d60e21b815260040160405180910390fd5b6000546001600160a01b0316156102fd576040516318e6d51960e01b815260040160405180910390fd5b61030681610875565b600080546001600160a01b0319166001600160a01b038316908117825560405190917f9cf19cefd9aab739c33b95716ee3f3f921f219dc6d7aae25e1f9497b3788915091a250565b60008060009054906101000a90046001600160a01b03166001600160a01b031662b83bce6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c5919061093c565b90506000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042b9190610959565b905080600003610445575050670de0b6b3a7640000600255565b60008054604051631c2d8fb360e31b81527f7a8fe1bac8d7638862c53b62ffada56d0a56c381287c35f66503b5b86fa88b85600482015282916001600160a01b03169063e16c7d9890602401602060405180830381865afa1580156104ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d2919061093c565b905060008060009054906101000a90046001600160a01b03166001600160a01b031663770672a66040518163ffffffff1660e01b8152600401600060405180830381865afa158015610528573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105509190810190610988565b805190915060005b818161ffff161015610627576000838261ffff168151811061057c5761057c610a4d565b6020026020010151905060006105918261063d565b6040516352c4889f60e01b81526001600160a01b0384811660048301529192506000918816906352c4889f90602401602060405180830381865afa1580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610959565b905061060d8282610a79565b6106179089610a96565b9750836001019350505050610558565b506106328585610aa9565b600255505050505050565b6001600160a01b0380821660009081526001602052604081205490918391166106795760405163762798e160e01b815260040160405180910390fd5b6001600160a01b038381166000818152600160205260409081902054905163b3596f0760e01b815260048101929092529091169063b3596f0790602401602060405180830381865afa1580156106d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f79190610959565b9392505050565b600054600160a81b900460ff161580801561072657506000546001600160a01b90910460ff16105b806107475750303b1580156107475750600054600160a01b900460ff166001145b6107ae5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff60a01b1916600160a01b17905580156107db576000805460ff60a81b1916600160a81b1790555b6107e482610875565b600080546001600160a01b0319166001600160a01b038416908117825560405190917f9cf19cefd9aab739c33b95716ee3f3f921f219dc6d7aae25e1f9497b3788915091a28015610871576000805460ff60a81b19169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03811661089c576040516342bcdf7f60e11b815260040160405180910390fd5b50565b6001600160a01b038116811461089c57600080fd5b600080604083850312156108c757600080fd5b82356108d28161089f565b915060208301356108e28161089f565b809150509250929050565b6000602082840312156108ff57600080fd5b81356106f78161089f565b60006020828403121561091c57600080fd5b815180151581146106f757600080fd5b80516109378161089f565b919050565b60006020828403121561094e57600080fd5b81516106f78161089f565b60006020828403121561096b57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561099b57600080fd5b825167ffffffffffffffff808211156109b357600080fd5b818501915085601f8301126109c757600080fd5b8151818111156109d9576109d9610972565b8060051b604051601f19603f830116810181811085821117156109fe576109fe610972565b604052918252848201925083810185019188831115610a1c57600080fd5b938501935b82851015610a4157610a328561092c565b84529385019392850192610a21565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a9057610a90610a63565b92915050565b80820180821115610a9057610a90610a63565b600082610ac657634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220ea458048d24ace84614b8f924471a1779beec89121ff6c983ed0dd018f58e0fe64736f6c63430008150033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.