Source Code
Overview
GLMR Balance
GLMR Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 14207495 | 3 hrs ago | 2.70733825 GLMR | ||||
| 14203079 | 11 hrs ago | 0.44365674 GLMR | ||||
| 14202539 | 12 hrs ago | 0.50793876 GLMR | ||||
| 14201681 | 13 hrs ago | 0.53222694 GLMR | ||||
| 14201413 | 14 hrs ago | 8.59503425 GLMR | ||||
| 14200952 | 15 hrs ago | 4.16761363 GLMR | ||||
| 14200947 | 15 hrs ago | 4.08987386 GLMR | ||||
| 14200784 | 15 hrs ago | 0.60029414 GLMR | ||||
| 14199844 | 17 hrs ago | 1.23690464 GLMR | ||||
| 14199679 | 17 hrs ago | 0.6087016 GLMR | ||||
| 14199519 | 18 hrs ago | 94.02431254 GLMR | ||||
| 14199279 | 18 hrs ago | 4.49556625 GLMR | ||||
| 14199137 | 18 hrs ago | 4.43572904 GLMR | ||||
| 14199087 | 18 hrs ago | 3.12767627 GLMR | ||||
| 14198959 | 19 hrs ago | 4.67911427 GLMR | ||||
| 14198627 | 19 hrs ago | 0.34776159 GLMR | ||||
| 14198539 | 20 hrs ago | 10.7655282 GLMR | ||||
| 14198311 | 20 hrs ago | 123.34224904 GLMR | ||||
| 14198214 | 20 hrs ago | 9.3530831 GLMR | ||||
| 14197951 | 21 hrs ago | 1.08262771 GLMR | ||||
| 14197864 | 21 hrs ago | 12.94132178 GLMR | ||||
| 14197827 | 21 hrs ago | 11.45814588 GLMR | ||||
| 14197741 | 21 hrs ago | 10.56610344 GLMR | ||||
| 14197626 | 21 hrs ago | 3.5168025 GLMR | ||||
| 14197563 | 21 hrs ago | 4.58645819 GLMR |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
AxelarGasService
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 1000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';
import { InterchainGasEstimation, GasInfo } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/gas-estimation/InterchainGasEstimation.sol';
import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol';
import { SafeTokenTransfer, SafeTokenTransferFrom } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol';
import { SafeNativeTransfer } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeNativeTransfer.sol';
/**
* @title AxelarGasService
* @notice This contract manages gas payments and refunds for cross-chain communication on the Axelar network.
* @dev The owner address of this contract should be the microservice that pays for gas.
* @dev Users pay gas for cross-chain calls, and the gasCollector can collect accumulated fees and/or refund users if needed.
*/
contract AxelarGasService is InterchainGasEstimation, Upgradable, IAxelarGasService {
using SafeTokenTransfer for IERC20;
using SafeTokenTransferFrom for IERC20;
using SafeNativeTransfer for address payable;
address public immutable gasCollector;
/**
* @notice Constructs the AxelarGasService contract.
* @param gasCollector_ The address of the gas collector
*/
constructor(address gasCollector_) {
gasCollector = gasCollector_;
}
/**
* @notice Modifier that ensures the caller is the designated gas collector.
*/
modifier onlyCollector() {
if (msg.sender != gasCollector) revert NotCollector();
_;
}
/**
* @notice Pay for gas for any type of contract execution on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @dev If estimateOnChain is true, the function will estimate the gas cost and revert if the payment is insufficient.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param executionGasLimit The gas limit for the contract call
* @param estimateOnChain Flag to enable on-chain gas estimation
* @param refundAddress The address where refunds, if any, should be sent
* @param params Additional parameters for gas payment
*/
function payGas(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
uint256 executionGasLimit,
bool estimateOnChain,
address refundAddress,
bytes calldata params
) external payable override {
if (params.length > 0) {
revert InvalidParams();
}
if (estimateOnChain) {
uint256 gasEstimate = estimateGasFee(destinationChain, destinationAddress, payload, executionGasLimit, params);
if (gasEstimate > msg.value) {
revert InsufficientGasPayment(gasEstimate, msg.value);
}
}
emit NativeGasPaidForContractCall(sender, destinationChain, destinationAddress, keccak256(payload), msg.value, refundAddress);
}
/**
* @notice Pay for gas using ERC20 tokens for a contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external override {
emit GasPaidForContractCall(
sender,
destinationChain,
destinationAddress,
keccak256(payload),
gasToken,
gasFeeAmount,
refundAddress
);
IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
}
/**
* @notice Pay for gas using ERC20 tokens for a contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string memory symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external override {
emit GasPaidForContractCallWithToken(
sender,
destinationChain,
destinationAddress,
keccak256(payload),
symbol,
amount,
gasToken,
gasFeeAmount,
refundAddress
);
IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
}
/**
* @notice Pay for gas using native currency for a contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable override {
emit NativeGasPaidForContractCall(sender, destinationChain, destinationAddress, keccak256(payload), msg.value, refundAddress);
}
/**
* @notice Pay for gas using native currency for a contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable override {
emit NativeGasPaidForContractCallWithToken(
sender,
destinationChain,
destinationAddress,
keccak256(payload),
symbol,
amount,
msg.value,
refundAddress
);
}
/**
* @notice Pay for gas using ERC20 tokens for an express contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForExpressCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external override {
emit GasPaidForExpressCall(sender, destinationChain, destinationAddress, keccak256(payload), gasToken, gasFeeAmount, refundAddress);
IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
}
/**
* @notice Pay for gas using ERC20 tokens for an express contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string memory symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external override {
emit GasPaidForExpressCallWithToken(
sender,
destinationChain,
destinationAddress,
keccak256(payload),
symbol,
amount,
gasToken,
gasFeeAmount,
refundAddress
);
IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
}
/**
* @notice Pay for gas using native currency for an express contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForExpressCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable override {
emit NativeGasPaidForExpressCall(sender, destinationChain, destinationAddress, keccak256(payload), msg.value, refundAddress);
}
/**
* @notice Pay for gas using native currency for an express contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable override {
emit NativeGasPaidForExpressCallWithToken(
sender,
destinationChain,
destinationAddress,
keccak256(payload),
symbol,
amount,
msg.value,
refundAddress
);
}
/**
* @notice Add additional gas payment using ERC20 tokens after initiating a cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param gasToken The ERC20 token address used to add gas
* @param gasFeeAmount The amount of tokens to add as gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function addGas(
bytes32 txHash,
uint256 logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external override {
emit GasAdded(txHash, logIndex, gasToken, gasFeeAmount, refundAddress);
IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
}
/**
* @notice Add additional gas payment using native currency after initiating a cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param refundAddress The address where refunds, if any, should be sent
*/
function addNativeGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable override {
emit NativeGasAdded(txHash, logIndex, msg.value, refundAddress);
}
/**
* @notice Add additional gas payment using ERC20 tokens after initiating an express cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param gasToken The ERC20 token address used to add gas
* @param gasFeeAmount The amount of tokens to add as gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function addExpressGas(
bytes32 txHash,
uint256 logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external override {
emit ExpressGasAdded(txHash, logIndex, gasToken, gasFeeAmount, refundAddress);
IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
}
/**
* @notice Add additional gas payment using native currency after initiating an express cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param refundAddress The address where refunds, if any, should be sent
*/
function addNativeExpressGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable override {
emit NativeExpressGasAdded(txHash, logIndex, msg.value, refundAddress);
}
/**
* @notice Updates the gas price for a specific chain.
* @dev This function is called by the gas oracle to update the gas prices for a specific chains.
* @param chains Array of chain names
* @param gasUpdates Array of gas updates
*/
function updateGasInfo(string[] calldata chains, GasInfo[] calldata gasUpdates) external onlyCollector {
uint256 chainsLength = chains.length;
if (chainsLength != gasUpdates.length) revert InvalidGasUpdates();
for (uint256 i; i < chainsLength; i++) {
string calldata chain = chains[i];
GasInfo calldata gasUpdate = gasUpdates[i];
_setGasInfo(chain, gasUpdate);
}
}
/**
* @notice Allows the gasCollector to collect accumulated fees from the contract.
* @dev Use address(0) as the token address for native currency.
* @param receiver The address to receive the collected fees
* @param tokens Array of token addresses to be collected
* @param amounts Array of amounts to be collected for each respective token address
*/
function collectFees(
address payable receiver,
address[] calldata tokens,
uint256[] calldata amounts
) external onlyCollector {
if (receiver == address(0)) revert InvalidAddress();
uint256 tokensLength = tokens.length;
if (tokensLength != amounts.length) revert InvalidAmounts();
for (uint256 i; i < tokensLength; i++) {
address token = tokens[i];
uint256 amount = amounts[i];
if (amount == 0) revert InvalidAmounts();
if (token == address(0)) {
if (amount <= address(this).balance) receiver.safeNativeTransfer(amount);
} else {
// slither-disable-next-line calls-loop
if (amount <= IERC20(token).balanceOf(address(this))) IERC20(token).safeTransfer(receiver, amount);
}
}
}
/**
* @dev Deprecated refund function, kept for backward compatibility.
*/
function refund(
address payable receiver,
address token,
uint256 amount
) external onlyCollector {
_refund(bytes32(0), 0, receiver, token, amount);
}
/**
* @notice Refunds gas payment to the receiver in relation to a specific cross-chain transaction.
* @dev Only callable by the gasCollector.
* @dev Use address(0) as the token address to refund native currency.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param receiver The address to receive the refund
* @param token The token address to be refunded
* @param amount The amount to refund
*/
function refund(
bytes32 txHash,
uint256 logIndex,
address payable receiver,
address token,
uint256 amount
) external onlyCollector {
_refund(txHash, logIndex, receiver, token, amount);
}
/**
* @dev Internal function to implement gas refund logic.
*/
function _refund(
bytes32 txHash,
uint256 logIndex,
address payable receiver,
address token,
uint256 amount
) private {
if (receiver == address(0)) revert InvalidAddress();
emit Refunded(txHash, logIndex, receiver, token, amount);
if (token == address(0)) {
receiver.safeNativeTransfer(amount);
} else {
IERC20(token).safeTransfer(receiver, amount);
}
}
/**
* @notice Returns a unique identifier for the contract.
* @return bytes32 Hash of the contract identifier
*/
function contractId() external pure returns (bytes32) {
return keccak256('axelar-gas-service');
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { GasEstimationType, GasInfo } from '../types/GasEstimationTypes.sol';
import { IInterchainGasEstimation } from '../interfaces/IInterchainGasEstimation.sol';
/**
* @title InterchainGasEstimation
* @notice This is an abstract contract that allows for estimating gas fees for cross-chain communication on the Axelar network.
*/
abstract contract InterchainGasEstimation is IInterchainGasEstimation {
// keccak256('GasEstimate.Slot') - 1
bytes32 internal constant GAS_SERVICE_SLOT = 0x2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a3902;
// 68 bytes for the TX RLP encoding overhead
uint256 internal constant TX_ENCODING_OVERHEAD = 68;
// GMP executeWithToken call parameters
// 4 bytes for method selector, 32 bytes for the commandId, 96 bytes for the sourceChain, 128 bytes for the sourceAddress, 96 bytes for token symbol, 32 bytes for amount
// Expecting most of the calldata bytes to be zeroes. So multiplying by 8 as a weighted average of 4 and 16
uint256 internal constant GMP_CALLDATA_SIZE = 4 + 32 + 96 + 128 + 96 + 32; // 388 bytes
struct GasServiceStorage {
mapping(string => GasInfo) gasPrices;
}
/**
* @notice Returns the gas price for a specific chain.
* @param chain The name of the chain
* @return gasInfo The gas info for the chain
*/
function getGasInfo(string calldata chain) external view returns (GasInfo memory) {
return _storage().gasPrices[chain];
}
/**
* @notice Sets the gas price for a specific chain.
* @dev This function is called by the gas oracle to update the gas price for a specific chain.
* @param chain The name of the chain
* @param gasInfo The gas info for the chain
*/
function _setGasInfo(string calldata chain, GasInfo calldata gasInfo) internal {
emit GasInfoUpdated(chain, gasInfo);
_storage().gasPrices[chain] = gasInfo;
}
/**
* @notice Estimates the gas fee for a contract call on a destination chain.
* @param destinationChain Axelar registered name of the destination chain
* param destinationAddress Destination contract address being called
* @param executionGasLimit The gas limit to be used for the destination contract execution,
* e.g. pass in 200k if your app consumes needs upto 200k for this contract call
* param params Additional parameters for the gas estimation
* @return gasEstimate The cross-chain gas estimate, in terms of source chain's native gas token that should be forwarded to the gas service.
*/
function estimateGasFee(
string calldata destinationChain,
string calldata, /* destinationAddress */
bytes calldata payload,
uint256 executionGasLimit,
bytes calldata /* params */
) public view returns (uint256 gasEstimate) {
GasInfo storage gasInfo = _storage().gasPrices[destinationChain];
GasEstimationType gasEstimationType = GasEstimationType(gasInfo.gasEstimationType);
gasEstimate = gasInfo.axelarBaseFee + (executionGasLimit * gasInfo.relativeGasPrice);
// if chain is L2, compute L1 data fee using L1 gas price info
if (gasEstimationType != GasEstimationType.Default) {
GasInfo storage l1GasInfo = _storage().gasPrices['ethereum'];
gasEstimate += computeL1DataFee(gasEstimationType, payload, gasInfo, l1GasInfo);
}
}
/**
* @notice Computes the additional L1 data fee for an L2 destination chain.
* @param gasEstimationType The gas estimation type
* @param payload The payload of the contract call
* @param l1GasInfo The L1 gas info
* @return l1DataFee The L1 to L2 data fee
*/
function computeL1DataFee(
GasEstimationType gasEstimationType,
bytes calldata payload,
GasInfo storage gasInfo,
GasInfo storage l1GasInfo
) internal view returns (uint256) {
if (gasEstimationType == GasEstimationType.OptimismEcotone) {
return optimismEcotoneL1Fee(payload, gasInfo, l1GasInfo);
}
if (gasEstimationType == GasEstimationType.OptimismBedrock) {
return optimismBedrockL1Fee(payload, gasInfo, l1GasInfo);
}
if (gasEstimationType == GasEstimationType.Arbitrum) {
return arbitrumL1Fee(payload, gasInfo, l1GasInfo);
}
if (gasEstimationType == GasEstimationType.Scroll) {
return scrollL1Fee(payload, gasInfo, l1GasInfo);
}
revert UnsupportedEstimationType(gasEstimationType);
}
/**
* @notice Computes the L1 to L2 fee for an OP chain with Ecotone gas model.
* @param payload The payload of the contract call
* @param gasInfo Destination chain gas info
* @param l1GasInfo The L1 gas info
* @return l1DataFee The L1 to L2 data fee
*/
function optimismEcotoneL1Fee(
bytes calldata payload,
GasInfo storage gasInfo,
GasInfo storage l1GasInfo
) internal view returns (uint256 l1DataFee) {
/* Optimism Ecotone gas model https://docs.optimism.io/stack/transactions/fees#ecotone
tx_compressed_size = ((count_zero_bytes(tx_data) * 4 + count_non_zero_bytes(tx_data) * 16)) / 16
weighted_gas_price = 16 * base_fee_scalar*base_fee + blob_base_fee_scalar * blob_base_fee
l1_data_fee = tx_compressed_size * weighted_gas_price
Reference implementation:
https://github.com/ethereum-optimism/optimism/blob/876e16ad04968f0bb641eb76f98eb77e7e1a3e16/packages/contracts-bedrock/src/L2/GasPriceOracle.sol#L138
*/
// The new base_fee_scalar is currently set to 0.001368
// We are setting it to un upper bound of 0.0015 to account for possible fluctuations
uint256 scalarPrecision = 10**6;
// The blob_base_fee_scalar is currently set to 0.810949. Setting it to 0.9 as an upper bound
// https://eips.ethereum.org/EIPS/eip-4844
uint256 blobBaseFeeScalar = 9 * 10**5; // 0.9 multiplied by scalarPrecision
// Calculating transaction size in bytes that will later be divided by 16 to compress the size
uint256 txSize = _l1TxSize(payload);
uint256 weightedGasPrice = 16 *
gasInfo.l1FeeScalar *
l1GasInfo.relativeGasPrice +
blobBaseFeeScalar *
l1GasInfo.relativeBlobBaseFee;
l1DataFee = (weightedGasPrice * txSize) / (16 * scalarPrecision); // 16 for txSize compression and scalar precision conversion
}
/**
* @notice Computes the L1 to L2 fee for an OP chain with Bedrock gas model.
* @param payload The payload of the contract call
* @param gasInfo Destination chain gas info
* @param l1GasInfo The L1 gas info
* @return l1DataFee The L1 to L2 data fee
*/
function optimismBedrockL1Fee(
bytes calldata payload,
GasInfo storage gasInfo,
GasInfo storage l1GasInfo
) internal view returns (uint256 l1DataFee) {
// Resembling OP Bedrock gas price model
// https://docs.optimism.io/stack/transactions/fees#bedrock
// https://docs-v2.mantle.xyz/devs/concepts/tx-fee/ef
// Reference https://github.com/mantlenetworkio/mantle-v2/blob/a29f01045191344b0ba89542215e6a02bd5e7fcc/packages/contracts-bedrock/contracts/L2/GasPriceOracle.sol#L98-L105
uint256 overhead = 188;
uint256 precision = 1e6;
uint256 txSize = _l1TxSize(payload) + overhead;
return (l1GasInfo.relativeGasPrice * txSize * gasInfo.l1FeeScalar) / precision;
}
/**
* @notice Computes the L1 to L2 fee for a contract call on the Arbitrum chain.
* @param payload The payload of the contract call
* param gasInfo Destination chain gas info
* @param l1GasInfo The L1 gas info
* @return l1DataFee The L1 to L2 data fee
*/
function arbitrumL1Fee(
bytes calldata payload,
GasInfo storage, /* gasInfo */
GasInfo storage l1GasInfo
) internal view returns (uint256 l1DataFee) {
// https://docs.arbitrum.io/build-decentralized-apps/how-to-estimate-gas
// https://docs.arbitrum.io/arbos/l1-pricing
// Reference https://github.com/OffchainLabs/nitro/blob/master/arbos/l1pricing/l1pricing.go#L565-L578
uint256 oneInBips = 10000;
uint256 txDataNonZeroGasEIP2028 = 16;
uint256 estimationPaddingUnits = 16 * txDataNonZeroGasEIP2028;
uint256 estimationPaddingBasisPoints = 100;
uint256 l1Bytes = TX_ENCODING_OVERHEAD + GMP_CALLDATA_SIZE + payload.length;
// Brotli baseline compression rate as 2x
uint256 units = (txDataNonZeroGasEIP2028 * l1Bytes) / 2;
return
(l1GasInfo.relativeGasPrice *
(units + estimationPaddingUnits) *
(oneInBips + estimationPaddingBasisPoints)) / oneInBips;
}
/**
* @notice Computes the L1 to L2 fee for a contract call on the Scroll chain.
* @param payload The payload of the contract call
* @param gasInfo Destination chain gas info
* @param l1GasInfo The L1 gas info
* @return l1DataFee The L1 to L2 data fee
*/
function scrollL1Fee(
bytes calldata payload,
GasInfo storage gasInfo,
GasInfo storage l1GasInfo
) internal view returns (uint256 l1DataFee) {
// https://docs.scroll.io/en/developers/guides/estimating-gas-and-tx-fees/
// Reference https://github.com/scroll-tech/scroll/blob/af2913903b181f3492af1c62b4da4c1c99cc552d/contracts/src/L2/predeploys/L1GasPriceOracle.sol#L63-L86
uint256 overhead = 2500;
uint256 precision = 1e9;
uint256 txSize = _l1TxSize(payload) + overhead + (4 * 16);
return (l1GasInfo.relativeGasPrice * txSize * gasInfo.l1FeeScalar) / precision;
}
/**
* @notice Computes the transaction size for an L1 transaction
* @param payload The payload of the contract call
* @return txSize The transaction size
*/
function _l1TxSize(bytes calldata payload) private pure returns (uint256 txSize) {
txSize = TX_ENCODING_OVERHEAD * 16;
// GMP executeWithToken call parameters
// Expecting most of the calldata bytes to be zeroes. So multiplying by 8 as a weighted average of 4 and 16
txSize += GMP_CALLDATA_SIZE * 8;
uint256 length = payload.length;
for (uint256 i; i < length; ++i) {
if (payload[i] == 0) {
txSize += 4; // 4 for each zero byte
} else {
txSize += 16; // 16 for each non-zero byte
}
}
}
/**
* @notice Get the storage slot for the GasServiceStorage struct
*/
function _storage() private pure returns (GasServiceStorage storage slot) {
assembly {
slot.slot := GAS_SERVICE_SLOT
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { GasInfo } from '../types/GasEstimationTypes.sol';
import { IInterchainGasEstimation } from './IInterchainGasEstimation.sol';
import { IUpgradable } from './IUpgradable.sol';
/**
* @title IAxelarGasService Interface
* @notice This is an interface for the AxelarGasService contract which manages gas payments
* and refunds for cross-chain communication on the Axelar network.
* @dev This interface inherits IUpgradable
*/
interface IAxelarGasService is IInterchainGasEstimation, IUpgradable {
error InvalidAddress();
error NotCollector();
error InvalidAmounts();
error InvalidGasUpdates();
error InvalidParams();
error InsufficientGasPayment(uint256 required, uint256 provided);
event GasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForExpressCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForExpressCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForExpressCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForExpressCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
uint256 gasFeeAmount,
address refundAddress
);
event GasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);
event ExpressGasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeExpressGasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
uint256 gasFeeAmount,
address refundAddress
);
event Refunded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address payable receiver,
address token,
uint256 amount
);
/**
* @notice Pay for gas for any type of contract execution on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @dev If estimateOnChain is true, the function will estimate the gas cost and revert if the payment is insufficient.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param executionGasLimit The gas limit for the contract call
* @param estimateOnChain Flag to enable on-chain gas estimation
* @param refundAddress The address where refunds, if any, should be sent
* @param params Additional parameters for gas payment. This can be left empty for normal contract call payments.
*/
function payGas(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
uint256 executionGasLimit,
bool estimateOnChain,
address refundAddress,
bytes calldata params
) external payable;
/**
* @notice Pay for gas using ERC20 tokens for a contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
/**
* @notice Pay for gas using ERC20 tokens for a contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
/**
* @notice Pay for gas using native currency for a contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable;
/**
* @notice Pay for gas using native currency for a contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable;
/**
* @notice Pay for gas using ERC20 tokens for an express contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForExpressCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
/**
* @notice Pay for gas using ERC20 tokens for an express contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param gasToken The address of the ERC20 token used to pay for gas
* @param gasFeeAmount The amount of tokens to pay for gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function payGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
/**
* @notice Pay for gas using native currency for an express contract call on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForExpressCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable;
/**
* @notice Pay for gas using native currency for an express contract call with tokens on a destination chain.
* @dev This function is called on the source chain before calling the gateway to execute a remote contract.
* @param sender The address making the payment
* @param destinationChain The target chain where the contract call with tokens will be made
* @param destinationAddress The target address on the destination chain
* @param payload Data payload for the contract call with tokens
* @param symbol The symbol of the token to be sent with the call
* @param amount The amount of tokens to be sent with the call
* @param refundAddress The address where refunds, if any, should be sent
*/
function payNativeGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable;
/**
* @notice Add additional gas payment using ERC20 tokens after initiating a cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param gasToken The ERC20 token address used to add gas
* @param gasFeeAmount The amount of tokens to add as gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function addGas(
bytes32 txHash,
uint256 logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
/**
* @notice Add additional gas payment using native currency after initiating a cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param refundAddress The address where refunds, if any, should be sent
*/
function addNativeGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable;
/**
* @notice Add additional gas payment using ERC20 tokens after initiating an express cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param gasToken The ERC20 token address used to add gas
* @param gasFeeAmount The amount of tokens to add as gas
* @param refundAddress The address where refunds, if any, should be sent
*/
function addExpressGas(
bytes32 txHash,
uint256 logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
/**
* @notice Add additional gas payment using native currency after initiating an express cross-chain call.
* @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param refundAddress The address where refunds, if any, should be sent
*/
function addNativeExpressGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable;
/**
* @notice Updates the gas price for a specific chain.
* @dev This function is called by the gas oracle to update the gas prices for a specific chains.
* @param chains Array of chain names
* @param gasUpdates Array of gas updates
*/
function updateGasInfo(string[] calldata chains, GasInfo[] calldata gasUpdates) external;
/**
* @notice Allows the gasCollector to collect accumulated fees from the contract.
* @dev Use address(0) as the token address for native currency.
* @param receiver The address to receive the collected fees
* @param tokens Array of token addresses to be collected
* @param amounts Array of amounts to be collected for each respective token address
*/
function collectFees(
address payable receiver,
address[] calldata tokens,
uint256[] calldata amounts
) external;
/**
* @notice Refunds gas payment to the receiver in relation to a specific cross-chain transaction.
* @dev Only callable by the gasCollector.
* @dev Use address(0) as the token address to refund native currency.
* @param txHash The transaction hash of the cross-chain call
* @param logIndex The log index for the cross-chain call
* @param receiver The address to receive the refund
* @param token The token address to be refunded
* @param amount The amount to refund
*/
function refund(
bytes32 txHash,
uint256 logIndex,
address payable receiver,
address token,
uint256 amount
) external;
/**
* @notice Returns the address of the designated gas collector.
* @return address of the gas collector
*/
function gasCollector() external returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// General interface for upgradable contracts
interface IContractIdentifier {
/**
* @notice Returns the contract ID. It can be used as a check during upgrades.
* @dev Meant to be overridden in derived contracts.
* @return bytes32 The contract ID
*/
function contractId() external pure returns (bytes32);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
error InvalidAccount();
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IContractIdentifier } from './IContractIdentifier.sol';
interface IImplementation is IContractIdentifier {
error NotProxy();
function setup(bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { GasEstimationType, GasInfo } from '../types/GasEstimationTypes.sol';
/**
* @title IInterchainGasEstimation Interface
* @notice This is an interface for the InterchainGasEstimation contract
* which allows for estimating gas fees for cross-chain communication on the Axelar network.
*/
interface IInterchainGasEstimation {
error UnsupportedEstimationType(GasEstimationType gasEstimationType);
/**
* @notice Event emitted when the gas price for a specific chain is updated.
* @param chain The name of the chain
* @param info The gas info for the chain
*/
event GasInfoUpdated(string chain, GasInfo info);
/**
* @notice Returns the gas price for a specific chain.
* @param chain The name of the chain
* @return gasInfo The gas info for the chain
*/
function getGasInfo(string calldata chain) external view returns (GasInfo memory);
/**
* @notice Estimates the gas fee for a cross-chain contract call.
* @param destinationChain Axelar registered name of the destination chain
* @param destinationAddress Destination contract address being called
* @param executionGasLimit The gas limit to be used for the destination contract execution,
* e.g. pass in 200k if your app consumes needs upto 200k for this contract call
* @param params Additional parameters for the gas estimation
* @return gasEstimate The cross-chain gas estimate, in terms of source chain's native gas token that should be forwarded to the gas service.
*/
function estimateGasFee(
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
uint256 executionGasLimit,
bytes calldata params
) external view returns (uint256 gasEstimate);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IOwnable Interface
* @notice IOwnable is an interface that abstracts the implementation of a
* contract with ownership control features. It's commonly used in upgradable
* contracts and includes the functionality to get current owner, transfer
* ownership, and propose and accept ownership.
*/
interface IOwnable {
error NotOwner();
error InvalidOwner();
error InvalidOwnerAddress();
event OwnershipTransferStarted(address indexed newOwner);
event OwnershipTransferred(address indexed newOwner);
/**
* @notice Returns the current owner of the contract.
* @return address The address of the current owner
*/
function owner() external view returns (address);
/**
* @notice Returns the address of the pending owner of the contract.
* @return address The address of the pending owner
*/
function pendingOwner() external view returns (address);
/**
* @notice Transfers ownership of the contract to a new address
* @param newOwner The address to transfer ownership to
*/
function transferOwnership(address newOwner) external;
/**
* @notice Proposes to transfer the contract's ownership to a new address.
* The new owner needs to accept the ownership explicitly.
* @param newOwner The address to transfer ownership to
*/
function proposeOwnership(address newOwner) external;
/**
* @notice Transfers ownership to the pending owner.
* @dev Can only be called by the pending owner
*/
function acceptOwnership() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IOwnable } from './IOwnable.sol';
import { IImplementation } from './IImplementation.sol';
// General interface for upgradable contracts
interface IUpgradable is IOwnable, IImplementation {
error InvalidCodeHash();
error InvalidImplementation();
error SetupFailed();
event Upgraded(address indexed newImplementation);
function implementation() external view returns (address);
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata params
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
error NativeTransferFailed();
/*
* @title SafeNativeTransfer
* @dev This library is used for performing safe native value transfers in Solidity by utilizing inline assembly.
*/
library SafeNativeTransfer {
/*
* @notice Perform a native transfer to a given address.
* @param receiver The recipient address to which the amount will be sent.
* @param amount The amount of native value to send.
* @throws NativeTransferFailed error if transfer is not successful.
*/
function safeNativeTransfer(address receiver, uint256 amount) internal {
bool success;
assembly {
success := call(gas(), receiver, amount, 0, 0, 0, 0)
}
if (!success) revert NativeTransferFailed();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IERC20 } from '../interfaces/IERC20.sol';
error TokenTransferFailed();
/*
* @title SafeTokenCall
* @dev This library is used for performing safe token transfers.
*/
library SafeTokenCall {
/*
* @notice Make a safe call to a token contract.
* @param token The token contract to interact with.
* @param callData The function call data.
* @throws TokenTransferFailed error if transfer of token is not successful.
*/
function safeCall(IERC20 token, bytes memory callData) internal {
(bool success, bytes memory returnData) = address(token).call(callData);
bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));
if (!transferred || address(token).code.length == 0) revert TokenTransferFailed();
}
}
/*
* @title SafeTokenTransfer
* @dev This library safely transfers tokens from the contract to a recipient.
*/
library SafeTokenTransfer {
/*
* @notice Transfer tokens to a recipient.
* @param token The token contract.
* @param receiver The recipient of the tokens.
* @param amount The amount of tokens to transfer.
*/
function safeTransfer(
IERC20 token,
address receiver,
uint256 amount
) internal {
SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount));
}
}
/*
* @title SafeTokenTransferFrom
* @dev This library helps to safely transfer tokens on behalf of a token holder.
*/
library SafeTokenTransferFrom {
/*
* @notice Transfer tokens on behalf of a token holder.
* @param token The token contract.
* @param from The address of the token holder.
* @param to The address the tokens are to be sent to.
* @param amount The amount of tokens to be transferred.
*/
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 amount
) internal {
SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title GasEstimationType
* @notice This enum represents the gas estimation types for different chains.
*/
enum GasEstimationType {
Default,
OptimismEcotone,
OptimismBedrock,
Arbitrum,
Scroll
}
/**
* @title GasInfo
* @notice This struct represents the gas pricing information for a specific chain.
* @dev Smaller uint types are used for efficient struct packing to save storage costs.
*/
struct GasInfo {
/// @dev Custom gas pricing rule, such as L1 data fee on L2s
uint64 gasEstimationType;
/// @dev Scalar value needed for specific gas estimation types, expected to be less than 1e10
uint64 l1FeeScalar;
/// @dev Axelar base fee for cross-chain message approval on destination, in terms of source native gas token
uint128 axelarBaseFee;
/// @dev Gas price of destination chain, in terms of the source chain token, i.e dest_gas_price * dest_token_market_price / src_token_market_price
uint128 relativeGasPrice;
/// @dev Needed for specific gas estimation types. Blob base fee of destination chain, in terms of the source chain token, i.e dest_blob_base_fee * dest_token_market_price / src_token_market_price
uint128 relativeBlobBaseFee;
/// @dev Axelar express fee for express execution, in terms of source chain token
uint128 expressFee;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IImplementation } from '../interfaces/IImplementation.sol';
/**
* @title Implementation
* @notice This contract serves as a base for other contracts and enforces a proxy-first access restriction.
* @dev Derived contracts must implement the setup function.
*/
abstract contract Implementation is IImplementation {
address private immutable implementationAddress;
/**
* @dev Contract constructor that sets the implementation address to the address of this contract.
*/
constructor() {
implementationAddress = address(this);
}
/**
* @dev Modifier to require the caller to be the proxy contract.
* Reverts if the caller is the current contract (i.e., the implementation contract itself).
*/
modifier onlyProxy() {
if (implementationAddress == address(this)) revert NotProxy();
_;
}
/**
* @notice Initializes contract parameters.
* This function is intended to be overridden by derived contracts.
* The overriding function must have the onlyProxy modifier.
* @param params The parameters to be used for initialization
*/
function setup(bytes calldata params) external virtual;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IImplementation } from '../interfaces/IImplementation.sol';
import { IUpgradable } from '../interfaces/IUpgradable.sol';
import { Ownable } from '../utils/Ownable.sol';
import { Implementation } from './Implementation.sol';
/**
* @title Upgradable Contract
* @notice This contract provides an interface for upgradable smart contracts and includes the functionality to perform upgrades.
*/
abstract contract Upgradable is Ownable, Implementation, IUpgradable {
// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @notice Constructor sets the implementation address to the address of the contract itself
* @dev This is used in the onlyProxy modifier to prevent certain functions from being called directly
* on the implementation contract itself.
* @dev The owner is initially set as address(1) because the actual owner is set within the proxy. It is not
* set as the zero address because Ownable is designed to throw an error for ownership transfers to the zero address.
*/
constructor() Ownable(address(1)) {}
/**
* @notice Returns the address of the current implementation
* @return implementation_ Address of the current implementation
*/
function implementation() public view returns (address implementation_) {
assembly {
implementation_ := sload(_IMPLEMENTATION_SLOT)
}
}
/**
* @notice Upgrades the contract to a new implementation
* @param newImplementation The address of the new implementation contract
* @param newImplementationCodeHash The codehash of the new implementation contract
* @param params Optional setup parameters for the new implementation contract
* @dev This function is only callable by the owner.
*/
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata params
) external override onlyOwner {
if (IUpgradable(newImplementation).contractId() != IUpgradable(implementation()).contractId())
revert InvalidImplementation();
if (newImplementationCodeHash != newImplementation.codehash) revert InvalidCodeHash();
assembly {
sstore(_IMPLEMENTATION_SLOT, newImplementation)
}
emit Upgraded(newImplementation);
if (params.length > 0) {
// slither-disable-next-line controlled-delegatecall
(bool success, ) = newImplementation.delegatecall(abi.encodeWithSelector(this.setup.selector, params));
if (!success) revert SetupFailed();
}
}
/**
* @notice Sets up the contract with initial data
* @param data Initialization data for the contract
* @dev This function is only callable by the proxy contract.
*/
function setup(bytes calldata data) external override(IImplementation, Implementation) onlyProxy {
_setup(data);
}
/**
* @notice Internal function to set up the contract with initial data
* @param data Initialization data for the contract
* @dev This function should be implemented in derived contracts.
*/
function _setup(bytes calldata data) internal virtual {}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IOwnable } from '../interfaces/IOwnable.sol';
/**
* @title Ownable
* @notice A contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The owner account is set through ownership transfer. This module makes
* it possible to transfer the ownership of the contract to a new account in one
* step, as well as to an interim pending owner. In the second flow the ownership does not
* change until the pending owner accepts the ownership transfer.
*/
abstract contract Ownable is IOwnable {
// keccak256('owner')
bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0;
// keccak256('ownership-transfer')
bytes32 internal constant _OWNERSHIP_TRANSFER_SLOT =
0x9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1;
/**
* @notice Initializes the contract by transferring ownership to the owner parameter.
* @param _owner Address to set as the initial owner of the contract
*/
constructor(address _owner) {
_transferOwnership(_owner);
}
/**
* @notice Modifier that throws an error if called by any account other than the owner.
*/
modifier onlyOwner() {
if (owner() != msg.sender) revert NotOwner();
_;
}
/**
* @notice Returns the current owner of the contract.
* @return owner_ The current owner of the contract
*/
function owner() public view returns (address owner_) {
assembly {
owner_ := sload(_OWNER_SLOT)
}
}
/**
* @notice Returns the pending owner of the contract.
* @return owner_ The pending owner of the contract
*/
function pendingOwner() public view returns (address owner_) {
assembly {
owner_ := sload(_OWNERSHIP_TRANSFER_SLOT)
}
}
/**
* @notice Transfers ownership of the contract to a new account `newOwner`.
* @dev Can only be called by the current owner.
* @param newOwner The address to transfer ownership to
*/
function transferOwnership(address newOwner) external virtual onlyOwner {
_transferOwnership(newOwner);
}
/**
* @notice Propose to transfer ownership of the contract to a new account `newOwner`.
* @dev Can only be called by the current owner. The ownership does not change
* until the new owner accepts the ownership transfer.
* @param newOwner The address to transfer ownership to
*/
function proposeOwnership(address newOwner) external virtual onlyOwner {
if (newOwner == address(0)) revert InvalidOwnerAddress();
emit OwnershipTransferStarted(newOwner);
assembly {
sstore(_OWNERSHIP_TRANSFER_SLOT, newOwner)
}
}
/**
* @notice Accepts ownership of the contract.
* @dev Can only be called by the pending owner
*/
function acceptOwnership() external virtual {
address newOwner = pendingOwner();
if (newOwner != msg.sender) revert InvalidOwner();
_transferOwnership(newOwner);
}
/**
* @notice Internal function to transfer ownership of the contract to a new account `newOwner`.
* @dev Called in the constructor to set the initial owner.
* @param newOwner The address to transfer ownership to
*/
function _transferOwnership(address newOwner) internal virtual {
if (newOwner == address(0)) revert InvalidOwnerAddress();
emit OwnershipTransferred(newOwner);
assembly {
sstore(_OWNER_SLOT, newOwner)
sstore(_OWNERSHIP_TRANSFER_SLOT, 0)
}
}
}{
"evmVersion": "london",
"optimizer": {
"enabled": true,
"runs": 1000,
"details": {
"peephole": true,
"inliner": true,
"jumpdestRemover": true,
"orderLiterals": true,
"deduplicate": true,
"cse": true,
"constantOptimizer": true,
"yul": true,
"yulDetails": {
"stackAllocation": true
}
}
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"gasCollector_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"},{"internalType":"uint256","name":"provided","type":"uint256"}],"name":"InsufficientGasPayment","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAmounts","type":"error"},{"inputs":[],"name":"InvalidCodeHash","type":"error"},{"inputs":[],"name":"InvalidGasUpdates","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidOwnerAddress","type":"error"},{"inputs":[],"name":"InvalidParams","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[],"name":"NotCollector","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotProxy","type":"error"},{"inputs":[],"name":"SetupFailed","type":"error"},{"inputs":[],"name":"TokenTransferFailed","type":"error"},{"inputs":[{"internalType":"enum GasEstimationType","name":"gasEstimationType","type":"uint8"}],"name":"UnsupportedEstimationType","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"ExpressGasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"chain","type":"string"},{"components":[{"internalType":"uint64","name":"gasEstimationType","type":"uint64"},{"internalType":"uint64","name":"l1FeeScalar","type":"uint64"},{"internalType":"uint128","name":"axelarBaseFee","type":"uint128"},{"internalType":"uint128","name":"relativeGasPrice","type":"uint128"},{"internalType":"uint128","name":"relativeBlobBaseFee","type":"uint128"},{"internalType":"uint128","name":"expressFee","type":"uint128"}],"indexed":false,"internalType":"struct GasInfo","name":"info","type":"tuple"}],"name":"GasInfoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForContractCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForContractCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForExpressCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForExpressCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeExpressGasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForContractCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForContractCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForExpressCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForExpressCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"address payable","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Refunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addExpressGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addNativeExpressGas","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addNativeGas","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint256","name":"executionGasLimit","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"estimateGasFee","outputs":[{"internalType":"uint256","name":"gasEstimate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"chain","type":"string"}],"name":"getGasInfo","outputs":[{"components":[{"internalType":"uint64","name":"gasEstimationType","type":"uint64"},{"internalType":"uint64","name":"l1FeeScalar","type":"uint64"},{"internalType":"uint128","name":"axelarBaseFee","type":"uint128"},{"internalType":"uint128","name":"relativeGasPrice","type":"uint128"},{"internalType":"uint128","name":"relativeBlobBaseFee","type":"uint128"},{"internalType":"uint128","name":"expressFee","type":"uint128"}],"internalType":"struct GasInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"uint256","name":"executionGasLimit","type":"uint256"},{"internalType":"bool","name":"estimateOnChain","type":"bool"},{"internalType":"address","name":"refundAddress","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"payGas","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForContractCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForContractCallWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForExpressCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForExpressCallWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForContractCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForContractCallWithToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForExpressCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForExpressCallWithToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"proposeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"chains","type":"string[]"},{"components":[{"internalType":"uint64","name":"gasEstimationType","type":"uint64"},{"internalType":"uint64","name":"l1FeeScalar","type":"uint64"},{"internalType":"uint128","name":"axelarBaseFee","type":"uint128"},{"internalType":"uint128","name":"relativeGasPrice","type":"uint128"},{"internalType":"uint128","name":"relativeBlobBaseFee","type":"uint128"},{"internalType":"uint128","name":"expressFee","type":"uint128"}],"internalType":"struct GasInfo[]","name":"gasUpdates","type":"tuple[]"}],"name":"updateGasInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes32","name":"newImplementationCodeHash","type":"bytes32"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162002f5f38038062002f5f8339810160408190526200003491620000fc565b6001620000418162000058565b50306080526001600160a01b031660a0526200012e565b6001600160a01b0381166200008057604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6000602082840312156200010f57600080fd5b81516001600160a01b03811681146200012757600080fd5b9392505050565b60805160a051612def62000170600039600081816104240152818161067201528181610afc01528181610ce5015261131f01526000610e190152612def6000f3fe6080604052600436106101c25760003560e01c8063892b5007116100f7578063cd433ada11610095578063edf936f211610064578063edf936f214610594578063f2fde38b146105a7578063f61ed218146105c7578063fd09e3bd146105da57600080fd5b8063cd433ada1461050d578063d3b81f0c14610520578063e30c397814610540578063edb6b3a51461057457600080fd5b8063a3499c73116100d1578063a3499c731461049a578063ab1999ba146104ba578063ba9ddc8d146104da578063c62c2002146104fa57600080fd5b8063892b5007146104125780638da5cb5b146104465780639ded06df1461047a57600080fd5b80634d2384891161016457806379ba50971161013e57806379ba50971461031d5780638291286c1461033257806382ad6f351461036557806386389f021461038557600080fd5b80634d238489146102a25780635c60da1b146102b5578063710bf322146102fd57600080fd5b806317a49f7c116101a057806317a49f7c1461022f5780632e9b74701461024f5780632edd2aa814610262578063365047211461028257600080fd5b80630c93e3bb146101c75780631055eaaf146101dc578063135eaa70146101fc575b600080fd5b6101da6101d5366004611e59565b6105fa565b005b3480156101e857600080fd5b506101da6101f7366004611f5e565b610667565b34801561020857600080fd5b5061021c610217366004611fe1565b610846565b6040519081526020015b60405180910390f35b34801561023b57600080fd5b506101da61024a366004612154565b610980565b6101da61025d366004612272565b610a0c565b34801561026e57600080fd5b506101da61027d366004612365565b610a82565b34801561028e57600080fd5b506101da61029d3660046123bb565b610af1565b6101da6102b036600461240d565b610b46565b3480156102c157600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545b6040516001600160a01b039091168152602001610226565b34801561030957600080fd5b506101da610318366004612446565b610b91565b34801561032957600080fd5b506101da610c60565b34801561033e57600080fd5b507ffaa2f015f2ce5aee225904728de2def86eb8837491efd21f1a04fc20d8e923f661021c565b34801561037157600080fd5b506101da61038036600461246a565b610cda565b34801561039157600080fd5b506103a56103a03660046124ab565b610d35565b6040516102269190600060c08201905067ffffffffffffffff8084511683528060208501511660208401525060408301516001600160801b0380821660408501528060608601511660608501528060808601511660808501528060a08601511660a0850152505092915050565b34801561041e57600080fd5b506102e57f000000000000000000000000000000000000000000000000000000000000000081565b34801561045257600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0546102e5565b34801561048657600080fd5b506101da6104953660046124ab565b610e16565b3480156104a657600080fd5b506101da6104b53660046124ed565b610e7c565b3480156104c657600080fd5b506101da6104d5366004612365565b61119c565b3480156104e657600080fd5b506101da6104f5366004612549565b6111eb565b6101da610508366004612272565b611271565b6101da61051b36600461240d565b6112d2565b34801561052c57600080fd5b506101da61053b366004612621565b611314565b34801561054c57600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1546102e5565b34801561058057600080fd5b506101da61058f366004612154565b611405565b6101da6105a23660046126d4565b611466565b3480156105b357600080fd5b506101da6105c2366004612446565b611574565b6101da6105d5366004611e59565b6115c4565b3480156105e657600080fd5b506101da6105f5366004612549565b61161f565b828260405161060a9291906127f0565b6040518091039020886001600160a01b03167f617332c1832058df6ee45fcbdf471251474c9945a8e5d229287a21a5f67ccf0a89898989348860405161065596959493929190612829565b60405180910390a35050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106af57604051623bb10360e91b815260040160405180910390fd5b6001600160a01b0385166106d65760405163e6c4247b60e01b815260040160405180910390fd5b828181146106f757604051636c2b7e2d60e11b815260040160405180910390fd5b60005b8181101561083d57600086868381811061071657610716612873565b905060200201602081019061072b9190612446565b9050600085858481811061074157610741612873565b9050602002013590508060000361076b57604051636c2b7e2d60e11b815260040160405180910390fd5b6001600160a01b03821661079857478111610793576107936001600160a01b038a168261167c565b610833565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156107f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108199190612889565b8111610833576108336001600160a01b0383168a836116c1565b50506001016106fa565b50505050505050565b6000807f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a390260405161087a908d908d906127f0565b908152604051908190036020019020805490915060009067ffffffffffffffff1660048111156108ac576108ac6128a2565b60018301549091506108c7906001600160801b0316876128ce565b82546108e39190600160801b90046001600160801b03166128e5565b925060008160048111156108f9576108f96128a2565b1461097157604080517f657468657265756d00000000000000000000000000000000000000000000000081527f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a390260088201529051908190036028019020610963828a8a868561176a565b61096d90856128e5565b9350505b50509998505050505050505050565b86866040516109909291906127f0565b60405180910390208c6001600160a01b03167fda4ed638a7ffe9e814722efdb9ad6058c152c19c8564ceffe52e11dda1ca32238d8d8d8d8b8b8b8b8b6040516109e19998979695949392919061291c565b60405180910390a36109fe6001600160a01b038416333085611844565b505050505050505050505050565b8585604051610a1c9291906127f0565b60405180910390208b6001600160a01b03167f8c092067e86e85e8cfbaf187202ef580cdfd7ec37fbec89191607de73ca800058c8c8c8c8a8a8a348b604051610a6d999897969594939291906129a5565b60405180910390a35050505050505050505050565b604080516001600160a01b03808616825260208201859052831691810191909152849086907ff0b09bf969e7958967e0968e22596f647dd6efa09f4778e0393967b881f4b09f906060015b60405180910390a3610aea6001600160a01b038416333085611844565b5050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b3957604051623bb10360e91b815260040160405180910390fd5b610aea8585858585611895565b604080513481526001600160a01b0383166020820152839185917fb26db521e067acd5c6e345ad92fa1ed06bc7fb2aedd68f35dc7a2e10d636fc9891015b60405180910390a3505050565b33610bba7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610be1576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116610c0857604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6000610c8a7f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b0381163314610cce576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd781611945565b50565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610d2257604051623bb10360e91b815260040160405180910390fd5b610d30600080858585611895565b505050565b6040805160c081018252600080825260208201819052818301819052606082018190526080820181905260a082015290517f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a390290610d9590859085906127f0565b90815260408051918290036020908101832060c084018352805467ffffffffffffffff808216865268010000000000000000820416928501929092526001600160801b03600160801b92839004811693850193909352600181015480841660608601529190910482166080840152600201541660a082015290505b92915050565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603610e78576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b33610ea57f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610ecc576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190612889565b846001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb19190612889565b14610fe8576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f831461102b576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8490556040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28015611196576000846001600160a01b0316639ded06df60e01b84846040516024016110b0929190612a0c565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161111b9190612a28565b600060405180830381855af49150503d8060008114611156576040519150601f19603f3d011682016040523d82523d6000602084013e61115b565b606091505b5050905080610aea576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b604080516001600160a01b03808616825260208201859052831691810191909152849086907f2275e75614080f9782f72563c2c1688c901c5339c7f9f436d323f9386fed700a90606001610acd565b84846040516111fb9291906127f0565b60405180910390208a6001600160a01b03167fd171a7eb157e548ca493dd0a16016d125963a369ac5ae3c275ec12c96d5277028b8b8b8b8989896040516112489796959493929190612a44565b60405180910390a36112656001600160a01b038416333085611844565b50505050505050505050565b85856040516112819291906127f0565b60405180910390208b6001600160a01b03167f999d431b58761213cf53af96262b67a069cbd963499fd8effd1e21556217b8418c8c8c8c8a8a8a348b604051610a6d999897969594939291906129a5565b604080513481526001600160a01b0383166020820152839185917ffeb6b00343feee0f29a1a4345f8bf93ca1c73ee922248a4237a4e50d6447604e9101610b84565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461135c57604051623bb10360e91b815260040160405180910390fd5b82818114611396576040517fa5f1efe300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156113fd573660008787848181106113b6576113b6612873565b90506020028101906113c89190612a98565b91509150368686858181106113df576113df612873565b905060c0020190506113f28383836119e8565b505050600101611399565b505050505050565b86866040516114159291906127f0565b60405180910390208c6001600160a01b03167f8875f9764f28fa82d3e7ff1b80bd5c8f665e1f42fcd8c2faebc7c400a4ba1bbd8d8d8d8d8b8b8b8b8b6040516109e19998979695949392919061291c565b801561149e576040517fa86b651200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83156115035760006114b78c8c8c8c8c8c8c8a8a610846565b905034811115611501576040517f5b1fe5fc000000000000000000000000000000000000000000000000000000008152600481018290523460248201526044015b60405180910390fd5b505b86866040516115139291906127f0565b60405180910390208c6001600160a01b03167f617332c1832058df6ee45fcbdf471251474c9945a8e5d229287a21a5f67ccf0a8d8d8d8d348a60405161155e96959493929190612829565b60405180910390a3505050505050505050505050565b3361159d7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610cce576040516330cd747160e01b815260040160405180910390fd5b82826040516115d49291906127f0565b6040518091039020886001600160a01b03167f5cf48f121a0fecaa2c4a64b3eaf482c8c308d5387e161535970f3e9e4363eff689898989348860405161065596959493929190612829565b848460405161162f9291906127f0565b60405180910390208a6001600160a01b03167f99206760f0be19dd093729bd35e5924daff5e217bcedc5223ed067b60008cf8a8b8b8b8b8989896040516112489796959493929190612a44565b600080600080600085875af1905080610d30576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038316602482015260448101829052610d309084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a6e565b60006001866004811115611780576117806128a2565b036117985761179185858585611b45565b905061183b565b60028660048111156117ac576117ac6128a2565b036117bd5761179185858585611c08565b60038660048111156117d1576117d16128a2565b036117e25761179185858585611c7e565b60048660048111156117f6576117f66128a2565b036118075761179185858585611d1a565b856040517f10fcd31f0000000000000000000000000000000000000000000000000000000081526004016114f89190612adf565b95945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526111969085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611706565b6001600160a01b0383166118bc5760405163e6c4247b60e01b815260040160405180910390fd5b604080516001600160a01b03808616825284166020820152908101829052849086907fd5df103822011013c8c940930e5180419111c65abadd6525ca7e740d56b4703f9060600160405180910390a36001600160a01b0382166119315761192c6001600160a01b0384168261167c565b610aea565b610aea6001600160a01b03831684836116c1565b6001600160a01b03811661196c57604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b7f11415423beab67062fb0f3f22cb2a478e3b5a02a845dd62ddb7c12d11098ff1b838383604051611a1b93929190612b32565b60405180910390a1807f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a3902604051611a5590869086906127f0565b908152604051908190036020019020610aea8282612bf0565b600080836001600160a01b031683604051611a899190612a28565b6000604051808303816000865af19150503d8060008114611ac6576040519150601f19603f3d011682016040523d82523d6000602084013e611acb565b606091505b50915091506000828015611af7575081511580611af7575081806020019051810190611af79190612d33565b9050801580611b0e57506001600160a01b0385163b155b15610aea576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620f4240620dbba082611b5a8888611d45565b6001860154909150600090611b7f90600160801b90046001600160801b0316846128ce565b600187015488546001600160801b0390911690611bb39068010000000000000000900467ffffffffffffffff166010612d50565b67ffffffffffffffff16611bc79190612d74565b6001600160801b0316611bda91906128e5565b9050611be78460106128ce565b611bf183836128ce565b611bfb9190612d97565b9998505050505050505050565b600060bc620f42408282611c1c8989611d45565b611c2691906128e5565b8654600187015491925083916801000000000000000090910467ffffffffffffffff1690611c5e9084906001600160801b03166128ce565b611c6891906128ce565b611c729190612d97565b98975050505050505050565b6000612710601082611c9082806128ce565b90506064600088611ca461018460446128e5565b611cae91906128e5565b905060006002611cbe83876128ce565b611cc89190612d97565b905085611cd584826128e5565b611cdf86846128e5565b60018b0154611cf791906001600160801b03166128ce565b611d0191906128ce565b611d0b9190612d97565b9b9a5050505050505050505050565b60006109c4633b9aca008282611d308989611d45565b611d3a91906128e5565b611c269060406128e5565b6000611d53604460106128ce565b9050611d6261018460086128ce565b611d6c90826128e5565b90508160005b81811015611de357848482818110611d8c57611d8c612873565b909101357fff00000000000000000000000000000000000000000000000000000000000000166000039050611dcd57611dc66004846128e5565b9250611ddb565b611dd86010846128e5565b92505b600101611d72565b505092915050565b6001600160a01b0381168114610cd757600080fd5b8035611e0b81611deb565b919050565b60008083601f840112611e2257600080fd5b50813567ffffffffffffffff811115611e3a57600080fd5b602083019150836020828501011115611e5257600080fd5b9250929050565b60008060008060008060008060a0898b031215611e7557600080fd5b8835611e8081611deb565b9750602089013567ffffffffffffffff80821115611e9d57600080fd5b611ea98c838d01611e10565b909950975060408b0135915080821115611ec257600080fd5b611ece8c838d01611e10565b909750955060608b0135915080821115611ee757600080fd5b50611ef48b828c01611e10565b9094509250506080890135611f0881611deb565b809150509295985092959890939650565b60008083601f840112611f2b57600080fd5b50813567ffffffffffffffff811115611f4357600080fd5b6020830191508360208260051b8501011115611e5257600080fd5b600080600080600060608688031215611f7657600080fd5b8535611f8181611deb565b9450602086013567ffffffffffffffff80821115611f9e57600080fd5b611faa89838a01611f19565b90965094506040880135915080821115611fc357600080fd5b50611fd088828901611f19565b969995985093965092949392505050565b600080600080600080600080600060a08a8c031215611fff57600080fd5b893567ffffffffffffffff8082111561201757600080fd5b6120238d838e01611e10565b909b50995060208c013591508082111561203c57600080fd5b6120488d838e01611e10565b909950975060408c013591508082111561206157600080fd5b61206d8d838e01611e10565b909750955060608c0135945060808c013591508082111561208d57600080fd5b5061209a8c828d01611e10565b915080935050809150509295985092959850929598565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126120d857600080fd5b813567ffffffffffffffff808211156120f3576120f36120b1565b604051601f8301601f19908116603f0116810190828211818310171561211b5761211b6120b1565b8160405283815286602085880101111561213457600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806000806000806000806000806101208d8f03121561217757600080fd5b6121808d611e00565b9b5067ffffffffffffffff60208e0135111561219b57600080fd5b6121ab8e60208f01358f01611e10565b909b50995067ffffffffffffffff60408e013511156121c957600080fd5b6121d98e60408f01358f01611e10565b909950975067ffffffffffffffff60608e013511156121f757600080fd5b6122078e60608f01358f01611e10565b909750955067ffffffffffffffff60808e0135111561222557600080fd5b6122358e60808f01358f016120c7565b945060a08d0135935061224a60c08e01611e00565b925060e08d013591506122606101008e01611e00565b90509295989b509295989b509295989b565b600080600080600080600080600080600060e08c8e03121561229357600080fd5b61229c8c611e00565b9a5067ffffffffffffffff8060208e013511156122b857600080fd5b6122c88e60208f01358f01611e10565b909b50995060408d01358110156122de57600080fd5b6122ee8e60408f01358f01611e10565b909950975060608d013581101561230457600080fd5b6123148e60608f01358f01611e10565b909750955060808d013581101561232a57600080fd5b5061233b8d60808e01358e01611e10565b909450925060a08c0135915061235360c08d01611e00565b90509295989b509295989b9093969950565b600080600080600060a0868803121561237d57600080fd5b8535945060208601359350604086013561239681611deb565b92506060860135915060808601356123ad81611deb565b809150509295509295909350565b600080600080600060a086880312156123d357600080fd5b853594506020860135935060408601356123ec81611deb565b925060608601356123fc81611deb565b949793965091946080013592915050565b60008060006060848603121561242257600080fd5b8335925060208401359150604084013561243b81611deb565b809150509250925092565b60006020828403121561245857600080fd5b813561246381611deb565b9392505050565b60008060006060848603121561247f57600080fd5b833561248a81611deb565b9250602084013561249a81611deb565b929592945050506040919091013590565b600080602083850312156124be57600080fd5b823567ffffffffffffffff8111156124d557600080fd5b6124e185828601611e10565b90969095509350505050565b6000806000806060858703121561250357600080fd5b843561250e81611deb565b935060208501359250604085013567ffffffffffffffff81111561253157600080fd5b61253d87828801611e10565b95989497509550505050565b60008060008060008060008060008060e08b8d03121561256857600080fd5b8a3561257381611deb565b995060208b013567ffffffffffffffff8082111561259057600080fd5b61259c8e838f01611e10565b909b50995060408d01359150808211156125b557600080fd5b6125c18e838f01611e10565b909950975060608d01359150808211156125da57600080fd5b506125e78d828e01611e10565b90965094505060808b01356125fb81611deb565b925060a08b0135915061261060c08c01611e00565b90509295989b9194979a5092959850565b6000806000806040858703121561263757600080fd5b843567ffffffffffffffff8082111561264f57600080fd5b61265b88838901611f19565b9096509450602087013591508082111561267457600080fd5b818701915087601f83011261268857600080fd5b81358181111561269757600080fd5b88602060c0830285010111156126ac57600080fd5b95989497505060200194505050565b8015158114610cd757600080fd5b8035611e0b816126bb565b6000806000806000806000806000806000806101008d8f0312156126f757600080fd5b6127008d611e00565b9b5067ffffffffffffffff60208e0135111561271b57600080fd5b61272b8e60208f01358f01611e10565b909b50995067ffffffffffffffff60408e0135111561274957600080fd5b6127598e60408f01358f01611e10565b909950975067ffffffffffffffff60608e0135111561277757600080fd5b6127878e60608f01358f01611e10565b909750955060808d0135945061279f60a08e016126c9565b93506127ad60c08e01611e00565b925067ffffffffffffffff60e08e013511156127c857600080fd5b6127d88e60e08f01358f01611e10565b81935080925050509295989b509295989b509295989b565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60808152600061283d60808301888a612800565b8281036020840152612850818789612800565b9150508360408301526001600160a01b0383166060830152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561289b57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e1057610e106128b8565b80820180821115610e1057610e106128b8565b60005b838110156129135781810151838201526020016128fb565b50506000910152565b60e08152600061293060e083018b8d612800565b8281036020840152612943818a8c612800565b905082810360408401528751808252612963816020840160208c016128f8565b60608401979097526001600160a01b03958616608084015260a083019490945250921660c0909201919091526020601f909201601f1916010195945050505050565b60c0815260006129b960c083018b8d612800565b82810360208401526129cc818a8c612800565b905082810360408401526129e181888a612800565b6060840196909652505060808101929092526001600160a01b031660a0909101529695505050505050565b602081526000612a20602083018486612800565b949350505050565b60008251612a3a8184602087016128f8565b9190910192915050565b60a081526000612a5860a08301898b612800565b8281036020840152612a6b81888a612800565b6001600160a01b039687166040850152606084019590955250509216608090920191909152949350505050565b6000808335601e19843603018112612aaf57600080fd5b83018035915067ffffffffffffffff821115612aca57600080fd5b602001915036819003821315611e5257600080fd5b6020810160058310612b0157634e487b7160e01b600052602160045260246000fd5b91905290565b67ffffffffffffffff81168114610cd757600080fd5b6001600160801b0381168114610cd757600080fd5b60e081526000612b4660e083018587612800565b90508235612b5381612b07565b67ffffffffffffffff808216602085015260208501359150612b7482612b07565b16604083810191909152830135612b8a81612b1d565b6001600160801b03808216606085015260608501359150612baa82612b1d565b808216608085015260808501359150612bc282612b1d565b1660a083810191909152830135612bd881612b1d565b6001600160801b03811660c084015250949350505050565b8135612bfb81612b07565b67ffffffffffffffff8116905081548167ffffffffffffffff1982161783556020840135612c2881612b07565b6fffffffffffffffff00000000000000008160401b16836fffffffffffffffffffffffffffffffff198416171784555050506040820135612c6881612b1d565b81546001600160801b0316608082901b6fffffffffffffffffffffffffffffffff191617825550600181016060830135612ca181612b1d565b81546fffffffffffffffffffffffffffffffff19166001600160801b038216178255506080830135612cd281612b1d565b81546001600160801b0316608082901b6fffffffffffffffffffffffffffffffff1916178255505060a0820135612d0881612b1d565b6002820180546fffffffffffffffffffffffffffffffff19166001600160801b038316179055505050565b600060208284031215612d4557600080fd5b8151612463816126bb565b67ffffffffffffffff818116838216028082169190828114611de357611de36128b8565b6001600160801b03818116838216028082169190828114611de357611de36128b8565b600082612db457634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220f861469381b22ffcb51c7e8aac64c42df609fa41fe64a670d8f91918c4789d3a64736f6c634300081700330000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc
Deployed Bytecode
0x6080604052600436106101c25760003560e01c8063892b5007116100f7578063cd433ada11610095578063edf936f211610064578063edf936f214610594578063f2fde38b146105a7578063f61ed218146105c7578063fd09e3bd146105da57600080fd5b8063cd433ada1461050d578063d3b81f0c14610520578063e30c397814610540578063edb6b3a51461057457600080fd5b8063a3499c73116100d1578063a3499c731461049a578063ab1999ba146104ba578063ba9ddc8d146104da578063c62c2002146104fa57600080fd5b8063892b5007146104125780638da5cb5b146104465780639ded06df1461047a57600080fd5b80634d2384891161016457806379ba50971161013e57806379ba50971461031d5780638291286c1461033257806382ad6f351461036557806386389f021461038557600080fd5b80634d238489146102a25780635c60da1b146102b5578063710bf322146102fd57600080fd5b806317a49f7c116101a057806317a49f7c1461022f5780632e9b74701461024f5780632edd2aa814610262578063365047211461028257600080fd5b80630c93e3bb146101c75780631055eaaf146101dc578063135eaa70146101fc575b600080fd5b6101da6101d5366004611e59565b6105fa565b005b3480156101e857600080fd5b506101da6101f7366004611f5e565b610667565b34801561020857600080fd5b5061021c610217366004611fe1565b610846565b6040519081526020015b60405180910390f35b34801561023b57600080fd5b506101da61024a366004612154565b610980565b6101da61025d366004612272565b610a0c565b34801561026e57600080fd5b506101da61027d366004612365565b610a82565b34801561028e57600080fd5b506101da61029d3660046123bb565b610af1565b6101da6102b036600461240d565b610b46565b3480156102c157600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545b6040516001600160a01b039091168152602001610226565b34801561030957600080fd5b506101da610318366004612446565b610b91565b34801561032957600080fd5b506101da610c60565b34801561033e57600080fd5b507ffaa2f015f2ce5aee225904728de2def86eb8837491efd21f1a04fc20d8e923f661021c565b34801561037157600080fd5b506101da61038036600461246a565b610cda565b34801561039157600080fd5b506103a56103a03660046124ab565b610d35565b6040516102269190600060c08201905067ffffffffffffffff8084511683528060208501511660208401525060408301516001600160801b0380821660408501528060608601511660608501528060808601511660808501528060a08601511660a0850152505092915050565b34801561041e57600080fd5b506102e57f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc81565b34801561045257600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0546102e5565b34801561048657600080fd5b506101da6104953660046124ab565b610e16565b3480156104a657600080fd5b506101da6104b53660046124ed565b610e7c565b3480156104c657600080fd5b506101da6104d5366004612365565b61119c565b3480156104e657600080fd5b506101da6104f5366004612549565b6111eb565b6101da610508366004612272565b611271565b6101da61051b36600461240d565b6112d2565b34801561052c57600080fd5b506101da61053b366004612621565b611314565b34801561054c57600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1546102e5565b34801561058057600080fd5b506101da61058f366004612154565b611405565b6101da6105a23660046126d4565b611466565b3480156105b357600080fd5b506101da6105c2366004612446565b611574565b6101da6105d5366004611e59565b6115c4565b3480156105e657600080fd5b506101da6105f5366004612549565b61161f565b828260405161060a9291906127f0565b6040518091039020886001600160a01b03167f617332c1832058df6ee45fcbdf471251474c9945a8e5d229287a21a5f67ccf0a89898989348860405161065596959493929190612829565b60405180910390a35050505050505050565b336001600160a01b037f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc16146106af57604051623bb10360e91b815260040160405180910390fd5b6001600160a01b0385166106d65760405163e6c4247b60e01b815260040160405180910390fd5b828181146106f757604051636c2b7e2d60e11b815260040160405180910390fd5b60005b8181101561083d57600086868381811061071657610716612873565b905060200201602081019061072b9190612446565b9050600085858481811061074157610741612873565b9050602002013590508060000361076b57604051636c2b7e2d60e11b815260040160405180910390fd5b6001600160a01b03821661079857478111610793576107936001600160a01b038a168261167c565b610833565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156107f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108199190612889565b8111610833576108336001600160a01b0383168a836116c1565b50506001016106fa565b50505050505050565b6000807f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a390260405161087a908d908d906127f0565b908152604051908190036020019020805490915060009067ffffffffffffffff1660048111156108ac576108ac6128a2565b60018301549091506108c7906001600160801b0316876128ce565b82546108e39190600160801b90046001600160801b03166128e5565b925060008160048111156108f9576108f96128a2565b1461097157604080517f657468657265756d00000000000000000000000000000000000000000000000081527f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a390260088201529051908190036028019020610963828a8a868561176a565b61096d90856128e5565b9350505b50509998505050505050505050565b86866040516109909291906127f0565b60405180910390208c6001600160a01b03167fda4ed638a7ffe9e814722efdb9ad6058c152c19c8564ceffe52e11dda1ca32238d8d8d8d8b8b8b8b8b6040516109e19998979695949392919061291c565b60405180910390a36109fe6001600160a01b038416333085611844565b505050505050505050505050565b8585604051610a1c9291906127f0565b60405180910390208b6001600160a01b03167f8c092067e86e85e8cfbaf187202ef580cdfd7ec37fbec89191607de73ca800058c8c8c8c8a8a8a348b604051610a6d999897969594939291906129a5565b60405180910390a35050505050505050505050565b604080516001600160a01b03808616825260208201859052831691810191909152849086907ff0b09bf969e7958967e0968e22596f647dd6efa09f4778e0393967b881f4b09f906060015b60405180910390a3610aea6001600160a01b038416333085611844565b5050505050565b336001600160a01b037f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc1614610b3957604051623bb10360e91b815260040160405180910390fd5b610aea8585858585611895565b604080513481526001600160a01b0383166020820152839185917fb26db521e067acd5c6e345ad92fa1ed06bc7fb2aedd68f35dc7a2e10d636fc9891015b60405180910390a3505050565b33610bba7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610be1576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116610c0857604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6000610c8a7f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b0381163314610cce576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd781611945565b50565b336001600160a01b037f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc1614610d2257604051623bb10360e91b815260040160405180910390fd5b610d30600080858585611895565b505050565b6040805160c081018252600080825260208201819052818301819052606082018190526080820181905260a082015290517f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a390290610d9590859085906127f0565b90815260408051918290036020908101832060c084018352805467ffffffffffffffff808216865268010000000000000000820416928501929092526001600160801b03600160801b92839004811693850193909352600181015480841660608601529190910482166080840152600201541660a082015290505b92915050565b307f000000000000000000000000cb5c784dcf8ff342625dbc53b356ed0cbb0ebb9b6001600160a01b031603610e78576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b33610ea57f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610ecc576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f9190612889565b846001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb19190612889565b14610fe8576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f831461102b576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8490556040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28015611196576000846001600160a01b0316639ded06df60e01b84846040516024016110b0929190612a0c565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161111b9190612a28565b600060405180830381855af49150503d8060008114611156576040519150601f19603f3d011682016040523d82523d6000602084013e61115b565b606091505b5050905080610aea576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b604080516001600160a01b03808616825260208201859052831691810191909152849086907f2275e75614080f9782f72563c2c1688c901c5339c7f9f436d323f9386fed700a90606001610acd565b84846040516111fb9291906127f0565b60405180910390208a6001600160a01b03167fd171a7eb157e548ca493dd0a16016d125963a369ac5ae3c275ec12c96d5277028b8b8b8b8989896040516112489796959493929190612a44565b60405180910390a36112656001600160a01b038416333085611844565b50505050505050505050565b85856040516112819291906127f0565b60405180910390208b6001600160a01b03167f999d431b58761213cf53af96262b67a069cbd963499fd8effd1e21556217b8418c8c8c8c8a8a8a348b604051610a6d999897969594939291906129a5565b604080513481526001600160a01b0383166020820152839185917ffeb6b00343feee0f29a1a4345f8bf93ca1c73ee922248a4237a4e50d6447604e9101610b84565b336001600160a01b037f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc161461135c57604051623bb10360e91b815260040160405180910390fd5b82818114611396576040517fa5f1efe300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156113fd573660008787848181106113b6576113b6612873565b90506020028101906113c89190612a98565b91509150368686858181106113df576113df612873565b905060c0020190506113f28383836119e8565b505050600101611399565b505050505050565b86866040516114159291906127f0565b60405180910390208c6001600160a01b03167f8875f9764f28fa82d3e7ff1b80bd5c8f665e1f42fcd8c2faebc7c400a4ba1bbd8d8d8d8d8b8b8b8b8b6040516109e19998979695949392919061291c565b801561149e576040517fa86b651200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83156115035760006114b78c8c8c8c8c8c8c8a8a610846565b905034811115611501576040517f5b1fe5fc000000000000000000000000000000000000000000000000000000008152600481018290523460248201526044015b60405180910390fd5b505b86866040516115139291906127f0565b60405180910390208c6001600160a01b03167f617332c1832058df6ee45fcbdf471251474c9945a8e5d229287a21a5f67ccf0a8d8d8d8d348a60405161155e96959493929190612829565b60405180910390a3505050505050505050505050565b3361159d7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610cce576040516330cd747160e01b815260040160405180910390fd5b82826040516115d49291906127f0565b6040518091039020886001600160a01b03167f5cf48f121a0fecaa2c4a64b3eaf482c8c308d5387e161535970f3e9e4363eff689898989348860405161065596959493929190612829565b848460405161162f9291906127f0565b60405180910390208a6001600160a01b03167f99206760f0be19dd093729bd35e5924daff5e217bcedc5223ed067b60008cf8a8b8b8b8b8989896040516112489796959493929190612a44565b600080600080600085875af1905080610d30576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038316602482015260448101829052610d309084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611a6e565b60006001866004811115611780576117806128a2565b036117985761179185858585611b45565b905061183b565b60028660048111156117ac576117ac6128a2565b036117bd5761179185858585611c08565b60038660048111156117d1576117d16128a2565b036117e25761179185858585611c7e565b60048660048111156117f6576117f66128a2565b036118075761179185858585611d1a565b856040517f10fcd31f0000000000000000000000000000000000000000000000000000000081526004016114f89190612adf565b95945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526111969085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611706565b6001600160a01b0383166118bc5760405163e6c4247b60e01b815260040160405180910390fd5b604080516001600160a01b03808616825284166020820152908101829052849086907fd5df103822011013c8c940930e5180419111c65abadd6525ca7e740d56b4703f9060600160405180910390a36001600160a01b0382166119315761192c6001600160a01b0384168261167c565b610aea565b610aea6001600160a01b03831684836116c1565b6001600160a01b03811661196c57604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b7f11415423beab67062fb0f3f22cb2a478e3b5a02a845dd62ddb7c12d11098ff1b838383604051611a1b93929190612b32565b60405180910390a1807f2fa150da4c9f4c3a28593398c65313dd42f63d0530ec6db4a2b46e6d837a3902604051611a5590869086906127f0565b908152604051908190036020019020610aea8282612bf0565b600080836001600160a01b031683604051611a899190612a28565b6000604051808303816000865af19150503d8060008114611ac6576040519150601f19603f3d011682016040523d82523d6000602084013e611acb565b606091505b50915091506000828015611af7575081511580611af7575081806020019051810190611af79190612d33565b9050801580611b0e57506001600160a01b0385163b155b15610aea576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000620f4240620dbba082611b5a8888611d45565b6001860154909150600090611b7f90600160801b90046001600160801b0316846128ce565b600187015488546001600160801b0390911690611bb39068010000000000000000900467ffffffffffffffff166010612d50565b67ffffffffffffffff16611bc79190612d74565b6001600160801b0316611bda91906128e5565b9050611be78460106128ce565b611bf183836128ce565b611bfb9190612d97565b9998505050505050505050565b600060bc620f42408282611c1c8989611d45565b611c2691906128e5565b8654600187015491925083916801000000000000000090910467ffffffffffffffff1690611c5e9084906001600160801b03166128ce565b611c6891906128ce565b611c729190612d97565b98975050505050505050565b6000612710601082611c9082806128ce565b90506064600088611ca461018460446128e5565b611cae91906128e5565b905060006002611cbe83876128ce565b611cc89190612d97565b905085611cd584826128e5565b611cdf86846128e5565b60018b0154611cf791906001600160801b03166128ce565b611d0191906128ce565b611d0b9190612d97565b9b9a5050505050505050505050565b60006109c4633b9aca008282611d308989611d45565b611d3a91906128e5565b611c269060406128e5565b6000611d53604460106128ce565b9050611d6261018460086128ce565b611d6c90826128e5565b90508160005b81811015611de357848482818110611d8c57611d8c612873565b909101357fff00000000000000000000000000000000000000000000000000000000000000166000039050611dcd57611dc66004846128e5565b9250611ddb565b611dd86010846128e5565b92505b600101611d72565b505092915050565b6001600160a01b0381168114610cd757600080fd5b8035611e0b81611deb565b919050565b60008083601f840112611e2257600080fd5b50813567ffffffffffffffff811115611e3a57600080fd5b602083019150836020828501011115611e5257600080fd5b9250929050565b60008060008060008060008060a0898b031215611e7557600080fd5b8835611e8081611deb565b9750602089013567ffffffffffffffff80821115611e9d57600080fd5b611ea98c838d01611e10565b909950975060408b0135915080821115611ec257600080fd5b611ece8c838d01611e10565b909750955060608b0135915080821115611ee757600080fd5b50611ef48b828c01611e10565b9094509250506080890135611f0881611deb565b809150509295985092959890939650565b60008083601f840112611f2b57600080fd5b50813567ffffffffffffffff811115611f4357600080fd5b6020830191508360208260051b8501011115611e5257600080fd5b600080600080600060608688031215611f7657600080fd5b8535611f8181611deb565b9450602086013567ffffffffffffffff80821115611f9e57600080fd5b611faa89838a01611f19565b90965094506040880135915080821115611fc357600080fd5b50611fd088828901611f19565b969995985093965092949392505050565b600080600080600080600080600060a08a8c031215611fff57600080fd5b893567ffffffffffffffff8082111561201757600080fd5b6120238d838e01611e10565b909b50995060208c013591508082111561203c57600080fd5b6120488d838e01611e10565b909950975060408c013591508082111561206157600080fd5b61206d8d838e01611e10565b909750955060608c0135945060808c013591508082111561208d57600080fd5b5061209a8c828d01611e10565b915080935050809150509295985092959850929598565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126120d857600080fd5b813567ffffffffffffffff808211156120f3576120f36120b1565b604051601f8301601f19908116603f0116810190828211818310171561211b5761211b6120b1565b8160405283815286602085880101111561213457600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806000806000806000806000806101208d8f03121561217757600080fd5b6121808d611e00565b9b5067ffffffffffffffff60208e0135111561219b57600080fd5b6121ab8e60208f01358f01611e10565b909b50995067ffffffffffffffff60408e013511156121c957600080fd5b6121d98e60408f01358f01611e10565b909950975067ffffffffffffffff60608e013511156121f757600080fd5b6122078e60608f01358f01611e10565b909750955067ffffffffffffffff60808e0135111561222557600080fd5b6122358e60808f01358f016120c7565b945060a08d0135935061224a60c08e01611e00565b925060e08d013591506122606101008e01611e00565b90509295989b509295989b509295989b565b600080600080600080600080600080600060e08c8e03121561229357600080fd5b61229c8c611e00565b9a5067ffffffffffffffff8060208e013511156122b857600080fd5b6122c88e60208f01358f01611e10565b909b50995060408d01358110156122de57600080fd5b6122ee8e60408f01358f01611e10565b909950975060608d013581101561230457600080fd5b6123148e60608f01358f01611e10565b909750955060808d013581101561232a57600080fd5b5061233b8d60808e01358e01611e10565b909450925060a08c0135915061235360c08d01611e00565b90509295989b509295989b9093969950565b600080600080600060a0868803121561237d57600080fd5b8535945060208601359350604086013561239681611deb565b92506060860135915060808601356123ad81611deb565b809150509295509295909350565b600080600080600060a086880312156123d357600080fd5b853594506020860135935060408601356123ec81611deb565b925060608601356123fc81611deb565b949793965091946080013592915050565b60008060006060848603121561242257600080fd5b8335925060208401359150604084013561243b81611deb565b809150509250925092565b60006020828403121561245857600080fd5b813561246381611deb565b9392505050565b60008060006060848603121561247f57600080fd5b833561248a81611deb565b9250602084013561249a81611deb565b929592945050506040919091013590565b600080602083850312156124be57600080fd5b823567ffffffffffffffff8111156124d557600080fd5b6124e185828601611e10565b90969095509350505050565b6000806000806060858703121561250357600080fd5b843561250e81611deb565b935060208501359250604085013567ffffffffffffffff81111561253157600080fd5b61253d87828801611e10565b95989497509550505050565b60008060008060008060008060008060e08b8d03121561256857600080fd5b8a3561257381611deb565b995060208b013567ffffffffffffffff8082111561259057600080fd5b61259c8e838f01611e10565b909b50995060408d01359150808211156125b557600080fd5b6125c18e838f01611e10565b909950975060608d01359150808211156125da57600080fd5b506125e78d828e01611e10565b90965094505060808b01356125fb81611deb565b925060a08b0135915061261060c08c01611e00565b90509295989b9194979a5092959850565b6000806000806040858703121561263757600080fd5b843567ffffffffffffffff8082111561264f57600080fd5b61265b88838901611f19565b9096509450602087013591508082111561267457600080fd5b818701915087601f83011261268857600080fd5b81358181111561269757600080fd5b88602060c0830285010111156126ac57600080fd5b95989497505060200194505050565b8015158114610cd757600080fd5b8035611e0b816126bb565b6000806000806000806000806000806000806101008d8f0312156126f757600080fd5b6127008d611e00565b9b5067ffffffffffffffff60208e0135111561271b57600080fd5b61272b8e60208f01358f01611e10565b909b50995067ffffffffffffffff60408e0135111561274957600080fd5b6127598e60408f01358f01611e10565b909950975067ffffffffffffffff60608e0135111561277757600080fd5b6127878e60608f01358f01611e10565b909750955060808d0135945061279f60a08e016126c9565b93506127ad60c08e01611e00565b925067ffffffffffffffff60e08e013511156127c857600080fd5b6127d88e60e08f01358f01611e10565b81935080925050509295989b509295989b509295989b565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60808152600061283d60808301888a612800565b8281036020840152612850818789612800565b9150508360408301526001600160a01b0383166060830152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561289b57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e1057610e106128b8565b80820180821115610e1057610e106128b8565b60005b838110156129135781810151838201526020016128fb565b50506000910152565b60e08152600061293060e083018b8d612800565b8281036020840152612943818a8c612800565b905082810360408401528751808252612963816020840160208c016128f8565b60608401979097526001600160a01b03958616608084015260a083019490945250921660c0909201919091526020601f909201601f1916010195945050505050565b60c0815260006129b960c083018b8d612800565b82810360208401526129cc818a8c612800565b905082810360408401526129e181888a612800565b6060840196909652505060808101929092526001600160a01b031660a0909101529695505050505050565b602081526000612a20602083018486612800565b949350505050565b60008251612a3a8184602087016128f8565b9190910192915050565b60a081526000612a5860a08301898b612800565b8281036020840152612a6b81888a612800565b6001600160a01b039687166040850152606084019590955250509216608090920191909152949350505050565b6000808335601e19843603018112612aaf57600080fd5b83018035915067ffffffffffffffff821115612aca57600080fd5b602001915036819003821315611e5257600080fd5b6020810160058310612b0157634e487b7160e01b600052602160045260246000fd5b91905290565b67ffffffffffffffff81168114610cd757600080fd5b6001600160801b0381168114610cd757600080fd5b60e081526000612b4660e083018587612800565b90508235612b5381612b07565b67ffffffffffffffff808216602085015260208501359150612b7482612b07565b16604083810191909152830135612b8a81612b1d565b6001600160801b03808216606085015260608501359150612baa82612b1d565b808216608085015260808501359150612bc282612b1d565b1660a083810191909152830135612bd881612b1d565b6001600160801b03811660c084015250949350505050565b8135612bfb81612b07565b67ffffffffffffffff8116905081548167ffffffffffffffff1982161783556020840135612c2881612b07565b6fffffffffffffffff00000000000000008160401b16836fffffffffffffffffffffffffffffffff198416171784555050506040820135612c6881612b1d565b81546001600160801b0316608082901b6fffffffffffffffffffffffffffffffff191617825550600181016060830135612ca181612b1d565b81546fffffffffffffffffffffffffffffffff19166001600160801b038216178255506080830135612cd281612b1d565b81546001600160801b0316608082901b6fffffffffffffffffffffffffffffffff1916178255505060a0820135612d0881612b1d565b6002820180546fffffffffffffffffffffffffffffffff19166001600160801b038316179055505050565b600060208284031215612d4557600080fd5b8151612463816126bb565b67ffffffffffffffff818116838216028082169190828114611de357611de36128b8565b6001600160801b03818116838216028082169190828114611de357611de36128b8565b600082612db457634e487b7160e01b600052601260045260246000fd5b50049056fea2646970667358221220f861469381b22ffcb51c7e8aac64c42df609fa41fe64a670d8f91918c4789d3a64736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc
-----Decoded View---------------
Arg [0] : gasCollector_ (address): 0x7DdB2d76b80B0AA19bDEa48EB1301182F4CeefbC
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
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.