Overview
GLMR Balance
0 GLMR
GLMR Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
9328593 | 1 hr ago | 3.14529098 GLMR | ||||
9324567 | 7 hrs ago | 2.06283376 GLMR | ||||
9324213 | 8 hrs ago | 0.05761545 GLMR | ||||
9323835 | 9 hrs ago | 0.09425075 GLMR | ||||
9323611 | 9 hrs ago | 0.01231876 GLMR | ||||
9323335 | 9 hrs ago | 0.09458581 GLMR | ||||
9321262 | 13 hrs ago | 0.0437861 GLMR | ||||
9320352 | 14 hrs ago | 0.00895797 GLMR | ||||
9319861 | 15 hrs ago | 0.1376016 GLMR | ||||
9319350 | 16 hrs ago | 2.08144062 GLMR | ||||
9318986 | 17 hrs ago | 0.21066558 GLMR | ||||
9318894 | 17 hrs ago | 1.75893854 GLMR | ||||
9318206 | 18 hrs ago | 0.01141942 GLMR | ||||
9317823 | 19 hrs ago | 0.07538315 GLMR | ||||
9317213 | 20 hrs ago | 0.13878546 GLMR | ||||
9317027 | 20 hrs ago | 0.19649766 GLMR | ||||
9316266 | 21 hrs ago | 3.1007228 GLMR | ||||
9316266 | 21 hrs ago | 3.1007228 GLMR | ||||
9316250 | 21 hrs ago | 2.88897698 GLMR | ||||
9316250 | 21 hrs ago | 2.8267244 GLMR | ||||
9316237 | 21 hrs ago | 2.24615946 GLMR | ||||
9316112 | 22 hrs ago | 2.17776183 GLMR | ||||
9316102 | 22 hrs ago | 2.84192868 GLMR | ||||
9316056 | 22 hrs ago | 2.17944417 GLMR | ||||
9315985 | 22 hrs ago | 2.17011606 GLMR |
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 Source Code Verified (Exact Match)
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
[{"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
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.