Source Code
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 50138358 | 3 days ago | 38.0175351 MON | ||||
| 50138358 | 3 days ago | 38.0175351 MON | ||||
| 49954950 | 4 days ago | 90 MON | ||||
| 49954950 | 4 days ago | 90 MON | ||||
| 49781347 | 4 days ago | 120.96267499 MON | ||||
| 49781347 | 4 days ago | 120.96267499 MON | ||||
| 48963132 | 8 days ago | 54.2877986 MON | ||||
| 48963132 | 8 days ago | 54.2877986 MON | ||||
| 47690585 | 14 days ago | 100 MON | ||||
| 47690585 | 14 days ago | 100 MON | ||||
| 47689619 | 14 days ago | 100 MON | ||||
| 47689619 | 14 days ago | 100 MON | ||||
| 47662638 | 14 days ago | 0.8284099 MON | ||||
| 47662638 | 14 days ago | 0.8284099 MON | ||||
| 47641229 | 14 days ago | 109.89789855 MON | ||||
| 47641229 | 14 days ago | 109.89789855 MON | ||||
| 46908324 | 18 days ago | 3.57522608 MON | ||||
| 46908324 | 18 days ago | 3.57522608 MON | ||||
| 46811299 | 18 days ago | 60 MON | ||||
| 46811299 | 18 days ago | 60 MON | ||||
| 44306206 | 30 days ago | 66.38651957 MON | ||||
| 44306206 | 30 days ago | 66.38651957 MON | ||||
| 44289941 | 30 days ago | 50 MON | ||||
| 44289941 | 30 days ago | 50 MON | ||||
| 42249583 | 39 days ago | 11,135 MON |
Loading...
Loading
Contract Name:
GenericStakedRoute
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.19;
import {SafeTransferLib} from "solady/src/utils/SafeTransferLib.sol";
import {Ownable} from "../utils/Ownable.sol";
import {RescueFundsLib} from "../lib/RescueFundsLib.sol";
import {IStakedRouterExternalExecutor} from "../interfaces/IStakedRouterExecutor.sol";
/// @title GenericStakedRoute
/// @notice A generic contract that bridges tokens between chains by interacting with arbitrary bridge contracts
/// @dev Used to execute bridge operations via StakedRouterExecutor
contract GenericStakedRoute is Ownable, IStakedRouterExternalExecutor {
struct Action {
address target;
uint256 value;
bytes data;
}
error CallerNotStakedRouterExecutor();
error BridgeFailed();
error InvalidMsgValue();
error PositionOutOfBounds();
error ActionsFailed(uint256 index);
/// @dev address used to identify native token
address public constant NATIVE_TOKEN_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
/// @notice The address of the staked router executor
/// @dev Can be set by the owner
address public stakedRouterExecutor;
constructor(address _owner, address _stakedRouterExecutor) Ownable(_owner) {
stakedRouterExecutor = _stakedRouterExecutor;
}
function setStakedRouterExecutor(address _stakedRouterExecutor) external onlyOwner {
stakedRouterExecutor = _stakedRouterExecutor;
}
/// @notice Implements IStakedRouterExternalExecutor.executeData()
/// @dev Executes external bridge interactions after modifying amount in calldata
/// @dev Only callable by StakedRouterExecutor
/// @param requestHash The hash of the request
/// @param token The token to bridge
/// @param amount The amount of tokens to bridge
/// @param externalExecutorData The encoded data to use for bridging
function executeData(
bytes32 requestHash,
address token,
uint256 amount,
bytes calldata externalExecutorData
) external payable override {
// Revert if the caller is not the staked router executor
if (msg.sender != stakedRouterExecutor) revert CallerNotStakedRouterExecutor();
// Decode externalExecutorData
(
bool isApprovalRequired, // whether to approve the externalSpender
address externalSpender, // address to approve
address externalContract, // address to call
uint256 additionalValue, // additional msg.value to use with externalContract.call()
uint256 bytesPosition, // position of `amount` to modify in `externalData`
bytes memory externalData // calldata to call on `externalContract`
) = abi.decode(externalExecutorData, (bool, address, address, uint256, uint256, bytes));
// check if we need to modify the calldata
if (bytesPosition != type(uint256).max) {
// check if the bytesPosition is out of bounds
if (bytesPosition + 32 > externalData.length) revert PositionOutOfBounds();
// Directly modify externalData in-place without creating a new copy
assembly {
// Calculate position in memory where we need to write the new amount
let pos := add(add(externalData, 32), bytesPosition)
// Write the amount at that position
mstore(pos, amount)
}
}
// Call external contract for execution
if (token == NATIVE_TOKEN_ADDRESS) {
// Check if msg.value is equal to amount
/// @dev StakedRouterExecutor always calls with amount as value
/// But this contract can hold some native tokens in general
/// So we check msg.value here
if (msg.value != amount) revert InvalidMsgValue();
(bool success, ) = externalContract.call{value: amount + additionalValue}(externalData);
if (!success) revert BridgeFailed();
} else {
// Approve if required
if (isApprovalRequired) {
SafeTransferLib.safeApprove(token, externalSpender, amount);
}
(bool success, ) = externalContract.call{value: additionalValue}(externalData);
if (!success) revert BridgeFailed();
}
}
/// @dev Can be used by owner to perform arbitrary actions
/// eg. reset approvals, etc.
function performActions(Action[] calldata actions) external onlyOwner {
for (uint256 i = 0; i < actions.length; i++) {
(bool success, ) = actions[i].target.call{value: actions[i].value}(actions[i].data);
if (!success) revert ActionsFailed(i);
}
}
/// @notice Rescues funds from the contract if they are locked by mistake.
/// @param token_ The address of the token contract.
/// @param rescueTo_ The address where rescued tokens need to be sent.
/// @param amount_ The amount of tokens to be rescued.
function rescueFunds(address token_, address rescueTo_, uint256 amount_) external onlyOwner {
RescueFundsLib.rescueFunds(token_, rescueTo_, amount_);
}
/// @dev Since this contract interacts with bridge contracts,
/// it should be able to receive native tokens with or without calldata, that maybe sent as refunds
receive() external payable {}
fallback() external payable {}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @author Permit2 operations from (https://github.com/Uniswap/permit2/blob/main/src/libraries/Permit2Lib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
library SafeTransferLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ETH transfer has failed.
error ETHTransferFailed();
/// @dev The ERC20 `transferFrom` has failed.
error TransferFromFailed();
/// @dev The ERC20 `transfer` has failed.
error TransferFailed();
/// @dev The ERC20 `approve` has failed.
error ApproveFailed();
/// @dev The ERC20 `totalSupply` query has failed.
error TotalSupplyQueryFailed();
/// @dev The Permit2 operation has failed.
error Permit2Failed();
/// @dev The Permit2 amount must be less than `2**160 - 1`.
error Permit2AmountOverflow();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;
/// @dev Suggested gas stipend for contract receiving ETH to perform a few
/// storage reads and writes, but low enough to prevent griefing.
uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;
/// @dev The unique EIP-712 domain domain separator for the DAI token contract.
bytes32 internal constant DAI_DOMAIN_SEPARATOR =
0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7;
/// @dev The address for the WETH9 contract on Ethereum mainnet.
address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
/// @dev The canonical Permit2 address.
/// [Github](https://github.com/Uniswap/permit2)
/// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3)
address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ETH OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
//
// The regular variants:
// - Forwards all remaining gas to the target.
// - Reverts if the target reverts.
// - Reverts if the current contract has insufficient balance.
//
// The force variants:
// - Forwards with an optional gas stipend
// (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
// - If the target reverts, or if the gas stipend is exhausted,
// creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
// Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
// - Reverts if the current contract has insufficient balance.
//
// The try variants:
// - Forwards with a mandatory gas stipend.
// - Instead of reverting, returns whether the transfer succeeded.
/// @dev Sends `amount` (in wei) ETH to `to`.
function safeTransferETH(address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Sends all the ETH in the current contract to `to`.
function safeTransferAllETH(address to) internal {
/// @solidity memory-safe-assembly
assembly {
// Transfer all the ETH and check if it succeeded or not.
if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
/// @solidity memory-safe-assembly
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
/// @solidity memory-safe-assembly
assembly {
if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
function forceSafeTransferETH(address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
function forceSafeTransferAllETH(address to) internal {
/// @solidity memory-safe-assembly
assembly {
// forgefmt: disable-next-item
if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to) // Store the address in scratch space.
mstore8(0x0b, 0x73) // Opcode `PUSH20`.
mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
}
}
}
/// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
}
}
/// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
function trySafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC20 OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have at least `amount` approved for
/// the current contract to manage.
function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
///
/// The `from` account must have at least `amount` approved for the current contract to manage.
function trySafeTransferFrom(address token, address from, address to, uint256 amount)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
success := lt(or(iszero(extcodesize(token)), returndatasize()), success)
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends all of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have their entire balance approved for the current contract to manage.
function safeTransferAllFrom(address token, address from, address to)
internal
returns (uint256 amount)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
)
) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransfer(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sends all of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransferAll(address token, address to) internal returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
mstore(0x20, address()) // Store the address of the current contract.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
)
) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
mstore(0x14, to) // Store the `to` argument.
amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// Reverts upon failure.
function safeApprove(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
/// then retries the approval again (some tokens, e.g. USDT, requires this).
/// Reverts upon failure.
function safeApproveWithRetry(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
// Perform the approval, retrying upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x34, 0) // Store 0 for the `amount`.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.
mstore(0x34, amount) // Store back the original `amount`.
// Retry the approval, reverting upon failure.
success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
// Check the `extcodesize` again just in case the token selfdestructs lol.
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
}
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Returns the amount of ERC20 `token` owned by `account`.
/// Returns zero if the `token` does not exist.
function balanceOf(address token, address account) internal view returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, account) // Store the `account` argument.
mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
amount :=
mul( // The arguments of `mul` are evaluated from right to left.
mload(0x20),
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
)
)
}
}
/// @dev Returns the total supply of the `token`.
/// Reverts if the token does not exist or does not implement `totalSupply()`.
function totalSupply(address token) internal view returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, 0x18160ddd) // `totalSupply()`.
if iszero(
and(gt(returndatasize(), 0x1f), staticcall(gas(), token, 0x1c, 0x04, 0x00, 0x20))
) {
mstore(0x00, 0x54cd9435) // `TotalSupplyQueryFailed()`.
revert(0x1c, 0x04)
}
result := mload(0x00)
}
}
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
/// If the initial attempt fails, try to use Permit2 to transfer the token.
/// Reverts upon failure.
///
/// The `from` account must have at least `amount` approved for the current contract to manage.
function safeTransferFrom2(address token, address from, address to, uint256 amount) internal {
if (!trySafeTransferFrom(token, from, to, amount)) {
permit2TransferFrom(token, from, to, amount);
}
}
/// @dev Sends `amount` of ERC20 `token` from `from` to `to` via Permit2.
/// Reverts upon failure.
function permit2TransferFrom(address token, address from, address to, uint256 amount)
internal
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(add(m, 0x74), shr(96, shl(96, token)))
mstore(add(m, 0x54), amount)
mstore(add(m, 0x34), to)
mstore(add(m, 0x20), shl(96, from))
// `transferFrom(address,address,uint160,address)`.
mstore(m, 0x36c78516000000000000000000000000)
let p := PERMIT2
let exists := eq(chainid(), 1)
if iszero(exists) { exists := iszero(iszero(extcodesize(p))) }
if iszero(
and(
call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00),
lt(iszero(extcodesize(token)), exists) // Token has code and Permit2 exists.
)
) {
mstore(0x00, 0x7939f4248757f0fd) // `TransferFromFailed()` or `Permit2AmountOverflow()`.
revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04)
}
}
}
/// @dev Permit a user to spend a given amount of
/// another user's tokens via native EIP-2612 permit if possible, falling
/// back to Permit2 if native permit fails or is not implemented on the token.
function permit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
for {} shl(96, xor(token, WETH9)) {} {
mstore(0x00, 0x3644e515) // `DOMAIN_SEPARATOR()`.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)), // Returns 1 non-zero word.
// Gas stipend to limit gas burn for tokens that don't refund gas when
// an non-existing function is called. 5K should be enough for a SLOAD.
staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20)
)
) { break }
// After here, we can be sure that token is a contract.
let m := mload(0x40)
mstore(add(m, 0x34), spender)
mstore(add(m, 0x20), shl(96, owner))
mstore(add(m, 0x74), deadline)
if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) {
mstore(0x14, owner)
mstore(0x00, 0x7ecebe00000000000000000000000000) // `nonces(address)`.
mstore(add(m, 0x94), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20))
mstore(m, 0x8fcbaf0c000000000000000000000000) // `IDAIPermit.permit`.
// `nonces` is already at `add(m, 0x54)`.
// `1` is already stored at `add(m, 0x94)`.
mstore(add(m, 0xb4), and(0xff, v))
mstore(add(m, 0xd4), r)
mstore(add(m, 0xf4), s)
success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00)
break
}
mstore(m, 0xd505accf000000000000000000000000) // `IERC20Permit.permit`.
mstore(add(m, 0x54), amount)
mstore(add(m, 0x94), and(0xff, v))
mstore(add(m, 0xb4), r)
mstore(add(m, 0xd4), s)
success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00)
break
}
}
if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s);
}
/// @dev Simple permit on the Permit2 contract.
function simplePermit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40)
mstore(m, 0x927da105) // `allowance(address,address,address)`.
{
let addressMask := shr(96, not(0))
mstore(add(m, 0x20), and(addressMask, owner))
mstore(add(m, 0x40), and(addressMask, token))
mstore(add(m, 0x60), and(addressMask, spender))
mstore(add(m, 0xc0), and(addressMask, spender))
}
let p := mul(PERMIT2, iszero(shr(160, amount)))
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x5f), // Returns 3 words: `amount`, `expiration`, `nonce`.
staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60)
)
) {
mstore(0x00, 0x6b836e6b8757f0fd) // `Permit2Failed()` or `Permit2AmountOverflow()`.
revert(add(0x18, shl(2, iszero(p))), 0x04)
}
mstore(m, 0x2b67b570) // `Permit2.permit` (PermitSingle variant).
// `owner` is already `add(m, 0x20)`.
// `token` is already at `add(m, 0x40)`.
mstore(add(m, 0x60), amount)
mstore(add(m, 0x80), 0xffffffffffff) // `expiration = type(uint48).max`.
// `nonce` is already at `add(m, 0xa0)`.
// `spender` is already at `add(m, 0xc0)`.
mstore(add(m, 0xe0), deadline)
mstore(add(m, 0x100), 0x100) // `signature` offset.
mstore(add(m, 0x120), 0x41) // `signature` length.
mstore(add(m, 0x140), r)
mstore(add(m, 0x160), s)
mstore(add(m, 0x180), shl(248, v))
if iszero( // Revert if token does not have code, or if the call fails.
mul(extcodesize(token), call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00))) {
mstore(0x00, 0x6b836e6b) // `Permit2Failed()`.
revert(0x1c, 0x04)
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/*//////////////////////////////////////////////////////////////
BUNGEE ERRORS
//////////////////////////////////////////////////////////////*/
error MofaSignatureInvalid();
error InsufficientNativeAmount();
error UnsupportedRequest();
error RouterNotRegistered();
error CallerNotBungeeGateway();
error CallerNotEntrypoint();
error SwapOutputInsufficient();
error MinOutputNotMet();
error InvalidRequest();
error FulfilmentDeadlineNotMet();
error CallerNotDelegate();
error CallerNotStakedRouter();
error InvalidMsg();
error RequestProcessed();
error RequestNotProcessed();
error InvalidSwitchboard();
error PromisedAmountNotMet();
error MsgReceiveFailed();
error RouterAlreadyRegistered();
error InvalidFulfil();
error NotImplemented();
error OnlyOwner();
error OnlyNominee();
error InvalidReceiver();
error ImplAlreadyRegistered();
error InvalidAddress();
error ActionFailed();
error InvalidDstEid();
error SwapInputExceedsAllowance();
/*//////////////////////////////////////////////////////////////
SWITCHBOARD ERRORS
//////////////////////////////////////////////////////////////*/
error NotSiblingBungeeGateway();
error NotSocket();
error NotSwitchboardRouter();
error NotSwitchboardPlug();
error SwitchboardPlugZero();
error ConnectionAlreadyInitialised();
error IncorrectSwitchboard();// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
interface IStakedRouterExecutor {
function execute(
bytes32 requestHash,
address inputToken,
uint256 amount,
bytes calldata actionData
) external payable;
}
interface IStakedRouterExternalExecutor {
function executeData(bytes32 requestHash, address token, uint256 amount, bytes memory externalExecutorData) external payable;
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.19;
// @audit Audited before by Zellic: https://github.com/SocketDotTech/audits/blob/main/Socket-DL/07-2023%20-%20Data%20Layer%20-%20Zellic.pdf
import {SafeTransferLib} from "solady/src/utils/SafeTransferLib.sol";
error ZeroAddress();
/**
* @title RescueFundsLib
* @dev A library that provides a function to rescue funds from a contract.
*/
library RescueFundsLib {
/**
* @dev The address used to identify ETH.
*/
address public constant ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
/**
* @dev thrown when the given token address don't have any code
*/
error InvalidTokenAddress();
/**
* @dev Rescues funds from a contract.
* @param token_ The address of the token contract.
* @param rescueTo_ The address of the user.
* @param amount_ The amount of tokens to be rescued.
*/
function rescueFunds(address token_, address rescueTo_, uint256 amount_) internal {
if (rescueTo_ == address(0)) revert ZeroAddress();
if (token_ == ETH_ADDRESS) {
SafeTransferLib.safeTransferETH(rescueTo_, amount_);
} else {
if (token_.code.length == 0) revert InvalidTokenAddress();
SafeTransferLib.safeTransfer(token_, rescueTo_, amount_);
}
}
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.19;
import {OnlyOwner, OnlyNominee} from "../common/Errors.sol";
// @audit Audited before by Zellic: https://github.com/SocketDotTech/audits/blob/main/Socket-DL/07-2023%20-%20Data%20Layer%20-%20Zellic.pdf
abstract contract Ownable {
address private _owner;
address private _nominee;
event OwnerNominated(address indexed nominee);
event OwnerClaimed(address indexed claimer);
constructor(address owner_) {
_claimOwner(owner_);
}
modifier onlyOwner() {
if (msg.sender != _owner) {
revert OnlyOwner();
}
_;
}
function owner() public view returns (address) {
return _owner;
}
function nominee() public view returns (address) {
return _nominee;
}
function nominateOwner(address nominee_) external {
if (msg.sender != _owner) {
revert OnlyOwner();
}
_nominee = nominee_;
emit OwnerNominated(_nominee);
}
function claimOwner() external {
if (msg.sender != _nominee) {
revert OnlyNominee();
}
_claimOwner(msg.sender);
}
function _claimOwner(address claimer_) internal {
_owner = claimer_;
_nominee = address(0);
emit OwnerClaimed(claimer_);
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_stakedRouterExecutor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ActionsFailed","type":"error"},{"inputs":[],"name":"BridgeFailed","type":"error"},{"inputs":[],"name":"CallerNotStakedRouterExecutor","type":"error"},{"inputs":[],"name":"InvalidMsgValue","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[],"name":"OnlyNominee","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"PositionOutOfBounds","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"}],"name":"OwnerClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nominee","type":"address"}],"name":"OwnerNominated","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"NATIVE_TOKEN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestHash","type":"bytes32"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"externalExecutorData","type":"bytes"}],"name":"executeData","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"nominee_","type":"address"}],"name":"nominateOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct GenericStakedRoute.Action[]","name":"actions","type":"tuple[]"}],"name":"performActions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"rescueTo_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakedRouterExecutor","type":"address"}],"name":"setStakedRouterExecutor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedRouterExecutor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405234801561001057600080fd5b50604051610ce7380380610ce783398101604081905261002f916100cf565b8161003981610060565b50600280546001600160a01b0319166001600160a01b039290921691909117905550610102565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b80516001600160a01b03811681146100ca57600080fd5b919050565b600080604083850312156100e257600080fd5b6100eb836100b3565b91506100f9602084016100b3565b90509250929050565b610bd6806101116000396000f3fe60806040526004361061008f5760003560e01c80638da5cb5b116100565780638da5cb5b1461014357806391dda0bd146101615780639f08b95114610181578063b980c2e2146101a1578063df2ebdbb146101b457005b806320f99c0a146100985780633bd1adec146100ce5780633dfc50d3146100e35780635b94db27146101035780636ccae0541461012357005b3661009657005b005b3480156100a457600080fd5b506001546001600160a01b03165b6040516001600160a01b03909116815260200160405180910390f35b3480156100da57600080fd5b506100966101dc565b3480156100ef57600080fd5b506002546100b2906001600160a01b031681565b34801561010f57600080fd5b5061009661011e36600461080f565b610212565b34801561012f57600080fd5b5061009661013e366004610833565b610287565b34801561014f57600080fd5b506000546001600160a01b03166100b2565b34801561016d57600080fd5b5061009661017c366004610874565b6102c2565b34801561018d57600080fd5b5061009661019c36600461080f565b61041b565b6100966101af3660046108e9565b610468565b3480156101c057600080fd5b506100b273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6001546001600160a01b0316331461020757604051637c91ccdd60e01b815260040160405180910390fd5b61021033610663565b565b6000546001600160a01b0316331461023d57604051635fc483c560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b6000546001600160a01b031633146102b257604051635fc483c560e01b815260040160405180910390fd5b6102bd8383836106b6565b505050565b6000546001600160a01b031633146102ed57604051635fc483c560e01b815260040160405180910390fd5b60005b818110156102bd57600083838381811061030c5761030c61097f565b905060200281019061031e9190610995565b61032c90602081019061080f565b6001600160a01b03168484848181106103475761034761097f565b90506020028101906103599190610995565b6020013585858581811061036f5761036f61097f565b90506020028101906103819190610995565b61038f9060408101906109b5565b60405161039d929190610a03565b60006040518083038185875af1925050503d80600081146103da576040519150601f19603f3d011682016040523d82523d6000602084013e6103df565b606091505b50509050806104085760405163505737f760e11b81526004810183905260240160405180910390fd5b508061041381610a29565b9150506102f0565b6000546001600160a01b0316331461044657604051635fc483c560e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331461049357604051634a8f4afb60e01b815260040160405180910390fd5b600080808080806104a687890189610a58565b95509550955095509550955060001982146104f15780516104c8836020610b58565b11156104e75760405163eb9bc44760e01b815260040160405180910390fd5b8082016020018990525b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038b16016105c45788341461053657604051631841b4e160e01b815260040160405180910390fd5b60006001600160a01b03851661054c858c610b58565b8360405161055a9190610b71565b60006040518083038185875af1925050503d8060008114610597576040519150601f19603f3d011682016040523d82523d6000602084013e61059c565b606091505b50509050806105be576040516361dcf76f60e11b815260040160405180910390fd5b50610656565b85156105d5576105d58a868b610742565b6000846001600160a01b031684836040516105f09190610b71565b60006040518083038185875af1925050503d806000811461062d576040519150601f19603f3d011682016040523d82523d6000602084013e610632565b606091505b5050905080610654576040516361dcf76f60e11b815260040160405180910390fd5b505b5050505050505050505050565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b6001600160a01b0382166106dd5760405163d92e233d60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0384160161070c576102bd8282610792565b826001600160a01b03163b60000361073757604051630f58058360e11b815260040160405180910390fd5b6102bd8383836107b2565b816014528060345263095ea7b360601b60005260206000604460106000875af1806001600051141661078757803d853b15171061078757633e3f8f736000526004601cfd5b506000603452505050565b60003860003884865af16107ae5763b12d13eb6000526004601cfd5b5050565b816014528060345263a9059cbb60601b60005260206000604460106000875af1806001600051141661078757803d853b151710610787576390b8ec186000526004601cfd5b6001600160a01b038116811461080c57600080fd5b50565b60006020828403121561082157600080fd5b813561082c816107f7565b9392505050565b60008060006060848603121561084857600080fd5b8335610853816107f7565b92506020840135610863816107f7565b929592945050506040919091013590565b6000806020838503121561088757600080fd5b823567ffffffffffffffff8082111561089f57600080fd5b818501915085601f8301126108b357600080fd5b8135818111156108c257600080fd5b8660208260051b85010111156108d757600080fd5b60209290920196919550909350505050565b60008060008060006080868803121561090157600080fd5b853594506020860135610913816107f7565b935060408601359250606086013567ffffffffffffffff8082111561093757600080fd5b818801915088601f83011261094b57600080fd5b81358181111561095a57600080fd5b89602082850101111561096c57600080fd5b9699959850939650602001949392505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e198336030181126109ab57600080fd5b9190910192915050565b6000808335601e198436030181126109cc57600080fd5b83018035915067ffffffffffffffff8211156109e757600080fd5b6020019150368190038213156109fc57600080fd5b9250929050565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b600060018201610a3b57610a3b610a13565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c08789031215610a7157600080fd5b86358015158114610a8157600080fd5b95506020870135610a91816107f7565b94506040870135610aa1816107f7565b9350606087013592506080870135915060a087013567ffffffffffffffff80821115610acc57600080fd5b818901915089601f830112610ae057600080fd5b813581811115610af257610af2610a42565b604051601f8201601f19908116603f01168101908382118183101715610b1a57610b1a610a42565b816040528281528c6020848701011115610b3357600080fd5b8260208601602083013760006020848301015280955050505050509295509295509295565b80820180821115610b6b57610b6b610a13565b92915050565b6000825160005b81811015610b925760208186018101518583015201610b78565b50600092019182525091905056fea2646970667358221220f5fa6a6743dd98e2a67d7d49a46b5902aa8d936b63047003dda7291a273b7f3664736f6c634300081300330000000000000000000000000e1b5ab67af1c99f8c7ebc71f41f75d4d6211e5300000000000000000000000012efda5e4d410c5da723ceb7e43942779e3fe49b
Deployed Bytecode
0x60806040526004361061008f5760003560e01c80638da5cb5b116100565780638da5cb5b1461014357806391dda0bd146101615780639f08b95114610181578063b980c2e2146101a1578063df2ebdbb146101b457005b806320f99c0a146100985780633bd1adec146100ce5780633dfc50d3146100e35780635b94db27146101035780636ccae0541461012357005b3661009657005b005b3480156100a457600080fd5b506001546001600160a01b03165b6040516001600160a01b03909116815260200160405180910390f35b3480156100da57600080fd5b506100966101dc565b3480156100ef57600080fd5b506002546100b2906001600160a01b031681565b34801561010f57600080fd5b5061009661011e36600461080f565b610212565b34801561012f57600080fd5b5061009661013e366004610833565b610287565b34801561014f57600080fd5b506000546001600160a01b03166100b2565b34801561016d57600080fd5b5061009661017c366004610874565b6102c2565b34801561018d57600080fd5b5061009661019c36600461080f565b61041b565b6100966101af3660046108e9565b610468565b3480156101c057600080fd5b506100b273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6001546001600160a01b0316331461020757604051637c91ccdd60e01b815260040160405180910390fd5b61021033610663565b565b6000546001600160a01b0316331461023d57604051635fc483c560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b6000546001600160a01b031633146102b257604051635fc483c560e01b815260040160405180910390fd5b6102bd8383836106b6565b505050565b6000546001600160a01b031633146102ed57604051635fc483c560e01b815260040160405180910390fd5b60005b818110156102bd57600083838381811061030c5761030c61097f565b905060200281019061031e9190610995565b61032c90602081019061080f565b6001600160a01b03168484848181106103475761034761097f565b90506020028101906103599190610995565b6020013585858581811061036f5761036f61097f565b90506020028101906103819190610995565b61038f9060408101906109b5565b60405161039d929190610a03565b60006040518083038185875af1925050503d80600081146103da576040519150601f19603f3d011682016040523d82523d6000602084013e6103df565b606091505b50509050806104085760405163505737f760e11b81526004810183905260240160405180910390fd5b508061041381610a29565b9150506102f0565b6000546001600160a01b0316331461044657604051635fc483c560e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331461049357604051634a8f4afb60e01b815260040160405180910390fd5b600080808080806104a687890189610a58565b95509550955095509550955060001982146104f15780516104c8836020610b58565b11156104e75760405163eb9bc44760e01b815260040160405180910390fd5b8082016020018990525b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038b16016105c45788341461053657604051631841b4e160e01b815260040160405180910390fd5b60006001600160a01b03851661054c858c610b58565b8360405161055a9190610b71565b60006040518083038185875af1925050503d8060008114610597576040519150601f19603f3d011682016040523d82523d6000602084013e61059c565b606091505b50509050806105be576040516361dcf76f60e11b815260040160405180910390fd5b50610656565b85156105d5576105d58a868b610742565b6000846001600160a01b031684836040516105f09190610b71565b60006040518083038185875af1925050503d806000811461062d576040519150601f19603f3d011682016040523d82523d6000602084013e610632565b606091505b5050905080610654576040516361dcf76f60e11b815260040160405180910390fd5b505b5050505050505050505050565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b6001600160a01b0382166106dd5760405163d92e233d60e01b815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0384160161070c576102bd8282610792565b826001600160a01b03163b60000361073757604051630f58058360e11b815260040160405180910390fd5b6102bd8383836107b2565b816014528060345263095ea7b360601b60005260206000604460106000875af1806001600051141661078757803d853b15171061078757633e3f8f736000526004601cfd5b506000603452505050565b60003860003884865af16107ae5763b12d13eb6000526004601cfd5b5050565b816014528060345263a9059cbb60601b60005260206000604460106000875af1806001600051141661078757803d853b151710610787576390b8ec186000526004601cfd5b6001600160a01b038116811461080c57600080fd5b50565b60006020828403121561082157600080fd5b813561082c816107f7565b9392505050565b60008060006060848603121561084857600080fd5b8335610853816107f7565b92506020840135610863816107f7565b929592945050506040919091013590565b6000806020838503121561088757600080fd5b823567ffffffffffffffff8082111561089f57600080fd5b818501915085601f8301126108b357600080fd5b8135818111156108c257600080fd5b8660208260051b85010111156108d757600080fd5b60209290920196919550909350505050565b60008060008060006080868803121561090157600080fd5b853594506020860135610913816107f7565b935060408601359250606086013567ffffffffffffffff8082111561093757600080fd5b818801915088601f83011261094b57600080fd5b81358181111561095a57600080fd5b89602082850101111561096c57600080fd5b9699959850939650602001949392505050565b634e487b7160e01b600052603260045260246000fd5b60008235605e198336030181126109ab57600080fd5b9190910192915050565b6000808335601e198436030181126109cc57600080fd5b83018035915067ffffffffffffffff8211156109e757600080fd5b6020019150368190038213156109fc57600080fd5b9250929050565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b600060018201610a3b57610a3b610a13565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c08789031215610a7157600080fd5b86358015158114610a8157600080fd5b95506020870135610a91816107f7565b94506040870135610aa1816107f7565b9350606087013592506080870135915060a087013567ffffffffffffffff80821115610acc57600080fd5b818901915089601f830112610ae057600080fd5b813581811115610af257610af2610a42565b604051601f8201601f19908116603f01168101908382118183101715610b1a57610b1a610a42565b816040528281528c6020848701011115610b3357600080fd5b8260208601602083013760006020848301015280955050505050509295509295509295565b80820180821115610b6b57610b6b610a13565b92915050565b6000825160005b81811015610b925760208186018101518583015201610b78565b50600092019182525091905056fea2646970667358221220f5fa6a6743dd98e2a67d7d49a46b5902aa8d936b63047003dda7291a273b7f3664736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000e1b5ab67af1c99f8c7ebc71f41f75d4d6211e5300000000000000000000000012efda5e4d410c5da723ceb7e43942779e3fe49b
-----Decoded View---------------
Arg [0] : _owner (address): 0x0E1B5AB67aF1c99F8c7Ebc71f41f75D4D6211e53
Arg [1] : _stakedRouterExecutor (address): 0x12EFda5e4D410C5Da723ceb7E43942779E3FE49b
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000e1b5ab67af1c99f8c7ebc71f41f75d4d6211e53
Arg [1] : 00000000000000000000000012efda5e4d410c5da723ceb7e43942779e3fe49b
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$2.27
Net Worth in MON
Token Allocations
LINK
53.60%
ETH
36.46%
UBTC
5.34%
Others
4.59%
Multichain Portfolio | 35 Chains
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.