Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 29199425 | 56 days ago | Contract Creation | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Router
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IRouter} from "src/router/interfaces/IRouter.sol";
import {IRouterModule} from "src/router/interfaces/IRouterModule.sol";
/// @title Router.
/// @author Stake DAO
/// @custom:github @stake-dao
/// @custom:contact [email protected]
/// @notice Router serves as the single entry point for all Staking V2 operations.
/// It allows for the execution of arbitrary delegate calls to registered modules,
/// enabling modular functionality extension while maintaining a unified interface.
contract Router is IRouter, Ownable {
///////////////////////////////////////////////////////////////
// --- CONSTANTS
///////////////////////////////////////////////////////////////
/// @notice The storage buffer for the modules
/// @dev Instead of using a traditional mapping that hashes the key to calculate the slot,
/// we directly use the unique identifier of each module as the storage slot.
///
/// The storage buffer exists to avoid future collisions. Note the owner of this
/// contract takes one slot in storage (slot 0).
///
/// The value of the buffer is equal to the keccak256 hash of the constant
/// string "STAKEDAO.STAKING.V2.ROUTER.V1", meaning the modules will be
/// stored starting at slot `0x5fb198ff3ff065a7e746cc70c28b38b1f3eeaf1a559ede71c28b60a0759b061b`.
/// This is a gas cost optimization made possible due to the simplicity of the storage layout.
bytes32 internal constant $buffer = keccak256("STAKEDAO.STAKING.V2.ROUTER.V1");
string public constant version = "1.1.0";
///////////////////////////////////////////////////////////////
// --- EVENTS - ERRORS
///////////////////////////////////////////////////////////////
/// @notice Emitted when a module is set
/// @param identifier The unique identifier of the module (indexed value)
/// @param module The address of the module
/// @param name The name of the module
event ModuleSet(uint8 indexed identifier, address module, string name);
// @notice Thrown when a module is already set
// @dev Only thrown when setting a module in safe mode
error IdentifierAlreadyUsed(uint8 identifier);
// @notice Thrown when trying to call a module that is not set
error ModuleNotSet(uint8 identifier);
constructor() Ownable(msg.sender) {}
///////////////////////////////////////////////////////////////
// --- MODULES MANAGEMENT
///////////////////////////////////////////////////////////////
/// @notice Sets a module
/// @dev The module is set at the storage slot `buffer + identifier`
///
/// While not enforced by the code, developers are expected to use
/// incremental identifiers when setting modules.
/// This allows modules to be enumerated using the `enumerateModules` helper.
/// Note that this is just a convention, and modules should be indexed off-chain for
/// efficiency and correctness.
/// @param identifier The unique identifier of the module
/// @param module The address of the module
/// @param safe Whether the module is set in safe mode (if true, the module must not be already set)
/// @custom:throws OwnableUnauthorizedAccount if the caller is not the owner
function setModule(uint8 identifier, address module, bool safe) public onlyOwner {
if (safe) require(address(getModule(identifier)) == address(0), IdentifierAlreadyUsed(identifier));
bytes32 buffer = $buffer;
assembly ("memory-safe") {
sstore(add(buffer, identifier), module)
}
emit ModuleSet(identifier, module, IRouterModule(module).name());
}
/// @notice Gets the module at the given identifier
/// @param identifier The unique identifier of the module
/// @return module The address of the module. Returns address(0) if the module is not set
function getModule(uint8 identifier) public view returns (IRouterModule module) {
bytes32 buffer = $buffer;
assembly ("memory-safe") {
module := sload(add(buffer, identifier))
}
}
///////////////////////////////////////////////////////////////
// --- EXECUTION
///////////////////////////////////////////////////////////////
/// @notice Executes a batch of delegate calls to registered modules.
/// @dev Each element in the `calls` array must be encoded as:
/// - 1 byte: the module identifier (`uint8`), corresponding to a registered module.
/// - N bytes: Optional ABI-encoded call data using `abi.encodeWithSelector(...)`, where:
/// - The first 4 bytes represent the function selector.
/// - The remaining bytes (a multiple of 32) represent the function arguments.
///
/// Example: `bytes.concat(bytes1(identifier), abi.encodeWithSelector(...))`
///
/// All calls are performed using `delegatecall`, so state changes affect this contract.
/// @param calls An array of encoded calls. Each call must start with a 1-byte module identifier
/// followed by the ABI-encoded function call data.
/// @return returnData An array containing the returned data for each call, in order.
/// @custom:throws OwnableUnauthorizedAccount if the caller is not the owner
/// @custom:throws ModuleNotSet if the module for a given identifier is not set
/// @custom:throws _ if a `calls[i]` element is empty
function execute(bytes[] calldata calls) external payable returns (bytes[] memory) {
bytes[] memory returnData = new bytes[](calls.length);
for (uint256 i; i < calls.length; i++) {
address module = address(getModule(uint8(calls[i][0])));
require(module != address(0), ModuleNotSet(uint8(calls[i][0])));
// `calls[i][1:]` is the optional calldata, including the function selector, w/o the module identifier
returnData[i] = Address.functionDelegateCall(module, calls[i][1:]);
}
return returnData;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
(bool success, bytes memory returndata) = recipient.call{value: amount}("");
if (!success) {
_revert(returndata);
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {Errors.FailedCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
* of an unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {Errors.FailedCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
*/
function _revert(bytes memory returndata) 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
assembly ("memory-safe") {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert Errors.FailedCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.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.
*
* The initial owner is set to the address provided by the deployer. 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 Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {IRouterModule} from "src/router/interfaces/IRouterModule.sol";
interface IRouter {
function execute(bytes[] calldata data) external payable returns (bytes[] memory returnData);
function setModule(uint8 identifier, address module, bool safe) external;
function getModule(uint8 identifier) external view returns (IRouterModule module);
function version() external view returns (string memory version);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
interface IRouterModule {
function name() external view returns (string memory name);
function version() external view returns (string memory version);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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 Context {
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;
}
}{
"remappings": [
"forge-std/=node_modules/forge-std/",
"@shared/=node_modules/@stake-dao/shared/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"@interfaces/=node_modules/@stake-dao/interfaces/src/interfaces/",
"@address-book/=node_modules/@stake-dao/address-book/",
"@strategies/=node_modules/@stake-dao/strategies/",
"@lockers/=node_modules/@stake-dao/lockers/",
"@safe/=node_modules/@stake-dao/strategies/node_modules/@safe-global/safe-smart-account/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[],"name":"FailedCall","type":"error"},{"inputs":[{"internalType":"uint8","name":"identifier","type":"uint8"}],"name":"IdentifierAlreadyUsed","type":"error"},{"inputs":[{"internalType":"uint8","name":"identifier","type":"uint8"}],"name":"ModuleNotSet","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"identifier","type":"uint8"},{"indexed":false,"internalType":"address","name":"module","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"ModuleSet","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"},{"inputs":[{"internalType":"bytes[]","name":"calls","type":"bytes[]"}],"name":"execute","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"identifier","type":"uint8"}],"name":"getModule","outputs":[{"internalType":"contract IRouterModule","name":"module","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"identifier","type":"uint8"},{"internalType":"address","name":"module","type":"address"},{"internalType":"bool","name":"safe","type":"bool"}],"name":"setModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052348015600e575f5ffd5b503380603357604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b603a81603f565b50608e565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6109c38061009b5f395ff3fe60806040526004361061006e575f3560e01c8063715018a61161004c578063715018a61461011d5780638da5cb5b14610133578063e8a264f21461014f578063f2fde38b1461016e575f5ffd5b8063444714151461007257806354fd4d501461009b5780636429212d146100d8575b5f5ffd5b610085610080366004610627565b61018d565b60405161009291906106c6565b60405180910390f35b3480156100a6575f5ffd5b506100cb604051806040016040528060058152602001640312e312e360dc1b81525081565b6040516100929190610729565b3480156100e3575f5ffd5b506101056100f2366004610750565b5f51602061096e5f395f51905f52015490565b6040516001600160a01b039091168152602001610092565b348015610128575f5ffd5b50610131610351565b005b34801561013e575f5ffd5b505f546001600160a01b0316610105565b34801561015a575f5ffd5b5061013161016936600461077f565b610364565b348015610179575f5ffd5b506101316101883660046107c7565b610475565b60605f8267ffffffffffffffff8111156101a9576101a96107e0565b6040519080825280602002602001820160405280156101dc57816020015b60608152602001906001900390816101c75790505b5090505f5b83811015610349575f61023e8686848181106101ff576101ff6107f4565b90506020028101906102119190610808565b5f818110610221576102216107f4565b919091013560f81c90505f51602061096e5f395f51905f52015490565b90506001600160a01b038116151586868481811061025e5761025e6107f4565b90506020028101906102709190610808565b5f818110610280576102806107f4565b919091013560f81c9190506102b357604051634f2da44960e11b815260ff90911660048201526024015b60405180910390fd5b50610323818787858181106102ca576102ca6107f4565b90506020028101906102dc9190610808565b6102ea916001908290610852565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506104b292505050565b838381518110610335576103356107f4565b6020908102919091010152506001016101e1565b509392505050565b610359610524565b6103625f610550565b565b61036c610524565b80156103bb575f61038a845f51602061096e5f395f51905f52015490565b6001600160a01b03161483906103b95760405163027b58bf60e41b815260ff90911660048201526024016102aa565b505b5f5f51602061096e5f395f51905f52905082848201558360ff167fedc7f66a6391d877278e0356bf1610da9f641d3c879afb07d520d1a42fbd97d384856001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610432573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526104599190810190610879565b60405161046792919061092c565b60405180910390a250505050565b61047d610524565b6001600160a01b0381166104a657604051631e4fbdf760e01b81525f60048201526024016102aa565b6104af81610550565b50565b60605f5f846001600160a01b0316846040516104ce9190610957565b5f60405180830381855af49150503d805f8114610506576040519150601f19603f3d011682016040523d82523d5f602084013e61050b565b606091505b509150915061051b85838361059f565b95945050505050565b5f546001600160a01b031633146103625760405163118cdaa760e01b81523360048201526024016102aa565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060826105b4576105af826105fe565b6105f7565b81511580156105cb57506001600160a01b0384163b155b156105f457604051639996b31560e01b81526001600160a01b03851660048201526024016102aa565b50805b9392505050565b80511561060e5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b5f5f60208385031215610638575f5ffd5b823567ffffffffffffffff81111561064e575f5ffd5b8301601f8101851361065e575f5ffd5b803567ffffffffffffffff811115610674575f5ffd5b8560208260051b8401011115610688575f5ffd5b6020919091019590945092505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561071d57603f19878603018452610708858351610698565b945060209384019391909101906001016106ec565b50929695505050505050565b602081525f6105f76020830184610698565b803560ff8116811461074b575f5ffd5b919050565b5f60208284031215610760575f5ffd5b6105f78261073b565b80356001600160a01b038116811461074b575f5ffd5b5f5f5f60608486031215610791575f5ffd5b61079a8461073b565b92506107a860208501610769565b9150604084013580151581146107bc575f5ffd5b809150509250925092565b5f602082840312156107d7575f5ffd5b6105f782610769565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e1984360301811261081d575f5ffd5b83018035915067ffffffffffffffff821115610837575f5ffd5b60200191503681900382131561084b575f5ffd5b9250929050565b5f5f85851115610860575f5ffd5b8386111561086c575f5ffd5b5050820193919092039150565b5f60208284031215610889575f5ffd5b815167ffffffffffffffff81111561089f575f5ffd5b8201601f810184136108af575f5ffd5b805167ffffffffffffffff8111156108c9576108c96107e0565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156108f8576108f86107e0565b60405281815282820160200186101561090f575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b6001600160a01b03831681526040602082018190525f9061094f90830184610698565b949350505050565b5f82518060208501845e5f92019182525091905056fe5fb198ff3ff065a7e746cc70c28b38b1f3eeaf1a559ede71c28b60a0759b061ba26469706673582212207a1739de013d9d45103d78140c6ee81d4d4082d4a0895e248bb83345f42cd24a64736f6c634300081c0033
Deployed Bytecode
0x60806040526004361061006e575f3560e01c8063715018a61161004c578063715018a61461011d5780638da5cb5b14610133578063e8a264f21461014f578063f2fde38b1461016e575f5ffd5b8063444714151461007257806354fd4d501461009b5780636429212d146100d8575b5f5ffd5b610085610080366004610627565b61018d565b60405161009291906106c6565b60405180910390f35b3480156100a6575f5ffd5b506100cb604051806040016040528060058152602001640312e312e360dc1b81525081565b6040516100929190610729565b3480156100e3575f5ffd5b506101056100f2366004610750565b5f51602061096e5f395f51905f52015490565b6040516001600160a01b039091168152602001610092565b348015610128575f5ffd5b50610131610351565b005b34801561013e575f5ffd5b505f546001600160a01b0316610105565b34801561015a575f5ffd5b5061013161016936600461077f565b610364565b348015610179575f5ffd5b506101316101883660046107c7565b610475565b60605f8267ffffffffffffffff8111156101a9576101a96107e0565b6040519080825280602002602001820160405280156101dc57816020015b60608152602001906001900390816101c75790505b5090505f5b83811015610349575f61023e8686848181106101ff576101ff6107f4565b90506020028101906102119190610808565b5f818110610221576102216107f4565b919091013560f81c90505f51602061096e5f395f51905f52015490565b90506001600160a01b038116151586868481811061025e5761025e6107f4565b90506020028101906102709190610808565b5f818110610280576102806107f4565b919091013560f81c9190506102b357604051634f2da44960e11b815260ff90911660048201526024015b60405180910390fd5b50610323818787858181106102ca576102ca6107f4565b90506020028101906102dc9190610808565b6102ea916001908290610852565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506104b292505050565b838381518110610335576103356107f4565b6020908102919091010152506001016101e1565b509392505050565b610359610524565b6103625f610550565b565b61036c610524565b80156103bb575f61038a845f51602061096e5f395f51905f52015490565b6001600160a01b03161483906103b95760405163027b58bf60e41b815260ff90911660048201526024016102aa565b505b5f5f51602061096e5f395f51905f52905082848201558360ff167fedc7f66a6391d877278e0356bf1610da9f641d3c879afb07d520d1a42fbd97d384856001600160a01b03166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa158015610432573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526104599190810190610879565b60405161046792919061092c565b60405180910390a250505050565b61047d610524565b6001600160a01b0381166104a657604051631e4fbdf760e01b81525f60048201526024016102aa565b6104af81610550565b50565b60605f5f846001600160a01b0316846040516104ce9190610957565b5f60405180830381855af49150503d805f8114610506576040519150601f19603f3d011682016040523d82523d5f602084013e61050b565b606091505b509150915061051b85838361059f565b95945050505050565b5f546001600160a01b031633146103625760405163118cdaa760e01b81523360048201526024016102aa565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060826105b4576105af826105fe565b6105f7565b81511580156105cb57506001600160a01b0384163b155b156105f457604051639996b31560e01b81526001600160a01b03851660048201526024016102aa565b50805b9392505050565b80511561060e5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b5f5f60208385031215610638575f5ffd5b823567ffffffffffffffff81111561064e575f5ffd5b8301601f8101851361065e575f5ffd5b803567ffffffffffffffff811115610674575f5ffd5b8560208260051b8401011115610688575f5ffd5b6020919091019590945092505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561071d57603f19878603018452610708858351610698565b945060209384019391909101906001016106ec565b50929695505050505050565b602081525f6105f76020830184610698565b803560ff8116811461074b575f5ffd5b919050565b5f60208284031215610760575f5ffd5b6105f78261073b565b80356001600160a01b038116811461074b575f5ffd5b5f5f5f60608486031215610791575f5ffd5b61079a8461073b565b92506107a860208501610769565b9150604084013580151581146107bc575f5ffd5b809150509250925092565b5f602082840312156107d7575f5ffd5b6105f782610769565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e1984360301811261081d575f5ffd5b83018035915067ffffffffffffffff821115610837575f5ffd5b60200191503681900382131561084b575f5ffd5b9250929050565b5f5f85851115610860575f5ffd5b8386111561086c575f5ffd5b5050820193919092039150565b5f60208284031215610889575f5ffd5b815167ffffffffffffffff81111561089f575f5ffd5b8201601f810184136108af575f5ffd5b805167ffffffffffffffff8111156108c9576108c96107e0565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156108f8576108f86107e0565b60405281815282820160200186101561090f575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b6001600160a01b03831681526040602082018190525f9061094f90830184610698565b949350505050565b5f82518060208501845e5f92019182525091905056fe5fb198ff3ff065a7e746cc70c28b38b1f3eeaf1a559ede71c28b60a0759b061ba26469706673582212207a1739de013d9d45103d78140c6ee81d4d4082d4a0895e248bb83345f42cd24a64736f6c634300081c0033
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
[ 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.