Latest 25 from a total of 102 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Swap | 22725976 | 186 days ago | IN | 0 ETH | 0.00000003 | ||||
| Swap | 22725928 | 186 days ago | IN | 0 ETH | 0.00000003 | ||||
| Swap | 22725800 | 186 days ago | IN | 0 ETH | 0.00000025 | ||||
| Swap | 22712816 | 186 days ago | IN | 0.033 ETH | 0.00000002 | ||||
| Swap | 22710304 | 186 days ago | IN | 0 ETH | 0.00000003 | ||||
| Swap | 22702604 | 186 days ago | IN | 0 ETH | 0.00000004 | ||||
| Swap | 22702228 | 186 days ago | IN | 0.05 ETH | 0.00000003 | ||||
| Swap | 22701834 | 186 days ago | IN | 0 ETH | 0.00000002 | ||||
| Swap | 22700900 | 186 days ago | IN | 0 ETH | 0.00000004 | ||||
| Swap | 22548071 | 188 days ago | IN | 0 ETH | 0.00000005 | ||||
| Swap | 22547506 | 188 days ago | IN | 0.0015 ETH | 0.00000007 | ||||
| Swap | 21671818 | 198 days ago | IN | 0 ETH | 0.00000061 | ||||
| Swap | 21564366 | 199 days ago | IN | 0.00002 ETH | 0.00000023 | ||||
| Swap | 21564320 | 199 days ago | IN | 0 ETH | 0.00000034 | ||||
| Swap | 21564259 | 199 days ago | IN | 0 ETH | 0.00000018 | ||||
| Swap | 21564200 | 199 days ago | IN | 0 ETH | 0.00000025 | ||||
| Swap | 21564120 | 199 days ago | IN | 0.00004 ETH | 0.00000022 | ||||
| Swap | 21506692 | 200 days ago | IN | 0 ETH | 0.00000026 | ||||
| Swap | 21506660 | 200 days ago | IN | 0.000001 ETH | 0.00000027 | ||||
| Swap | 21506641 | 200 days ago | IN | 0.00001 ETH | 0.00000025 | ||||
| Swap | 20734849 | 209 days ago | IN | 0.000001 ETH | 0.00000019 | ||||
| Swap | 20609960 | 210 days ago | IN | 0.005 ETH | 0.00000002 | ||||
| Swap | 20609917 | 210 days ago | IN | 0.0035 ETH | 0.00000002 | ||||
| Swap | 20542374 | 211 days ago | IN | 0.0021 ETH | 0.00000006 | ||||
| Swap | 20437309 | 212 days ago | IN | 0.000011 ETH | 0.00000002 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 22932258 | 183 days ago | 0.00740848 ETH | ||||
| 22932258 | 183 days ago | 0.00740848 ETH | ||||
| 22932233 | 183 days ago | 0.00756413 ETH | ||||
| 22932233 | 183 days ago | 0.00756413 ETH | ||||
| 22932198 | 183 days ago | 0.00757009 ETH | ||||
| 22932198 | 183 days ago | 0.00757009 ETH | ||||
| 22932178 | 183 days ago | 0.00754641 ETH | ||||
| 22932178 | 183 days ago | 0.00754641 ETH | ||||
| 22843455 | 184 days ago | 0.00092162 ETH | ||||
| 22843455 | 184 days ago | 0.00092162 ETH | ||||
| 22843436 | 184 days ago | 0.00090781 ETH | ||||
| 22843436 | 184 days ago | 0.00090781 ETH | ||||
| 22726459 | 186 days ago | 0.03268385 ETH | ||||
| 22726459 | 186 days ago | 0.03268385 ETH | ||||
| 22726227 | 186 days ago | 0.033 ETH | ||||
| 22726227 | 186 days ago | 0.033 ETH | ||||
| 22726074 | 186 days ago | 0.03220765 ETH | ||||
| 22726074 | 186 days ago | 0.03220765 ETH | ||||
| 22713201 | 186 days ago | 0.0325 ETH | ||||
| 22713201 | 186 days ago | 0.0325 ETH | ||||
| 22713102 | 186 days ago | 0.03276019 ETH | ||||
| 22713102 | 186 days ago | 0.03276019 ETH | ||||
| 22712816 | 186 days ago | 0.033 ETH | ||||
| 22710424 | 186 days ago | 0.04954409 ETH | ||||
| 22710424 | 186 days ago | 0.04954409 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
GluexRouter
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
No with 200 runs
Other Settings:
shanghai 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 {SafeERC20} from "./lib/SafeERC20.sol";
/**
* @title GluexRouter
* @notice A versatile router contract that enables the execution of on-chain interactions using the `IExecutor` interface.
* @dev This contract provides functionality for routing tokens through various interactions, collecting routing fees,
* and enforcing strict slippage and routing rules for optimal security and usability.
*/
contract GluexRouter is EthReceiver {
using SafeERC20 for IERC20;
// Errors
error InsufficientBalance();
error NativeTransferFailed();
error OnlyGlueTreasury();
error ZeroAddress();
// Events
/**
* @notice Emitted when a routing operation is completed.
* @param uniquePID The unique identifier for the partner.
* @param userAddress The address of the user who initiated the route.
* @param outputReceiver The address of the receiver of the output token.
* @param inputToken The ERC20 token used as input.
* @param inputAmount The amount of input token used for routing.
* @param outputToken The ERC20 token received as output.
* @param outputAmount The expected output amount from the route.
* @param partnerFee The fee charged for the partner.
* @param routingFee The fee charged for the routing operation.
* @param finalOutputAmount The actual output amount received after routing.
*/
event Routed(
bytes indexed uniquePID,
address indexed userAddress,
address outputReceiver,
IERC20 inputToken,
uint256 inputAmount,
IERC20 outputToken,
uint256 outputAmount,
uint256 partnerFee,
uint256 routingFee,
uint256 finalOutputAmount
);
// DataTypes
/**
* @dev A generic structure defining the parameters for a route.
*/
struct RouteDescription {
IERC20 inputToken; // Token used as input for the route
IERC20 outputToken; // Token received as output from the route
address payable inputReceiver; // Address to receive the input token
address payable outputReceiver; // Address to receive the output token
uint256 inputAmount; // Amount of input token
uint256 outputAmount; // Original output amount
uint256 partnerFee; // Fee for the partner
uint256 routingFee; // Fee for the routing operation
uint256 effectiveOutputAmount; // Effective output after deducting the routing fee
uint256 minOutputAmount; // Minimum acceptable output amount
bool isPermit2; // Whether to use Permit2 for token transfers
bytes uniquePID; // Unique identifier for the partner
}
// Constants
uint256 public _RAW_CALL_GAS_LIMIT = 5500;
uint256 public _MAX_FEE = 15; // 11 bps (0.11%)
uint256 public _MIN_FEE = 1; // 1 bps (0.01%)
uint256 public _TOLERANCE = 1000;
// State Variables
address public immutable _nativeToken; // Address of the native token (e.g., Ether on Ethereum)
address internal immutable _gluexTreasury; // Address of the GlueX treasury contract
/**
* @dev Initializes the contract with the treasury address and native token address.
* @param gluexTreasury The address of the Glue treasury contract.
* @param nativeToken The address of the native token.
*/
constructor(address gluexTreasury, address nativeToken) {
// Ensure the addresses are not zero
checkZeroAddress(gluexTreasury);
_gluexTreasury = gluexTreasury;
_nativeToken = nativeToken;
}
/**
* @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 != _gluexTreasury) 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 Collects routing fees from specified tokens and transfers them to the given receiver.
* @param feeTokens An array of ERC20 tokens from which fees will be collected.
* @param receiver The address where collected fees will be transferred.
*/
function collectFees(IERC20[] memory feeTokens, address payable receiver)
external
onlyTreasury
{
// Ensure the receiver address is valid
checkZeroAddress(receiver);
// Collect fees for each token
uint256 len = feeTokens.length;
for (uint256 i = 0; i < len; ) {
uint256 feeBalance = uniBalanceOf(feeTokens[i], address(this));
uniTransfer(feeTokens[i], receiver, feeBalance);
unchecked {
++i;
}
}
}
/**
* @notice Executes a route using the specified executor and interactions.
* @param executor The executor contract that performs the interactions.
* @param desc The route description containing input, output, and fee details.
* @param interactions The interactions encoded for execution by the executor.
* @return finalOutputAmount The final amount of output token received.
* @dev Ensures strict validation of slippage, routing fees, and input/output parameters.
*/
function swap(
IExecutor executor,
RouteDescription calldata desc,
Interaction[] calldata interactions,
uint256 deadline
) external payable returns (uint256 finalOutputAmount) {
// Deadline check
if (block.timestamp > deadline) revert("Deadline passed");
// Validate routing fee
if (desc.routingFee > (desc.outputAmount * _MAX_FEE) / 10000) revert("Routing fee too high");
if (desc.routingFee < (desc.outputAmount * _MIN_FEE) / 10000) revert("Routing fee too low");
// Validate non-zero addresses
checkZeroAddress(desc.inputReceiver);
checkZeroAddress(desc.outputReceiver);
// Validate route parameters
if (desc.minOutputAmount <= 0) revert("Negative slippage limit");
if (desc.minOutputAmount > desc.outputAmount) revert("Slippage limit too large");
if (desc.inputToken == desc.outputToken) revert("Arbitrage not supported");
if (desc.routingFee <= 0) revert("Negative routing fee");
if (desc.partnerFee < 0) revert("Negative partner fee");
if (
desc.outputAmount <
desc.effectiveOutputAmount +
desc.partnerFee +
desc.routingFee -
_TOLERANCE ||
desc.outputAmount >
desc.effectiveOutputAmount +
desc.partnerFee +
desc.routingFee +
_TOLERANCE
) revert("Invalid amounts");
// Handle native token input validation
if (address(desc.inputToken) == _nativeToken) {
if (msg.value != desc.inputAmount) revert("Invalid native token input amount");
} else {
if (msg.value != 0) revert("Invalid native token input amount");
desc.inputToken.safeTransferFromUniversal(
msg.sender,
desc.inputReceiver,
desc.inputAmount,
desc.isPermit2
);
}
// Execute interactions through the executor
uint256 outputBalanceBefore = uniBalanceOf(IERC20(desc.outputToken), address(this));
IExecutor(executor).executeRoute{value: msg.value}(
interactions,
desc.outputToken
);
uint256 outputBalanceAfter = uniBalanceOf(IERC20(desc.outputToken), address(this));
// Calculate final output amount
uint256 routingFee = 0;
if (outputBalanceAfter - outputBalanceBefore > desc.effectiveOutputAmount + desc.routingFee) {
finalOutputAmount = outputBalanceAfter - outputBalanceBefore - desc.routingFee;
routingFee = desc.routingFee;
} else if (outputBalanceAfter - outputBalanceBefore > desc.effectiveOutputAmount) {
finalOutputAmount = desc.effectiveOutputAmount;
routingFee = outputBalanceAfter - outputBalanceBefore - desc.effectiveOutputAmount;
} else {
finalOutputAmount = outputBalanceAfter - outputBalanceBefore;
}
// Ensure final output amount meets the minimum required
if (finalOutputAmount < desc.minOutputAmount) revert("Negative slippage too large");
// Transfer the final output amount to the receiver
uniTransfer(IERC20(desc.outputToken), desc.outputReceiver, finalOutputAmount);
emit Routed(
desc.uniquePID,
msg.sender,
desc.outputReceiver,
desc.inputToken,
desc.inputAmount,
desc.outputToken,
desc.outputAmount,
desc.partnerFee,
routingFee,
finalOutputAmount
);
}
/**
* @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;
}
/**
* @notice Updates the maximum fee that can be charged by the contract.
* @param maxFee The new maximum fee to be set.
* @dev This function is restricted to the treasury.
*/
function setMaxFee(uint256 maxFee) external onlyTreasury {
_MAX_FEE = maxFee;
}
/**
* @notice Updates the minimum fee that can be charged by the contract.
* @param minFee The new minimum fee to be set.
* @dev This function is restricted to the treasury.
*/
function setMinFee(uint256 minFee) external onlyTreasury {
_MIN_FEE = minFee;
}
/**
* @notice Updates the tolerance.
* @param tolerance The new tolerance to be set.
* @dev This function is restricted to the treasury.
*/
function setTolerance(uint256 tolerance) external onlyTreasury {
_TOLERANCE = tolerance;
}
}// 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;
/**
* @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;
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;
/// @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;
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();
}
}// 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; // 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; // 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; // 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); }
{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": [],
"evmVersion": "shanghai"
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"gluexTreasury","type":"address"},{"internalType":"address","name":"nativeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EthDepositRejected","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[],"name":"OnlyGlueTreasury","type":"error"},{"inputs":[],"name":"Permit2TransferAmountTooHigh","type":"error"},{"inputs":[],"name":"SafeTransferFailed","type":"error"},{"inputs":[],"name":"SafeTransferFromFailed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes","name":"uniquePID","type":"bytes"},{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address","name":"outputReceiver","type":"address"},{"indexed":false,"internalType":"contract IERC20","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"contract IERC20","name":"outputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"outputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"partnerFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"routingFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"finalOutputAmount","type":"uint256"}],"name":"Routed","type":"event"},{"inputs":[],"name":"_MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_MIN_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_RAW_CALL_GAS_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_TOLERANCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_nativeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20[]","name":"feeTokens","type":"address[]"},{"internalType":"address payable","name":"receiver","type":"address"}],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasLimit","type":"uint256"}],"name":"setGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxFee","type":"uint256"}],"name":"setMaxFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minFee","type":"uint256"}],"name":"setMinFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tolerance","type":"uint256"}],"name":"setTolerance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IExecutor","name":"executor","type":"address"},{"components":[{"internalType":"contract IERC20","name":"inputToken","type":"address"},{"internalType":"contract IERC20","name":"outputToken","type":"address"},{"internalType":"address payable","name":"inputReceiver","type":"address"},{"internalType":"address payable","name":"outputReceiver","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"partnerFee","type":"uint256"},{"internalType":"uint256","name":"routingFee","type":"uint256"},{"internalType":"uint256","name":"effectiveOutputAmount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"bool","name":"isPermit2","type":"bool"},{"internalType":"bytes","name":"uniquePID","type":"bytes"}],"internalType":"struct GluexRouter.RouteDescription","name":"desc","type":"tuple"},{"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":"uint256","name":"deadline","type":"uint256"}],"name":"swap","outputs":[{"internalType":"uint256","name":"finalOutputAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c060405261157c5f55600f60015560016002556103e8600355348015610024575f80fd5b5060405161236e38038061236e8339818101604052810190610046919061018a565b610055826100c460201b60201c565b8173ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050506101c8565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610129576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61015982610130565b9050919050565b6101698161014f565b8114610173575f80fd5b50565b5f8151905061018481610160565b92915050565b5f80604083850312156101a05761019f61012c565b5b5f6101ad85828601610176565b92505060206101be85828601610176565b9150509250929050565b60805160a0516121706101fe5f395f610b9101525f818161075401528181610b5601528181610c810152610d6b01526121705ff3fe60806040526004361061009f575f3560e01c8063827f6e5c11610063578063827f6e5c1461017c578063af48bcb9146101a6578063b8039e98146101d0578063d81a055314610200578063deab3ebd1461022a578063ee7d72b414610254576100ae565b806306af20da146100b2578063249bf7e5146100da57806331ac9920146101045780633c5fd9821461012c578063710e5d2f14610154576100ae565b366100ae576100ac61027c565b005b5f80fd5b3480156100bd575f80fd5b506100d860048036038101906100d39190611364565b6102e3565b005b3480156100e5575f80fd5b506100ee610361565b6040516100fb91906113d6565b60405180910390f35b34801561010f575f80fd5b5061012a60048036038101906101259190611419565b610366565b005b348015610137575f80fd5b50610152600480360381019061014d9190611419565b610378565b005b34801561015f575f80fd5b5061017a60048036038101906101759190611419565b61038a565b005b348015610187575f80fd5b5061019061039c565b60405161019d91906113d6565b60405180910390f35b3480156101b1575f80fd5b506101ba6103a2565b6040516101c791906113d6565b60405180910390f35b6101ea60048036038101906101e591906114fb565b6103a8565b6040516101f791906113d6565b60405180910390f35b34801561020b575f80fd5b50610214610b54565b60405161022191906115aa565b60405180910390f35b348015610235575f80fd5b5061023e610b78565b60405161024b91906113d6565b60405180910390f35b34801561025f575f80fd5b5061027a60048036038101906102759190611419565b610b7e565b005b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036102e1576040517f1b10b0f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6102eb610b8f565b6102f481610c16565b5f825190505f5b8181101561035b575f61032885838151811061031a576103196115c3565b5b602002602001015130610c7e565b905061034f8583815181106103405761033f6115c3565b5b60200260200101518583610d61565b816001019150506102fb565b50505050565b5f5481565b61036e610b8f565b8060028190555050565b610380610b8f565b8060038190555050565b610392610b8f565b8060018190555050565b60035481565b60025481565b5f814211156103ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e39061164a565b60405180910390fd5b6127106001548660a001356104019190611695565b61040b9190611703565b8560e001351115610451576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104489061177d565b60405180910390fd5b6127106002548660a001356104669190611695565b6104709190611703565b8560e0013510156104b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ad906117e5565b60405180910390fd5b6104d18560400160208101906104cc9190611803565b610c16565b6104ec8560600160208101906104e79190611803565b610c16565b5f85610120013511610533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052a90611878565b60405180910390fd5b8460a00135856101200135111561057f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610576906118e0565b60405180910390fd5b84602001602081019061059291906118fe565b73ffffffffffffffffffffffffffffffffffffffff16855f0160208101906105ba91906118fe565b73ffffffffffffffffffffffffffffffffffffffff1603610610576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060790611973565b60405180910390fd5b5f8560e0013511610656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064d906119db565b60405180910390fd5b5f8560c00135101561069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069490611a43565b60405180910390fd5b6003548560e001358660c001358761010001356106ba9190611a61565b6106c49190611a61565b6106ce9190611a94565b8560a00135108061071257506003548560e001358660c001358761010001356106f79190611a61565b6107019190611a61565b61070b9190611a61565b8560a00135115b15610752576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074990611b11565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16855f01602081019061079b91906118fe565b73ffffffffffffffffffffffffffffffffffffffff160361080157846080013534146107fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f390611b9f565b60405180910390fd5b6108ad565b5f3414610843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083a90611b9f565b60405180910390fd5b6108ac3386604001602081019061085a9190611803565b8760800135886101400160208101906108739190611bf2565b895f01602081019061088591906118fe565b73ffffffffffffffffffffffffffffffffffffffff16610f0c90949392919063ffffffff16565b5b5f6108ca8660200160208101906108c491906118fe565b30610c7e565b90508673ffffffffffffffffffffffffffffffffffffffff1663c0dcf8043487878a60200160208101906108fe91906118fe565b6040518563ffffffff1660e01b815260040161091c93929190611edc565b5f604051808303818588803b158015610933575f80fd5b505af1158015610945573d5f803e3d5ffd5b50505050505f61096787602001602081019061096191906118fe565b30610c7e565b90505f8760e0013588610100013561097f9190611a61565b838361098b9190611a94565b11156109ba578760e0013583836109a29190611a94565b6109ac9190611a94565b93508760e001359050610a0d565b87610100013583836109cc9190611a94565b11156109fd57876101000135935087610100013583836109ec9190611a94565b6109f69190611a94565b9050610a0c565b8282610a099190611a94565b93505b5b876101200135841015610a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4c90611f56565b60405180910390fd5b610a84886020016020810190610a6b91906118fe565b896060016020810190610a7e9190611803565b86610d61565b3373ffffffffffffffffffffffffffffffffffffffff1688806101600190610aac9190611f80565b604051610aba929190612010565b60405180910390207f5e521321e80942e089aa52b7fc771168567b97a6322f12d75ae43b264fff9c778a6060016020810190610af69190611803565b8b5f016020810190610b0891906118fe565b8c608001358d6020016020810190610b2091906118fe565b8e60a001358f60c00135898d604051610b40989796959493929190612048565b60405180910390a350505095945050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60015481565b610b86610b8f565b805f8190555050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c14576040517ffcb6435400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c7b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ce0575f8231905080915050610d5b565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610d1991906115aa565b602060405180830381865afa158015610d34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5891906120d8565b90505b92915050565b5f811115610ed5577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ea4575f47905081811015610dfa576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8373ffffffffffffffffffffffffffffffffffffffff16835f5490604051610e2290612126565b5f60405180830381858888f193505050503d805f8114610e5d576040519150601f19603f3d011682016040523d82523d5f602084013e610e62565b606091505b5050905080610e9d576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050610ed0565b610ecf82828573ffffffffffffffffffffffffffffffffffffffff16610f379092919063ffffffff16565b5b610f07565b6040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b8015610f2357610f1e85858585610f85565b610f30565b610f2f85858585611075565b5b5050505050565b610f4a8363a9059cbb60e01b848461110d565b610f80576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b73ffffffffffffffffffffffffffffffffffffffff8016811115610fd5576040517f8112e11900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6336c7851660e01b90505f6040518281528560048201528460248201528360448201528660648201525f806084835f6e22d473030f116ddee9f6b43ac78ba35af191508115611035575f6e22d473030f116ddee9f6b43ac78ba33b1191505b508061106d576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b5f6323b872dd60e01b90505f60405182815285600482015284602482015283604482015260205f6064835f8b5af1915081156110cd573d5f81146110c45760015f5114601f3d111692506110cb565b5f883b1192505b505b5080611105576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b5f60405184815283600482015282602482015260205f6044835f8a5af191508115611154573d5f811461114b5760015f5114601f3d11169250611152565b5f873b1192505b505b50949350505050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6111b882611172565b810181811067ffffffffffffffff821117156111d7576111d6611182565b5b80604052505050565b5f6111e961115d565b90506111f582826111af565b919050565b5f67ffffffffffffffff82111561121457611213611182565b5b602082029050602081019050919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61125282611229565b9050919050565b5f61126382611248565b9050919050565b61127381611259565b811461127d575f80fd5b50565b5f8135905061128e8161126a565b92915050565b5f6112a66112a1846111fa565b6111e0565b905080838252602082019050602084028301858111156112c9576112c8611225565b5b835b818110156112f257806112de8882611280565b8452602084019350506020810190506112cb565b5050509392505050565b5f82601f8301126113105761130f61116e565b5b8135611320848260208601611294565b91505092915050565b5f61133382611229565b9050919050565b61134381611329565b811461134d575f80fd5b50565b5f8135905061135e8161133a565b92915050565b5f806040838503121561137a57611379611166565b5b5f83013567ffffffffffffffff8111156113975761139661116a565b5b6113a3858286016112fc565b92505060206113b485828601611350565b9150509250929050565b5f819050919050565b6113d0816113be565b82525050565b5f6020820190506113e95f8301846113c7565b92915050565b6113f8816113be565b8114611402575f80fd5b50565b5f81359050611413816113ef565b92915050565b5f6020828403121561142e5761142d611166565b5b5f61143b84828501611405565b91505092915050565b5f61144e82611248565b9050919050565b61145e81611444565b8114611468575f80fd5b50565b5f8135905061147981611455565b92915050565b5f80fd5b5f61018082840312156114995761149861147f565b5b81905092915050565b5f80fd5b5f8083601f8401126114bb576114ba61116e565b5b8235905067ffffffffffffffff8111156114d8576114d76114a2565b5b6020830191508360208202830111156114f4576114f3611225565b5b9250929050565b5f805f805f6080868803121561151457611513611166565b5b5f6115218882890161146b565b955050602086013567ffffffffffffffff8111156115425761154161116a565b5b61154e88828901611483565b945050604086013567ffffffffffffffff81111561156f5761156e61116a565b5b61157b888289016114a6565b9350935050606061158e88828901611405565b9150509295509295909350565b6115a481611248565b82525050565b5f6020820190506115bd5f83018461159b565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82825260208201905092915050565b7f446561646c696e652070617373656400000000000000000000000000000000005f82015250565b5f611634600f836115f0565b915061163f82611600565b602082019050919050565b5f6020820190508181035f83015261166181611628565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61169f826113be565b91506116aa836113be565b92508282026116b8816113be565b915082820484148315176116cf576116ce611668565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61170d826113be565b9150611718836113be565b925082611728576117276116d6565b5b828204905092915050565b7f526f7574696e672066656520746f6f20686967680000000000000000000000005f82015250565b5f6117676014836115f0565b915061177282611733565b602082019050919050565b5f6020820190508181035f8301526117948161175b565b9050919050565b7f526f7574696e672066656520746f6f206c6f77000000000000000000000000005f82015250565b5f6117cf6013836115f0565b91506117da8261179b565b602082019050919050565b5f6020820190508181035f8301526117fc816117c3565b9050919050565b5f6020828403121561181857611817611166565b5b5f61182584828501611350565b91505092915050565b7f4e6567617469766520736c697070616765206c696d69740000000000000000005f82015250565b5f6118626017836115f0565b915061186d8261182e565b602082019050919050565b5f6020820190508181035f83015261188f81611856565b9050919050565b7f536c697070616765206c696d697420746f6f206c6172676500000000000000005f82015250565b5f6118ca6018836115f0565b91506118d582611896565b602082019050919050565b5f6020820190508181035f8301526118f7816118be565b9050919050565b5f6020828403121561191357611912611166565b5b5f61192084828501611280565b91505092915050565b7f417262697472616765206e6f7420737570706f727465640000000000000000005f82015250565b5f61195d6017836115f0565b915061196882611929565b602082019050919050565b5f6020820190508181035f83015261198a81611951565b9050919050565b7f4e6567617469766520726f7574696e67206665650000000000000000000000005f82015250565b5f6119c56014836115f0565b91506119d082611991565b602082019050919050565b5f6020820190508181035f8301526119f2816119b9565b9050919050565b7f4e6567617469766520706172746e6572206665650000000000000000000000005f82015250565b5f611a2d6014836115f0565b9150611a38826119f9565b602082019050919050565b5f6020820190508181035f830152611a5a81611a21565b9050919050565b5f611a6b826113be565b9150611a76836113be565b9250828201905080821115611a8e57611a8d611668565b5b92915050565b5f611a9e826113be565b9150611aa9836113be565b9250828203905081811115611ac157611ac0611668565b5b92915050565b7f496e76616c696420616d6f756e747300000000000000000000000000000000005f82015250565b5f611afb600f836115f0565b9150611b0682611ac7565b602082019050919050565b5f6020820190508181035f830152611b2881611aef565b9050919050565b7f496e76616c6964206e617469766520746f6b656e20696e70757420616d6f756e5f8201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b5f611b896021836115f0565b9150611b9482611b2f565b604082019050919050565b5f6020820190508181035f830152611bb681611b7d565b9050919050565b5f8115159050919050565b611bd181611bbd565b8114611bdb575f80fd5b50565b5f81359050611bec81611bc8565b92915050565b5f60208284031215611c0757611c06611166565b5b5f611c1484828501611bde565b91505092915050565b5f82825260208201905092915050565b5f819050919050565b611c3f81611248565b8114611c49575f80fd5b50565b5f81359050611c5a81611c36565b92915050565b5f611c6e6020840184611c4c565b905092915050565b611c7f81611248565b82525050565b5f611c936020840184611405565b905092915050565b611ca4816113be565b82525050565b5f80fd5b5f80fd5b5f80fd5b5f8083356001602003843603038112611cd257611cd1611cb2565b5b83810192508235915060208301925067ffffffffffffffff821115611cfa57611cf9611caa565b5b600182023603831315611d1057611d0f611cae565b5b509250929050565b5f82825260208201905092915050565b828183375f83830152505050565b5f611d418385611d18565b9350611d4e838584611d28565b611d5783611172565b840190509392505050565b5f60608301611d735f840184611c60565b611d7f5f860182611c76565b50611d8d6020840184611c85565b611d9a6020860182611c9b565b50611da86040840184611cb6565b8583036040870152611dbb838284611d36565b925050508091505092915050565b5f611dd48383611d62565b905092915050565b5f82356001606003833603038112611df757611df6611cb2565b5b82810191505092915050565b5f602082019050919050565b5f611e1a8385611c1d565b935083602084028501611e2c84611c2d565b805f5b87811015611e6f578484038952611e468284611ddc565b611e508582611dc9565b9450611e5b83611e03565b925060208a01995050600181019050611e2f565b50829750879450505050509392505050565b5f819050919050565b5f611ea4611e9f611e9a84611229565b611e81565b611229565b9050919050565b5f611eb582611e8a565b9050919050565b5f611ec682611eab565b9050919050565b611ed681611ebc565b82525050565b5f6040820190508181035f830152611ef5818587611e0f565b9050611f046020830184611ecd565b949350505050565b7f4e6567617469766520736c69707061676520746f6f206c6172676500000000005f82015250565b5f611f40601b836115f0565b9150611f4b82611f0c565b602082019050919050565b5f6020820190508181035f830152611f6d81611f34565b9050919050565b5f80fd5b5f80fd5b5f80fd5b5f8083356001602003843603038112611f9c57611f9b611f74565b5b80840192508235915067ffffffffffffffff821115611fbe57611fbd611f78565b5b602083019250600182023603831315611fda57611fd9611f7c565b5b509250929050565b5f81905092915050565b5f611ff78385611fe2565b9350612004838584611d28565b82840190509392505050565b5f61201c828486611fec565b91508190509392505050565b5f61203282611eab565b9050919050565b61204281612028565b82525050565b5f6101008201905061205c5f83018b612039565b612069602083018a611ecd565b61207660408301896113c7565b6120836060830188611ecd565b61209060808301876113c7565b61209d60a08301866113c7565b6120aa60c08301856113c7565b6120b760e08301846113c7565b9998505050505050505050565b5f815190506120d2816113ef565b92915050565b5f602082840312156120ed576120ec611166565b5b5f6120fa848285016120c4565b91505092915050565b50565b5f6121115f83611fe2565b915061211c82612103565b5f82019050919050565b5f61213082612106565b915081905091905056fea2646970667358221220bdcc4184aad730269f65433cb4beecf2308e702c3dd3425edac9149add54765d64736f6c634300081a003300000000000000000000000084dbae2549d67caf00f65c355de3d6f4df59a32c000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
Deployed Bytecode
0x60806040526004361061009f575f3560e01c8063827f6e5c11610063578063827f6e5c1461017c578063af48bcb9146101a6578063b8039e98146101d0578063d81a055314610200578063deab3ebd1461022a578063ee7d72b414610254576100ae565b806306af20da146100b2578063249bf7e5146100da57806331ac9920146101045780633c5fd9821461012c578063710e5d2f14610154576100ae565b366100ae576100ac61027c565b005b5f80fd5b3480156100bd575f80fd5b506100d860048036038101906100d39190611364565b6102e3565b005b3480156100e5575f80fd5b506100ee610361565b6040516100fb91906113d6565b60405180910390f35b34801561010f575f80fd5b5061012a60048036038101906101259190611419565b610366565b005b348015610137575f80fd5b50610152600480360381019061014d9190611419565b610378565b005b34801561015f575f80fd5b5061017a60048036038101906101759190611419565b61038a565b005b348015610187575f80fd5b5061019061039c565b60405161019d91906113d6565b60405180910390f35b3480156101b1575f80fd5b506101ba6103a2565b6040516101c791906113d6565b60405180910390f35b6101ea60048036038101906101e591906114fb565b6103a8565b6040516101f791906113d6565b60405180910390f35b34801561020b575f80fd5b50610214610b54565b60405161022191906115aa565b60405180910390f35b348015610235575f80fd5b5061023e610b78565b60405161024b91906113d6565b60405180910390f35b34801561025f575f80fd5b5061027a60048036038101906102759190611419565b610b7e565b005b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036102e1576040517f1b10b0f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6102eb610b8f565b6102f481610c16565b5f825190505f5b8181101561035b575f61032885838151811061031a576103196115c3565b5b602002602001015130610c7e565b905061034f8583815181106103405761033f6115c3565b5b60200260200101518583610d61565b816001019150506102fb565b50505050565b5f5481565b61036e610b8f565b8060028190555050565b610380610b8f565b8060038190555050565b610392610b8f565b8060018190555050565b60035481565b60025481565b5f814211156103ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e39061164a565b60405180910390fd5b6127106001548660a001356104019190611695565b61040b9190611703565b8560e001351115610451576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104489061177d565b60405180910390fd5b6127106002548660a001356104669190611695565b6104709190611703565b8560e0013510156104b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ad906117e5565b60405180910390fd5b6104d18560400160208101906104cc9190611803565b610c16565b6104ec8560600160208101906104e79190611803565b610c16565b5f85610120013511610533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052a90611878565b60405180910390fd5b8460a00135856101200135111561057f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610576906118e0565b60405180910390fd5b84602001602081019061059291906118fe565b73ffffffffffffffffffffffffffffffffffffffff16855f0160208101906105ba91906118fe565b73ffffffffffffffffffffffffffffffffffffffff1603610610576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060790611973565b60405180910390fd5b5f8560e0013511610656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064d906119db565b60405180910390fd5b5f8560c00135101561069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069490611a43565b60405180910390fd5b6003548560e001358660c001358761010001356106ba9190611a61565b6106c49190611a61565b6106ce9190611a94565b8560a00135108061071257506003548560e001358660c001358761010001356106f79190611a61565b6107019190611a61565b61070b9190611a61565b8560a00135115b15610752576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074990611b11565b60405180910390fd5b7f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff16855f01602081019061079b91906118fe565b73ffffffffffffffffffffffffffffffffffffffff160361080157846080013534146107fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f390611b9f565b60405180910390fd5b6108ad565b5f3414610843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161083a90611b9f565b60405180910390fd5b6108ac3386604001602081019061085a9190611803565b8760800135886101400160208101906108739190611bf2565b895f01602081019061088591906118fe565b73ffffffffffffffffffffffffffffffffffffffff16610f0c90949392919063ffffffff16565b5b5f6108ca8660200160208101906108c491906118fe565b30610c7e565b90508673ffffffffffffffffffffffffffffffffffffffff1663c0dcf8043487878a60200160208101906108fe91906118fe565b6040518563ffffffff1660e01b815260040161091c93929190611edc565b5f604051808303818588803b158015610933575f80fd5b505af1158015610945573d5f803e3d5ffd5b50505050505f61096787602001602081019061096191906118fe565b30610c7e565b90505f8760e0013588610100013561097f9190611a61565b838361098b9190611a94565b11156109ba578760e0013583836109a29190611a94565b6109ac9190611a94565b93508760e001359050610a0d565b87610100013583836109cc9190611a94565b11156109fd57876101000135935087610100013583836109ec9190611a94565b6109f69190611a94565b9050610a0c565b8282610a099190611a94565b93505b5b876101200135841015610a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4c90611f56565b60405180910390fd5b610a84886020016020810190610a6b91906118fe565b896060016020810190610a7e9190611803565b86610d61565b3373ffffffffffffffffffffffffffffffffffffffff1688806101600190610aac9190611f80565b604051610aba929190612010565b60405180910390207f5e521321e80942e089aa52b7fc771168567b97a6322f12d75ae43b264fff9c778a6060016020810190610af69190611803565b8b5f016020810190610b0891906118fe565b8c608001358d6020016020810190610b2091906118fe565b8e60a001358f60c00135898d604051610b40989796959493929190612048565b60405180910390a350505095945050505050565b7f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b60015481565b610b86610b8f565b805f8190555050565b7f00000000000000000000000084dbae2549d67caf00f65c355de3d6f4df59a32c73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c14576040517ffcb6435400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c7b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b5f7f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ce0575f8231905080915050610d5b565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401610d1991906115aa565b602060405180830381865afa158015610d34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d5891906120d8565b90505b92915050565b5f811115610ed5577f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ea4575f47905081811015610dfa576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8373ffffffffffffffffffffffffffffffffffffffff16835f5490604051610e2290612126565b5f60405180830381858888f193505050503d805f8114610e5d576040519150601f19603f3d011682016040523d82523d5f602084013e610e62565b606091505b5050905080610e9d576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050610ed0565b610ecf82828573ffffffffffffffffffffffffffffffffffffffff16610f379092919063ffffffff16565b5b610f07565b6040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b8015610f2357610f1e85858585610f85565b610f30565b610f2f85858585611075565b5b5050505050565b610f4a8363a9059cbb60e01b848461110d565b610f80576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b73ffffffffffffffffffffffffffffffffffffffff8016811115610fd5576040517f8112e11900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6336c7851660e01b90505f6040518281528560048201528460248201528360448201528660648201525f806084835f6e22d473030f116ddee9f6b43ac78ba35af191508115611035575f6e22d473030f116ddee9f6b43ac78ba33b1191505b508061106d576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b5f6323b872dd60e01b90505f60405182815285600482015284602482015283604482015260205f6064835f8b5af1915081156110cd573d5f81146110c45760015f5114601f3d111692506110cb565b5f883b1192505b505b5080611105576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b5f60405184815283600482015282602482015260205f6044835f8a5af191508115611154573d5f811461114b5760015f5114601f3d11169250611152565b5f873b1192505b505b50949350505050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6111b882611172565b810181811067ffffffffffffffff821117156111d7576111d6611182565b5b80604052505050565b5f6111e961115d565b90506111f582826111af565b919050565b5f67ffffffffffffffff82111561121457611213611182565b5b602082029050602081019050919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61125282611229565b9050919050565b5f61126382611248565b9050919050565b61127381611259565b811461127d575f80fd5b50565b5f8135905061128e8161126a565b92915050565b5f6112a66112a1846111fa565b6111e0565b905080838252602082019050602084028301858111156112c9576112c8611225565b5b835b818110156112f257806112de8882611280565b8452602084019350506020810190506112cb565b5050509392505050565b5f82601f8301126113105761130f61116e565b5b8135611320848260208601611294565b91505092915050565b5f61133382611229565b9050919050565b61134381611329565b811461134d575f80fd5b50565b5f8135905061135e8161133a565b92915050565b5f806040838503121561137a57611379611166565b5b5f83013567ffffffffffffffff8111156113975761139661116a565b5b6113a3858286016112fc565b92505060206113b485828601611350565b9150509250929050565b5f819050919050565b6113d0816113be565b82525050565b5f6020820190506113e95f8301846113c7565b92915050565b6113f8816113be565b8114611402575f80fd5b50565b5f81359050611413816113ef565b92915050565b5f6020828403121561142e5761142d611166565b5b5f61143b84828501611405565b91505092915050565b5f61144e82611248565b9050919050565b61145e81611444565b8114611468575f80fd5b50565b5f8135905061147981611455565b92915050565b5f80fd5b5f61018082840312156114995761149861147f565b5b81905092915050565b5f80fd5b5f8083601f8401126114bb576114ba61116e565b5b8235905067ffffffffffffffff8111156114d8576114d76114a2565b5b6020830191508360208202830111156114f4576114f3611225565b5b9250929050565b5f805f805f6080868803121561151457611513611166565b5b5f6115218882890161146b565b955050602086013567ffffffffffffffff8111156115425761154161116a565b5b61154e88828901611483565b945050604086013567ffffffffffffffff81111561156f5761156e61116a565b5b61157b888289016114a6565b9350935050606061158e88828901611405565b9150509295509295909350565b6115a481611248565b82525050565b5f6020820190506115bd5f83018461159b565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82825260208201905092915050565b7f446561646c696e652070617373656400000000000000000000000000000000005f82015250565b5f611634600f836115f0565b915061163f82611600565b602082019050919050565b5f6020820190508181035f83015261166181611628565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61169f826113be565b91506116aa836113be565b92508282026116b8816113be565b915082820484148315176116cf576116ce611668565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61170d826113be565b9150611718836113be565b925082611728576117276116d6565b5b828204905092915050565b7f526f7574696e672066656520746f6f20686967680000000000000000000000005f82015250565b5f6117676014836115f0565b915061177282611733565b602082019050919050565b5f6020820190508181035f8301526117948161175b565b9050919050565b7f526f7574696e672066656520746f6f206c6f77000000000000000000000000005f82015250565b5f6117cf6013836115f0565b91506117da8261179b565b602082019050919050565b5f6020820190508181035f8301526117fc816117c3565b9050919050565b5f6020828403121561181857611817611166565b5b5f61182584828501611350565b91505092915050565b7f4e6567617469766520736c697070616765206c696d69740000000000000000005f82015250565b5f6118626017836115f0565b915061186d8261182e565b602082019050919050565b5f6020820190508181035f83015261188f81611856565b9050919050565b7f536c697070616765206c696d697420746f6f206c6172676500000000000000005f82015250565b5f6118ca6018836115f0565b91506118d582611896565b602082019050919050565b5f6020820190508181035f8301526118f7816118be565b9050919050565b5f6020828403121561191357611912611166565b5b5f61192084828501611280565b91505092915050565b7f417262697472616765206e6f7420737570706f727465640000000000000000005f82015250565b5f61195d6017836115f0565b915061196882611929565b602082019050919050565b5f6020820190508181035f83015261198a81611951565b9050919050565b7f4e6567617469766520726f7574696e67206665650000000000000000000000005f82015250565b5f6119c56014836115f0565b91506119d082611991565b602082019050919050565b5f6020820190508181035f8301526119f2816119b9565b9050919050565b7f4e6567617469766520706172746e6572206665650000000000000000000000005f82015250565b5f611a2d6014836115f0565b9150611a38826119f9565b602082019050919050565b5f6020820190508181035f830152611a5a81611a21565b9050919050565b5f611a6b826113be565b9150611a76836113be565b9250828201905080821115611a8e57611a8d611668565b5b92915050565b5f611a9e826113be565b9150611aa9836113be565b9250828203905081811115611ac157611ac0611668565b5b92915050565b7f496e76616c696420616d6f756e747300000000000000000000000000000000005f82015250565b5f611afb600f836115f0565b9150611b0682611ac7565b602082019050919050565b5f6020820190508181035f830152611b2881611aef565b9050919050565b7f496e76616c6964206e617469766520746f6b656e20696e70757420616d6f756e5f8201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b5f611b896021836115f0565b9150611b9482611b2f565b604082019050919050565b5f6020820190508181035f830152611bb681611b7d565b9050919050565b5f8115159050919050565b611bd181611bbd565b8114611bdb575f80fd5b50565b5f81359050611bec81611bc8565b92915050565b5f60208284031215611c0757611c06611166565b5b5f611c1484828501611bde565b91505092915050565b5f82825260208201905092915050565b5f819050919050565b611c3f81611248565b8114611c49575f80fd5b50565b5f81359050611c5a81611c36565b92915050565b5f611c6e6020840184611c4c565b905092915050565b611c7f81611248565b82525050565b5f611c936020840184611405565b905092915050565b611ca4816113be565b82525050565b5f80fd5b5f80fd5b5f80fd5b5f8083356001602003843603038112611cd257611cd1611cb2565b5b83810192508235915060208301925067ffffffffffffffff821115611cfa57611cf9611caa565b5b600182023603831315611d1057611d0f611cae565b5b509250929050565b5f82825260208201905092915050565b828183375f83830152505050565b5f611d418385611d18565b9350611d4e838584611d28565b611d5783611172565b840190509392505050565b5f60608301611d735f840184611c60565b611d7f5f860182611c76565b50611d8d6020840184611c85565b611d9a6020860182611c9b565b50611da86040840184611cb6565b8583036040870152611dbb838284611d36565b925050508091505092915050565b5f611dd48383611d62565b905092915050565b5f82356001606003833603038112611df757611df6611cb2565b5b82810191505092915050565b5f602082019050919050565b5f611e1a8385611c1d565b935083602084028501611e2c84611c2d565b805f5b87811015611e6f578484038952611e468284611ddc565b611e508582611dc9565b9450611e5b83611e03565b925060208a01995050600181019050611e2f565b50829750879450505050509392505050565b5f819050919050565b5f611ea4611e9f611e9a84611229565b611e81565b611229565b9050919050565b5f611eb582611e8a565b9050919050565b5f611ec682611eab565b9050919050565b611ed681611ebc565b82525050565b5f6040820190508181035f830152611ef5818587611e0f565b9050611f046020830184611ecd565b949350505050565b7f4e6567617469766520736c69707061676520746f6f206c6172676500000000005f82015250565b5f611f40601b836115f0565b9150611f4b82611f0c565b602082019050919050565b5f6020820190508181035f830152611f6d81611f34565b9050919050565b5f80fd5b5f80fd5b5f80fd5b5f8083356001602003843603038112611f9c57611f9b611f74565b5b80840192508235915067ffffffffffffffff821115611fbe57611fbd611f78565b5b602083019250600182023603831315611fda57611fd9611f7c565b5b509250929050565b5f81905092915050565b5f611ff78385611fe2565b9350612004838584611d28565b82840190509392505050565b5f61201c828486611fec565b91508190509392505050565b5f61203282611eab565b9050919050565b61204281612028565b82525050565b5f6101008201905061205c5f83018b612039565b612069602083018a611ecd565b61207660408301896113c7565b6120836060830188611ecd565b61209060808301876113c7565b61209d60a08301866113c7565b6120aa60c08301856113c7565b6120b760e08301846113c7565b9998505050505050505050565b5f815190506120d2816113ef565b92915050565b5f602082840312156120ed576120ec611166565b5b5f6120fa848285016120c4565b91505092915050565b50565b5f6121115f83611fe2565b915061211c82612103565b5f82019050919050565b5f61213082612106565b915081905091905056fea2646970667358221220bdcc4184aad730269f65433cb4beecf2308e702c3dd3425edac9149add54765d64736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000084dbae2549d67caf00f65c355de3d6f4df59a32c000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
-----Decoded View---------------
Arg [0] : gluexTreasury (address): 0x84dbAE2549d67CaF00f65C355de3D6F4df59A32C
Arg [1] : nativeToken (address): 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000084dbae2549d67caf00f65c355de3d6f4df59a32c
Arg [1] : 000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$8.86
Net Worth in ETH
0.002931
Token Allocations
AXOME
35.94%
USDC
18.87%
WETH
11.11%
Others
34.08%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| BASE | 35.94% | $0.019895 | 160 | $3.18 | |
| BASE | 9.60% | $0.999707 | 0.8509 | $0.8506 | |
| BASE | 7.71% | $89,085 | 0.00000767 | $0.6832 | |
| BASE | 4.06% | $3,021.3 | 0.00011891 | $0.35927 | |
| BASE | 2.72% | $3,017.23 | 0.00007993 | $0.2411 | |
| ETH | 8.39% | $3,021.63 | 0.00024585 | $0.7428 | |
| ETH | 6.30% | $0.999702 | 0.5584 | $0.5582 | |
| ETH | 1.41% | $0.998724 | 0.1247 | $0.1245 | |
| ETH | 1.40% | $3,021.63 | 0.00004117 | $0.124391 | |
| HYPEREVM | 7.94% | $89,155 | 0.00000789 | $0.7034 | |
| HYPEREVM | 2.25% | $0.022166 | 9 | $0.1994 | |
| HYPEREVM | 1.69% | $5,162.35 | 0.000029 | $0.1497 | |
| HYPEREVM | <0.01% | $30.89 | 0.000000000000006248 | <$0.000001 | |
| BSC | 4.30% | $0.998742 | 0.3817 | $0.3812 | |
| BSC | 2.96% | $0.999725 | 0.2625 | $0.2624 | |
| BSC | 2.86% | $899.42 | 0.00028139 | $0.253086 | |
| OP | 0.31% | $3,021.3 | 0.00000898 | $0.027145 | |
| POL | 0.14% | $0.119609 | 0.1032 | $0.012349 | |
| AVAX | <0.01% | $12.14 | 0.0000711 | $0.000863 | |
| ARB | <0.01% | $3,021.63 | 0.000000000000000045 | <$0.000001 | |
| UNI | <0.01% | $3,021.64 | 0.000000000000000013 | <$0.000001 | |
| GNO | <0.01% | $0.999754 | 0.000000000000000054 | <$0.000001 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.