Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 6775577 | 214 days ago | 1 HYPE | ||||
| 6775577 | 214 days ago | 1 HYPE | ||||
| 6766763 | 214 days ago | 108.17558874 HYPE | ||||
| 6766763 | 214 days ago | 108.17558874 HYPE | ||||
| 6739995 | 214 days ago | 1 HYPE | ||||
| 6739995 | 214 days ago | 1 HYPE | ||||
| 6739423 | 214 days ago | 0.28952955 HYPE | ||||
| 6739423 | 214 days ago | 0.28952955 HYPE | ||||
| 6739311 | 214 days ago | 0.1 HYPE | ||||
| 6739311 | 214 days ago | 0.1 HYPE | ||||
| 6739146 | 214 days ago | 0.1 HYPE | ||||
| 6739146 | 214 days ago | 0.1 HYPE | ||||
| 6712015 | 215 days ago | 0.99863081 HYPE | ||||
| 6712015 | 215 days ago | 0.99863081 HYPE | ||||
| 6711892 | 215 days ago | 1 HYPE | ||||
| 6711892 | 215 days ago | 1 HYPE | ||||
| 6709080 | 215 days ago | 2.36912611 HYPE | ||||
| 6709080 | 215 days ago | 2.36912611 HYPE | ||||
| 6708884 | 215 days ago | 1 HYPE | ||||
| 6708884 | 215 days ago | 1 HYPE | ||||
| 6200453 | 221 days ago | 1.08504141 HYPE | ||||
| 6200453 | 221 days ago | 1.08504141 HYPE | ||||
| 6200014 | 221 days ago | 1.43930518 HYPE | ||||
| 6200014 | 221 days ago | 1.43930518 HYPE | ||||
| 6195336 | 221 days ago | Contract Creation | 0 HYPE |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GluexExecutor
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
No with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import {EthReceiver} from "./utils/EthReceiver.sol";
import {Interaction} from "./base/RouterStructs.sol";
import {IExecutor} from "./interfaces/IExecutor.sol";
import {IERC20} from "./interfaces/IERC20.sol";
import {IWrappedNativeToken} from "./interfaces/IWrappedNativeToken.sol";
import {SafeERC20} from "./lib/SafeERC20.sol";
/**
* @title GluexExecutor
* @notice A contract that executes an array of interactions as specified by the caller.
* @dev This contract processes a sequence of interactions by invoking the target contract methods with provided call data and values.
*/
contract GluexExecutor is EthReceiver, IExecutor {
using SafeERC20 for IERC20;
// Errors
/**
* @notice Error emitted when an execution call fails.
* @param target The target address of the failed call.
* @param callData The call data sent to the target.
* @param failureData The data returned from the failed call.
*/
error FailedExecutionCall(
address target,
bytes callData,
bytes failureData
);
error InsufficientBalance();
error NativeTransferFailed();
error OnlyGlueTreasury();
error ZeroAddress();
// Constants
uint256 private _RAW_CALL_GAS_LIMIT = 5000;
// State Variables
address private immutable _gluexRouter;
address private immutable _glueTreasury;
address private immutable _nativeToken;
address private immutable _wrappedNativeToken;
/**
* @notice Constructs the GluexExecutor contract.
* @param gluexRouter The address of the GluexRouter contract.
* @param gluexTreasury The address of the GluexTreasury contract.
* @param nativeToken The address of the native token used by the contract.
* @param wrappedNativeToken The address of the wrapped native token used by the contract.
*/
constructor(
address gluexRouter,
address gluexTreasury,
address nativeToken,
address wrappedNativeToken
) {
// Ensure the address is not zero
checkZeroAddress(gluexRouter);
checkZeroAddress(gluexTreasury);
_gluexRouter = gluexRouter;
_glueTreasury = gluexTreasury;
_nativeToken = nativeToken;
_wrappedNativeToken = wrappedNativeToken;
}
/**
* @dev Modifier to restrict access to treasury-only functions.
*/
modifier onlyTreasury() {
checkTreasury();
_;
}
/**
* @notice Verifies the caller is the Glue treasury.
* @dev Reverts with `OnlyGlueTreasury` if the caller is not the treasury.
*/
function checkTreasury() internal view {
if (msg.sender != _glueTreasury) revert OnlyGlueTreasury();
}
/**
* @notice Verifies the given address is not zero.
* @param addr The address to verify.
* @dev Reverts with `ZeroAddress` if the address is zero.
*/
function checkZeroAddress(address addr) internal pure {
if (addr == address(0)) revert ZeroAddress();
}
/**
* @notice Executes a series of interactions by making low-level calls to the specified targets.
* @param interactions An array of `Interaction` structs, each containing the target address,
* call data, and value to be sent with the call.
* @dev Each interaction is executed sequentially. If any call fails, the function reverts with
* detailed information about the failed interaction.
*/
function executeRoute(
Interaction[] calldata interactions,
IERC20 outputToken
) external payable {
// Execute interactions sequentially
uint256 len = interactions.length;
IERC20 balanceToken;
if (address(outputToken) == _nativeToken) {
balanceToken = IERC20(_wrappedNativeToken);
} else {
balanceToken = outputToken;
}
for (uint256 i; i < len; ) {
// Perform the interaction via a low-level call
(bool success, bytes memory response) = interactions[i].target.call{
value: interactions[i].value
}(interactions[i].callData);
// Revert if the call fails
if (!success) {
revert FailedExecutionCall(
interactions[i].target,
interactions[i].callData,
response
);
}
unchecked {
++i;
}
}
uint256 outputAmountWithSlippage = uniBalanceOf(balanceToken, address(this));
if (address(outputToken) == _nativeToken) {
// Apply slippage adjusted unwrapping of native token
IWrappedNativeToken(_wrappedNativeToken).withdraw(outputAmountWithSlippage);
}
// Transfer the output token to the GluexRouter
if (outputAmountWithSlippage > 0)
uniTransfer(
outputToken,
payable(_gluexRouter),
outputAmountWithSlippage
);
}
/**
* @notice Retrieves the balance of a specified token for a given account.
* @param token The ERC20 token to check.
* @param account The account address to query the balance for.
* @return The balance of the token for the account.
*/
function uniBalanceOf(
IERC20 token,
address account
) internal view returns (uint256) {
if (address(token) == _nativeToken) {
uint256 contractBalance;
assembly {
contractBalance := balance(account)
}
return contractBalance;
} else {
return token.balanceOf(account);
}
}
/**
* @notice Transfers a specified amount of a token to a given address.
* @param token The ERC20 token to transfer.
* @param to The address to transfer the token to.
* @param amount The amount of the token to transfer.
* @dev Handles both native token and ERC20 transfers.
*/
function uniTransfer(
IERC20 token,
address payable to,
uint256 amount
) internal {
if (amount > 0) {
if (address(token) == _nativeToken) {
uint256 contractBalance;
assembly {
contractBalance := selfbalance()
}
if (contractBalance < amount) revert InsufficientBalance();
(bool success, ) = to.call{
value: amount,
gas: _RAW_CALL_GAS_LIMIT
}("");
if (!success) revert NativeTransferFailed();
} else {
token.safeTransfer(to, amount);
}
} else {
revert InsufficientBalance();
}
}
/**
* @notice Updates the gas limit for raw calls made by the contract.
* @param gasLimit The new gas limit to be set.
* @dev This function is restricted to the treasury.
*/
function setGasLimit(uint256 gasLimit) external onlyTreasury {
_RAW_CALL_GAS_LIMIT = gasLimit;
}
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
/// @dev generic smart contract interaction
struct Interaction {
address target;
uint256 value;
bytes callData;
}// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; // File @1inch/solidity-utils/contracts/interfaces/[email protected] interface IDaiLikePermit { function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value
) external returns (bool);
}// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import {Interaction} from "../base/RouterStructs.sol";
import {IERC20} from "./IERC20.sol";
/// @title Interface for making arbitrary calls
interface IExecutor {
/// @notice propagates information about original msg.sender and executes arbitrary data
function executeRoute(
Interaction[] calldata interactions,
IERC20 outputToken
) external payable;
}// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; // File @1inch/solidity-utils/contracts/interfaces/[email protected] interface IPermit2 { struct PermitDetails { // ERC20 token address address token; // the maximum amount allowed to spend uint160 amount; // timestamp at which a spender's token allowances become invalid uint48 expiration; // an incrementing value indexed per owner,token,and spender for each signature uint48 nonce; } /// @notice The permit message signed for a single token allownce struct PermitSingle { // the permit data for a single token alownce PermitDetails details; // address permissioned on the allowed tokens address spender; // deadline on the permit signature uint256 sigDeadline; } /// @notice Packed allowance struct PackedAllowance { // amount allowed uint160 amount; // permission expiry uint48 expiration; // an incrementing value indexed per owner,token,and spender for each signature uint48 nonce; } function transferFrom( address user, address spender, uint160 amount, address token ) external; function permit( address owner, PermitSingle memory permitSingle, bytes calldata signature ) external; function allowance( address user, address token, address spender ) external view returns (PackedAllowance memory); }
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
/**
* @dev Generic interface for native tokens.
*
* Note that this interface may require adjustment
* per chain.
*/
interface IWrappedNativeToken {
/**
* @dev Returns amount deposited into native wrapper.
*/
function deposit() external payable;
/**
* @dev Returns amount withdrawn from native wrapper.
*/
function withdraw(uint wad) external;
}// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; // File @1inch/solidity-utils/contracts/libraries/[email protected] /// @title Revert reason forwarder. library RevertReasonForwarder { /// @dev Forwards latest externall call revert. function reRevert() internal pure { // bubble up revert reason from latest external call assembly ("memory-safe") { // solhint-disable-line no-inline-assembly let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } } /// @dev Returns latest external call revert reason. function reReason() internal pure returns (bytes memory reason) { assembly ("memory-safe") { // solhint-disable-line no-inline-assembly reason := mload(0x40) let length := returndatasize() mstore(reason, length) returndatacopy(add(reason, 0x20), 0, length) mstore(0x40, add(reason, add(0x20, length))) } } }
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import {IERC20} from "../interfaces/IERC20.sol";
import {IPermit2} from "../interfaces/IPermit2.sol";
import {IERC20Permit} from "../interfaces/IERC20Permit.sol";
import {IDaiLikePermit} from "../interfaces/IDaiLikePermit.sol";
import {RevertReasonForwarder} from "../lib/RevertReasonForwarder.sol";
// File @1inch/solidity-utils/contracts/libraries/[email protected]
/**
* @title Implements efficient safe methods for ERC20 interface.
* @notice Compared to the standard ERC20, this implementation offers several enhancements:
* 1. more gas-efficient, providing significant savings in transaction costs.
* 2. support for different permit implementations
* 3. forceApprove functionality
* 4. support for WETH deposit and withdraw
*/
library SafeERC20 {
error SafeTransferFailed();
error SafeTransferFromFailed();
error ForceApproveFailed();
error SafeIncreaseAllowanceFailed();
error SafeDecreaseAllowanceFailed();
error SafePermitBadLength();
error Permit2TransferAmountTooHigh();
// Uniswap Permit2 address
address private constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
bytes4 private constant _PERMIT_LENGTH_ERROR = 0x68275857; // SafePermitBadLength.selector
uint256 private constant _RAW_CALL_GAS_LIMIT = 5000;
/**
* @notice Fetches the balance of a specific ERC20 token held by an account.
* Consumes less gas then regular `ERC20.balanceOf`.
* @dev Note that the implementation does not perform dirty bits cleaning, so it is the
* responsibility of the caller to make sure that the higher 96 bits of the `account` parameter are clean.
* @param token The IERC20 token contract for which the balance will be fetched.
* @param account The address of the account whose token balance will be fetched.
* @return tokenBalance The balance of the specified ERC20 token held by the account.
*/
function safeBalanceOf(
IERC20 token,
address account
) internal view returns (uint256 tokenBalance) {
bytes4 selector = IERC20.balanceOf.selector;
assembly ("memory-safe") {
// solhint-disable-line no-inline-assembly
mstore(0x00, selector)
mstore(0x04, account)
let success := staticcall(gas(), token, 0x00, 0x24, 0x00, 0x20)
tokenBalance := mload(0)
if or(iszero(success), lt(returndatasize(), 0x20)) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
}
}
/**
* @notice Attempts to safely transfer tokens from one address to another.
* @dev If permit2 is true, uses the Permit2 standard; otherwise uses the standard ERC20 transferFrom.
* Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of
* the caller to make sure that the higher 96 bits of the `from` and `to` parameters are clean.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param from The address from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param amount The amount of tokens to transfer.
* @param permit2 If true, uses the Permit2 standard for the transfer; otherwise uses the standard ERC20 transferFrom.
*/
function safeTransferFromUniversal(
IERC20 token,
address from,
address to,
uint256 amount,
bool permit2
) internal {
if (permit2) {
safeTransferFromPermit2(token, from, to, amount);
} else {
safeTransferFrom(token, from, to, amount);
}
}
/**
* @notice Attempts to safely transfer tokens from one address to another using the ERC20 standard.
* @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of
* the caller to make sure that the higher 96 bits of the `from` and `to` parameters are clean.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param from The address from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param amount The amount of tokens to transfer.
*/
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 amount
) internal {
bytes4 selector = token.transferFrom.selector;
bool success;
assembly ("memory-safe") {
// solhint-disable-line no-inline-assembly
let data := mload(0x40)
mstore(data, selector)
mstore(add(data, 0x04), from)
mstore(add(data, 0x24), to)
mstore(add(data, 0x44), amount)
success := call(gas(), token, 0, data, 100, 0x0, 0x20)
if success {
switch returndatasize()
case 0 {
success := gt(extcodesize(token), 0)
}
default {
success := and(gt(returndatasize(), 31), eq(mload(0), 1))
}
}
}
if (!success) revert SafeTransferFromFailed();
}
/**
* @notice Attempts to safely transfer tokens from one address to another using the Permit2 standard.
* @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of
* the caller to make sure that the higher 96 bits of the `from` and `to` parameters are clean.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param from The address from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param amount The amount of tokens to transfer.
*/
function safeTransferFromPermit2(
IERC20 token,
address from,
address to,
uint256 amount
) internal {
if (amount > type(uint160).max) revert Permit2TransferAmountTooHigh();
bytes4 selector = IPermit2.transferFrom.selector;
bool success;
assembly ("memory-safe") {
// solhint-disable-line no-inline-assembly
let data := mload(0x40)
mstore(data, selector)
mstore(add(data, 0x04), from)
mstore(add(data, 0x24), to)
mstore(add(data, 0x44), amount)
mstore(add(data, 0x64), token)
success := call(gas(), _PERMIT2, 0, data, 0x84, 0x0, 0x0)
if success {
success := gt(extcodesize(_PERMIT2), 0)
}
}
if (!success) revert SafeTransferFromFailed();
}
/**
* @notice Attempts to safely transfer tokens to another address.
* @dev Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of
* the caller to make sure that the higher 96 bits of the `to` parameter are clean.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param to The address to which the tokens will be transferred.
* @param value The amount of tokens to transfer.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
if (!_makeCall(token, token.transfer.selector, to, value)) {
revert SafeTransferFailed();
}
}
/**
* @notice Attempts to execute the `permit` function on the provided token with the sender and contract as parameters.
* Permit type is determined automatically based on permit calldata (IERC20Permit, IDaiLikePermit, and IPermit2).
* @dev Wraps `tryPermit` function and forwards revert reason if permit fails.
* @param token The IERC20 token to execute the permit function on.
* @param permit The permit data to be used in the function call.
*/
function safePermit(IERC20 token, bytes calldata permit) internal {
if (!tryPermit(token, msg.sender, address(this), permit))
RevertReasonForwarder.reRevert();
}
/**
* @notice Attempts to execute the `permit` function on the provided token with custom owner and spender parameters.
* Permit type is determined automatically based on permit calldata (IERC20Permit, IDaiLikePermit, and IPermit2).
* @dev Wraps `tryPermit` function and forwards revert reason if permit fails.
* Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of
* the caller to make sure that the higher 96 bits of the `owner` and `spender` parameters are clean.
* @param token The IERC20 token to execute the permit function on.
* @param owner The owner of the tokens for which the permit is made.
* @param spender The spender allowed to spend the tokens by the permit.
* @param permit The permit data to be used in the function call.
*/
function safePermit(
IERC20 token,
address owner,
address spender,
bytes calldata permit
) internal {
if (!tryPermit(token, owner, spender, permit))
RevertReasonForwarder.reRevert();
}
/**
* @notice Attempts to execute the `permit` function on the provided token with the sender and contract as parameters.
* @dev Invokes `tryPermit` with sender as owner and contract as spender.
* @param token The IERC20 token to execute the permit function on.
* @param permit The permit data to be used in the function call.
* @return success Returns true if the permit function was successfully executed, false otherwise.
*/
function tryPermit(
IERC20 token,
bytes calldata permit
) internal returns (bool success) {
return tryPermit(token, msg.sender, address(this), permit);
}
/**
* @notice The function attempts to call the permit function on a given ERC20 token.
* @dev The function is designed to support a variety of permit functions, namely: IERC20Permit, IDaiLikePermit, and IPermit2.
* It accommodates both Compact and Full formats of these permit types.
* Please note, it is expected that the `expiration` parameter for the compact Permit2 and the `deadline` parameter
* for the compact Permit are to be incremented by one before invoking this function. This approach is motivated by
* gas efficiency considerations; as the unlimited expiration period is likely to be the most common scenario, and
* zeros are cheaper to pass in terms of gas cost. Thus, callers should increment the expiration or deadline by one
* before invocation for optimized performance.
* Note that the implementation does not perform dirty bits cleaning, so it is the responsibility of
* the caller to make sure that the higher 96 bits of the `owner` and `spender` parameters are clean.
* @param token The address of the ERC20 token on which to call the permit function.
* @param owner The owner of the tokens. This address should have signed the off-chain permit.
* @param spender The address which will be approved for transfer of tokens.
* @param permit The off-chain permit data, containing different fields depending on the type of permit function.
* @return success A boolean indicating whether the permit call was successful.
*/
function tryPermit(
IERC20 token,
address owner,
address spender,
bytes calldata permit
) internal returns (bool success) {
// load function selectors for different permit standards
bytes4 permitSelector = IERC20Permit.permit.selector;
bytes4 daiPermitSelector = IDaiLikePermit.permit.selector;
bytes4 permit2Selector = IPermit2.permit.selector;
assembly ("memory-safe") {
// solhint-disable-line no-inline-assembly
let ptr := mload(0x40)
// Switch case for different permit lengths, indicating different permit standards
switch permit.length
// Compact IERC20Permit
case 100 {
mstore(ptr, permitSelector) // store selector
mstore(add(ptr, 0x04), owner) // store owner
mstore(add(ptr, 0x24), spender) // store spender
// Compact IERC20Permit.permit(uint256 value, uint32 deadline, uint256 r, uint256 vs)
{
// stack too deep
let deadline := shr(
224,
calldataload(add(permit.offset, 0x20))
) // loads permit.offset 0x20..0x23
let vs := calldataload(add(permit.offset, 0x44)) // loads permit.offset 0x44..0x63
calldatacopy(add(ptr, 0x44), permit.offset, 0x20) // store value = copy permit.offset 0x00..0x19
mstore(add(ptr, 0x64), sub(deadline, 1)) // store deadline = deadline - 1
mstore(add(ptr, 0x84), add(27, shr(255, vs))) // store v = most significant bit of vs + 27 (27 or 28)
calldatacopy(add(ptr, 0xa4), add(permit.offset, 0x24), 0x20) // store r = copy permit.offset 0x24..0x43
mstore(add(ptr, 0xc4), shr(1, shl(1, vs))) // store s = vs without most significant bit
}
// IERC20Permit.permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0xe4, 0, 0)
}
// Compact IDaiLikePermit
case 72 {
mstore(ptr, daiPermitSelector) // store selector
mstore(add(ptr, 0x04), owner) // store owner
mstore(add(ptr, 0x24), spender) // store spender
// Compact IDaiLikePermit.permit(uint32 nonce, uint32 expiry, uint256 r, uint256 vs)
{
// stack too deep
let expiry := shr(
224,
calldataload(add(permit.offset, 0x04))
) // loads permit.offset 0x04..0x07
let vs := calldataload(add(permit.offset, 0x28)) // loads permit.offset 0x28..0x47
mstore(
add(ptr, 0x44),
shr(224, calldataload(permit.offset))
) // store nonce = copy permit.offset 0x00..0x03
mstore(add(ptr, 0x64), sub(expiry, 1)) // store expiry = expiry - 1
mstore(add(ptr, 0x84), true) // store allowed = true
mstore(add(ptr, 0xa4), add(27, shr(255, vs))) // store v = most significant bit of vs + 27 (27 or 28)
calldatacopy(add(ptr, 0xc4), add(permit.offset, 0x08), 0x20) // store r = copy permit.offset 0x08..0x27
mstore(add(ptr, 0xe4), shr(1, shl(1, vs))) // store s = vs without most significant bit
}
// IDaiLikePermit.permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0x104, 0, 0)
}
// IERC20Permit
case 224 {
mstore(ptr, permitSelector)
calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata
// IERC20Permit.permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0xe4, 0, 0)
}
// IDaiLikePermit
case 256 {
mstore(ptr, daiPermitSelector)
calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata
// IDaiLikePermit.permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, 0x104, 0, 0)
}
// Compact IPermit2
case 96 {
// Compact IPermit2.permit(uint160 amount, uint32 expiration, uint32 nonce, uint32 sigDeadline, uint256 r, uint256 vs)
mstore(ptr, permit2Selector) // store selector
mstore(add(ptr, 0x04), owner) // store owner
mstore(add(ptr, 0x24), token) // store token
calldatacopy(add(ptr, 0x50), permit.offset, 0x14) // store amount = copy permit.offset 0x00..0x13
// and(0xffffffffffff, ...) - conversion to uint48
mstore(
add(ptr, 0x64),
and(
0xffffffffffff,
sub(shr(224, calldataload(add(permit.offset, 0x14))), 1)
)
) // store expiration = ((permit.offset 0x14..0x17 - 1) & 0xffffffffffff)
mstore(
add(ptr, 0x84),
shr(224, calldataload(add(permit.offset, 0x18)))
) // store nonce = copy permit.offset 0x18..0x1b
mstore(add(ptr, 0xa4), spender) // store spender
// and(0xffffffffffff, ...) - conversion to uint48
mstore(
add(ptr, 0xc4),
and(
0xffffffffffff,
sub(shr(224, calldataload(add(permit.offset, 0x1c))), 1)
)
) // store sigDeadline = ((permit.offset 0x1c..0x1f - 1) & 0xffffffffffff)
mstore(add(ptr, 0xe4), 0x100) // store offset = 256
mstore(add(ptr, 0x104), 0x40) // store length = 64
calldatacopy(add(ptr, 0x124), add(permit.offset, 0x20), 0x20) // store r = copy permit.offset 0x20..0x3f
calldatacopy(add(ptr, 0x144), add(permit.offset, 0x40), 0x20) // store vs = copy permit.offset 0x40..0x5f
// IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)
success := call(gas(), _PERMIT2, 0, ptr, 0x164, 0, 0)
}
// IPermit2
case 352 {
mstore(ptr, permit2Selector)
calldatacopy(add(ptr, 0x04), permit.offset, permit.length) // copy permit calldata
// IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)
success := call(gas(), _PERMIT2, 0, ptr, 0x164, 0, 0)
}
// Unknown
default {
mstore(ptr, _PERMIT_LENGTH_ERROR)
revert(ptr, 4)
}
}
}
/**
* @dev Executes a low level call to a token contract, making it resistant to reversion and erroneous boolean returns.
* @param token The IERC20 token contract on which the call will be made.
* @param selector The function signature that is to be called on the token contract.
* @param to The address to which the token amount will be transferred.
* @param amount The token amount to be transferred.
* @return success A boolean indicating if the call was successful. Returns 'true' on success and 'false' on failure.
* In case of success but no returned data, validates that the contract code exists.
* In case of returned data, ensures that it's a boolean `true`.
*/
function _makeCall(
IERC20 token,
bytes4 selector,
address to,
uint256 amount
) private returns (bool success) {
assembly ("memory-safe") {
// solhint-disable-line no-inline-assembly
let data := mload(0x40)
mstore(data, selector)
mstore(add(data, 0x04), to)
mstore(add(data, 0x24), amount)
success := call(gas(), token, 0, data, 0x44, 0x0, 0x20)
if success {
switch returndatasize()
case 0 {
success := gt(extcodesize(token), 0)
}
default {
success := and(gt(returndatasize(), 31), eq(mload(0), 1))
}
}
}
}
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
abstract contract EthReceiver {
error EthDepositRejected();
receive() external payable {
_receive();
}
function _receive() internal virtual {
// solhint-disable-next-line avoid-tx-origin
if (msg.sender == tx.origin) revert EthDepositRejected();
}
}{
"evmVersion": "cancun",
"libraries": {},
"optimizer": {
"enabled": false,
"runs": 200
},
"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":"gluexRouter","type":"address"},{"internalType":"address","name":"gluexTreasury","type":"address"},{"internalType":"address","name":"nativeToken","type":"address"},{"internalType":"address","name":"wrappedNativeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EthDepositRejected","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"failureData","type":"bytes"}],"name":"FailedExecutionCall","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[],"name":"OnlyGlueTreasury","type":"error"},{"inputs":[],"name":"SafeTransferFailed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct Interaction[]","name":"interactions","type":"tuple[]"},{"internalType":"contract IERC20","name":"outputToken","type":"address"}],"name":"executeRoute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasLimit","type":"uint256"}],"name":"setGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6101006040526113885f5534801562000016575f80fd5b5060405162000fd138038062000fd183398181016040528101906200003c919062000206565b6200004d846200013860201b60201c565b6200005e836200013860201b60201c565b8373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508173ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250505050505062000275565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200019e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620001d082620001a5565b9050919050565b620001e281620001c4565b8114620001ed575f80fd5b50565b5f815190506200020081620001d7565b92915050565b5f805f8060808587031215620002215762000220620001a1565b5b5f6200023087828801620001f0565b94505060206200024387828801620001f0565b93505060406200025687828801620001f0565b92505060606200026987828801620001f0565b91505092959194509250565b60805160a05160c05160e051610d0d620002c45f395f8181610147015261039701525f818160f4015281816103440152818161046c015261055601525f6106f901525f61042a0152610d0d5ff3fe60806040526004361061002c575f3560e01c8063c0dcf8041461003f578063ee7d72b41461005b5761003b565b3661003b57610039610083565b005b5f80fd5b610059600480360381019061005491906108f0565b6100ea565b005b348015610066575f80fd5b50610081600480360381019061007c9190610980565b610458565b005b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036100e8576040517f1b10b0f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f8383905090505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361016d577f00000000000000000000000000000000000000000000000000000000000000009050610171565b8290505b5f5b82811015610334575f808787848181106101905761018f6109ab565b5b90506020028101906101a291906109e4565b5f0160208101906101b39190610a35565b73ffffffffffffffffffffffffffffffffffffffff168888858181106101dc576101db6109ab565b5b90506020028101906101ee91906109e4565b60200135898986818110610205576102046109ab565b5b905060200281019061021791906109e4565b80604001906102269190610a60565b604051610234929190610afe565b5f6040518083038185875af1925050503d805f811461026e576040519150601f19603f3d011682016040523d82523d5f602084013e610273565b606091505b509150915081610327578787848181106102905761028f6109ab565b5b90506020028101906102a291906109e4565b5f0160208101906102b39190610a35565b8888858181106102c6576102c56109ab565b5b90506020028101906102d891906109e4565b80604001906102e79190610a60565b836040517f97474f3900000000000000000000000000000000000000000000000000000000815260040161031e9493929190610bdb565b60405180910390fd5b8260010192505050610173565b505f6103408230610469565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361041c577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b81526004016103ee9190610c2f565b5f604051808303815f87803b158015610405575f80fd5b505af1158015610417573d5f803e3d5ffd5b505050505b5f8111156104505761044f847f00000000000000000000000000000000000000000000000000000000000000008361054c565b5b505050505050565b6104606106f7565b805f8190555050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036104cb575f8231905080915050610546565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016105049190610c48565b602060405180830381865afa15801561051f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105439190610c75565b90505b92915050565b5f8111156106c0577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361068f575f479050818110156105e5576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8373ffffffffffffffffffffffffffffffffffffffff16835f549060405161060d90610cc3565b5f60405180830381858888f193505050503d805f8114610648576040519150601f19603f3d011682016040523d82523d5f602084013e61064d565b606091505b5050905080610688576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50506106bb565b6106ba82828573ffffffffffffffffffffffffffffffffffffffff1661077e9092919063ffffffff16565b5b6106f2565b6040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461077c576040517ffcb6435400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6107918363a9059cbb60e01b84846107cc565b6107c7576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b5f60405184815283600482015282602482015260205f6044835f8a5af191508115610813573d5f811461080a5760015f5114601f3d11169250610811565b5f873b1192505b505b50949350505050565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261084557610844610824565b5b8235905067ffffffffffffffff81111561086257610861610828565b5b60208301915083602082028301111561087e5761087d61082c565b5b9250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6108ae82610885565b9050919050565b5f6108bf826108a4565b9050919050565b6108cf816108b5565b81146108d9575f80fd5b50565b5f813590506108ea816108c6565b92915050565b5f805f604084860312156109075761090661081c565b5b5f84013567ffffffffffffffff81111561092457610923610820565b5b61093086828701610830565b93509350506020610943868287016108dc565b9150509250925092565b5f819050919050565b61095f8161094d565b8114610969575f80fd5b50565b5f8135905061097a81610956565b92915050565b5f602082840312156109955761099461081c565b5b5f6109a28482850161096c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80fd5b5f80fd5b5f80fd5b5f823560016060038336030381126109ff576109fe6109d8565b5b80830191505092915050565b610a14816108a4565b8114610a1e575f80fd5b50565b5f81359050610a2f81610a0b565b92915050565b5f60208284031215610a4a57610a4961081c565b5b5f610a5784828501610a21565b91505092915050565b5f8083356001602003843603038112610a7c57610a7b6109d8565b5b80840192508235915067ffffffffffffffff821115610a9e57610a9d6109dc565b5b602083019250600182023603831315610aba57610ab96109e0565b5b509250929050565b5f81905092915050565b828183375f83830152505050565b5f610ae58385610ac2565b9350610af2838584610acc565b82840190509392505050565b5f610b0a828486610ada565b91508190509392505050565b610b1f816108a4565b82525050565b5f82825260208201905092915050565b5f601f19601f8301169050919050565b5f610b508385610b25565b9350610b5d838584610acc565b610b6683610b35565b840190509392505050565b5f81519050919050565b5f5b83811015610b98578082015181840152602081019050610b7d565b5f8484015250505050565b5f610bad82610b71565b610bb78185610b25565b9350610bc7818560208601610b7b565b610bd081610b35565b840191505092915050565b5f606082019050610bee5f830187610b16565b8181036020830152610c01818587610b45565b90508181036040830152610c158184610ba3565b905095945050505050565b610c298161094d565b82525050565b5f602082019050610c425f830184610c20565b92915050565b5f602082019050610c5b5f830184610b16565b92915050565b5f81519050610c6f81610956565b92915050565b5f60208284031215610c8a57610c8961081c565b5b5f610c9784828501610c61565b91505092915050565b50565b5f610cae5f83610ac2565b9150610cb982610ca0565b5f82019050919050565b5f610ccd82610ca3565b915081905091905056fea2646970667358221220673d5c91e32daae5863dbea483033343000097a1d6f58c6a68ee351a4cd43c4c64736f6c63430008180033000000000000000000000000fd1c12f7bc0cc595486bb87860e985e91e96e4930000000000000000000000003cffef055725974e32a660a617fc999b67e9196e00000000000000000000000022222222222222222222222222222222222222220000000000000000000000005555555555555555555555555555555555555555
Deployed Bytecode
0x60806040526004361061002c575f3560e01c8063c0dcf8041461003f578063ee7d72b41461005b5761003b565b3661003b57610039610083565b005b5f80fd5b610059600480360381019061005491906108f0565b6100ea565b005b348015610066575f80fd5b50610081600480360381019061007c9190610980565b610458565b005b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036100e8576040517f1b10b0f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f8383905090505f7f000000000000000000000000222222222222222222222222222222222222222273ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361016d577f00000000000000000000000055555555555555555555555555555555555555559050610171565b8290505b5f5b82811015610334575f808787848181106101905761018f6109ab565b5b90506020028101906101a291906109e4565b5f0160208101906101b39190610a35565b73ffffffffffffffffffffffffffffffffffffffff168888858181106101dc576101db6109ab565b5b90506020028101906101ee91906109e4565b60200135898986818110610205576102046109ab565b5b905060200281019061021791906109e4565b80604001906102269190610a60565b604051610234929190610afe565b5f6040518083038185875af1925050503d805f811461026e576040519150601f19603f3d011682016040523d82523d5f602084013e610273565b606091505b509150915081610327578787848181106102905761028f6109ab565b5b90506020028101906102a291906109e4565b5f0160208101906102b39190610a35565b8888858181106102c6576102c56109ab565b5b90506020028101906102d891906109e4565b80604001906102e79190610a60565b836040517f97474f3900000000000000000000000000000000000000000000000000000000815260040161031e9493929190610bdb565b60405180910390fd5b8260010192505050610173565b505f6103408230610469565b90507f000000000000000000000000222222222222222222222222222222222222222273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361041c577f000000000000000000000000555555555555555555555555555555555555555573ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b81526004016103ee9190610c2f565b5f604051808303815f87803b158015610405575f80fd5b505af1158015610417573d5f803e3d5ffd5b505050505b5f8111156104505761044f847f000000000000000000000000fd1c12f7bc0cc595486bb87860e985e91e96e4938361054c565b5b505050505050565b6104606106f7565b805f8190555050565b5f7f000000000000000000000000222222222222222222222222222222222222222273ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036104cb575f8231905080915050610546565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016105049190610c48565b602060405180830381865afa15801561051f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105439190610c75565b90505b92915050565b5f8111156106c0577f000000000000000000000000222222222222222222222222222222222222222273ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361068f575f479050818110156105e5576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8373ffffffffffffffffffffffffffffffffffffffff16835f549060405161060d90610cc3565b5f60405180830381858888f193505050503d805f8114610648576040519150601f19603f3d011682016040523d82523d5f602084013e61064d565b606091505b5050905080610688576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50506106bb565b6106ba82828573ffffffffffffffffffffffffffffffffffffffff1661077e9092919063ffffffff16565b5b6106f2565b6040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b7f0000000000000000000000003cffef055725974e32a660a617fc999b67e9196e73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461077c576040517ffcb6435400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6107918363a9059cbb60e01b84846107cc565b6107c7576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b5f60405184815283600482015282602482015260205f6044835f8a5af191508115610813573d5f811461080a5760015f5114601f3d11169250610811565b5f873b1192505b505b50949350505050565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261084557610844610824565b5b8235905067ffffffffffffffff81111561086257610861610828565b5b60208301915083602082028301111561087e5761087d61082c565b5b9250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6108ae82610885565b9050919050565b5f6108bf826108a4565b9050919050565b6108cf816108b5565b81146108d9575f80fd5b50565b5f813590506108ea816108c6565b92915050565b5f805f604084860312156109075761090661081c565b5b5f84013567ffffffffffffffff81111561092457610923610820565b5b61093086828701610830565b93509350506020610943868287016108dc565b9150509250925092565b5f819050919050565b61095f8161094d565b8114610969575f80fd5b50565b5f8135905061097a81610956565b92915050565b5f602082840312156109955761099461081c565b5b5f6109a28482850161096c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80fd5b5f80fd5b5f80fd5b5f823560016060038336030381126109ff576109fe6109d8565b5b80830191505092915050565b610a14816108a4565b8114610a1e575f80fd5b50565b5f81359050610a2f81610a0b565b92915050565b5f60208284031215610a4a57610a4961081c565b5b5f610a5784828501610a21565b91505092915050565b5f8083356001602003843603038112610a7c57610a7b6109d8565b5b80840192508235915067ffffffffffffffff821115610a9e57610a9d6109dc565b5b602083019250600182023603831315610aba57610ab96109e0565b5b509250929050565b5f81905092915050565b828183375f83830152505050565b5f610ae58385610ac2565b9350610af2838584610acc565b82840190509392505050565b5f610b0a828486610ada565b91508190509392505050565b610b1f816108a4565b82525050565b5f82825260208201905092915050565b5f601f19601f8301169050919050565b5f610b508385610b25565b9350610b5d838584610acc565b610b6683610b35565b840190509392505050565b5f81519050919050565b5f5b83811015610b98578082015181840152602081019050610b7d565b5f8484015250505050565b5f610bad82610b71565b610bb78185610b25565b9350610bc7818560208601610b7b565b610bd081610b35565b840191505092915050565b5f606082019050610bee5f830187610b16565b8181036020830152610c01818587610b45565b90508181036040830152610c158184610ba3565b905095945050505050565b610c298161094d565b82525050565b5f602082019050610c425f830184610c20565b92915050565b5f602082019050610c5b5f830184610b16565b92915050565b5f81519050610c6f81610956565b92915050565b5f60208284031215610c8a57610c8961081c565b5b5f610c9784828501610c61565b91505092915050565b50565b5f610cae5f83610ac2565b9150610cb982610ca0565b5f82019050919050565b5f610ccd82610ca3565b915081905091905056fea2646970667358221220673d5c91e32daae5863dbea483033343000097a1d6f58c6a68ee351a4cd43c4c64736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fd1c12f7bc0cc595486bb87860e985e91e96e4930000000000000000000000003cffef055725974e32a660a617fc999b67e9196e00000000000000000000000022222222222222222222222222222222222222220000000000000000000000005555555555555555555555555555555555555555
-----Decoded View---------------
Arg [0] : gluexRouter (address): 0xFd1c12f7Bc0cc595486bB87860E985E91e96e493
Arg [1] : gluexTreasury (address): 0x3CffeF055725974e32a660a617FC999b67E9196E
Arg [2] : nativeToken (address): 0x2222222222222222222222222222222222222222
Arg [3] : wrappedNativeToken (address): 0x5555555555555555555555555555555555555555
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000fd1c12f7bc0cc595486bb87860e985e91e96e493
Arg [1] : 0000000000000000000000003cffef055725974e32a660a617fc999b67e9196e
Arg [2] : 0000000000000000000000002222222222222222222222222222222222222222
Arg [3] : 0000000000000000000000005555555555555555555555555555555555555555
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
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.