Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';
/**
* @title AxelarExecutable
* @dev Abstract contract to be inherited by contracts that need to execute cross-chain commands via Axelar's Gateway.
* It implements the IAxelarExecutable interface.
*/
abstract contract AxelarExecutable is IAxelarExecutable {
/// @dev Reference to the Axelar Gateway contract.
address internal immutable gatewayAddress;
/**
* @dev Contract constructor that sets the Axelar Gateway address.
* Reverts if the provided address is the zero address.
* @param gateway_ The address of the Axelar Gateway contract.
*/
constructor(address gateway_) {
if (gateway_ == address(0)) revert InvalidAddress();
gatewayAddress = gateway_;
}
/**
* @notice Executes the cross-chain command after validating it with the Axelar Gateway.
* @dev This function ensures the call is approved by Axelar Gateway before execution.
* It uses a hash of the payload for validation and internally calls _execute for the actual command execution.
* Reverts if the validation fails.
* @param commandId The unique identifier of the cross-chain message being executed.
* @param sourceChain The name of the source chain from which the message originated.
* @param sourceAddress The address on the source chain that sent the message.
* @param payload The payload of the message payload.
*/
function execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external virtual {
bytes32 payloadHash = keccak256(payload);
if (!gateway().validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
revert NotApprovedByGateway();
_execute(commandId, sourceChain, sourceAddress, payload);
}
/**
* @dev Internal virtual function to be overridden by child contracts to execute the command.
* It allows child contracts to define their custom command execution logic.
* @param commandId The identifier of the command to execute.
* @param sourceChain The name of the source chain from which the command originated.
* @param sourceAddress The address on the source chain that sent the command.
* @param payload The payload of the command to be executed.
*/
function _execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) internal virtual;
/**
* @notice Returns the address of the AxelarGateway contract.
* @return The Axelar Gateway instance.
*/
function gateway() public view returns (IAxelarGateway) {
return IAxelarGateway(gatewayAddress);
}
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarExecutable.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IAxelarGateway } from './IAxelarGateway.sol';
/**
* @title IAxelarExecutable
* @dev Interface for a contract that is executable by Axelar Gateway's cross-chain message passing.
* It defines a standard interface to execute commands sent from another chain.
*/
interface IAxelarExecutable {
/**
* @dev Thrown when a function is called with an invalid address.
*/
error InvalidAddress();
/**
* @dev Thrown when the call is not approved by the Axelar Gateway.
*/
error NotApprovedByGateway();
/**
* @notice Returns the address of the AxelarGateway contract.
* @return The Axelar Gateway contract associated with this executable contract.
*/
function gateway() external view returns (IAxelarGateway);
/**
* @notice Executes the specified command sent from another chain.
* @dev This function is called by the Axelar Gateway to carry out cross-chain commands.
* Reverts if the call is not approved by the gateway or other checks fail.
* @param commandId The identifier of the command to execute.
* @param sourceChain The name of the source chain from where the command originated.
* @param sourceAddress The address on the source chain that sent the command.
* @param payload The payload of the command to be executed. This typically includes the function selector and encoded arguments.
*/
function execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external;
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol": {
"content": "// 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);
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IAxelarGateway
* @dev Interface for the Axelar Gateway that supports general message passing and contract call execution.
*/
interface IAxelarGateway {
/**
* @notice Emitted when a contract call is made through the gateway.
* @dev Logs the attempt to call a contract on another chain.
* @param sender The address of the sender who initiated the contract call.
* @param destinationChain The name of the destination chain.
* @param destinationContractAddress The address of the contract on the destination chain.
* @param payloadHash The keccak256 hash of the sent payload data.
* @param payload The payload data used for the contract call.
*/
event ContractCall(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload
);
/**
* @notice Sends a contract call to another chain.
* @dev Initiates a cross-chain contract call through the gateway to the specified destination chain and contract.
* @param destinationChain The name of the destination chain.
* @param contractAddress The address of the contract on the destination chain.
* @param payload The payload data to be used in the contract call.
*/
function callContract(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload
) external;
/**
* @notice Checks if a contract call is approved.
* @dev Determines whether a given contract call, identified by the commandId and payloadHash, is approved.
* @param commandId The identifier of the command to check.
* @param sourceChain The name of the source chain.
* @param sourceAddress The address of the sender on the source chain.
* @param contractAddress The address of the contract where the call will be executed.
* @param payloadHash The keccak256 hash of the payload data.
* @return True if the contract call is approved, false otherwise.
*/
function isContractCallApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash
) external view returns (bool);
/**
* @notice Validates and approves a contract call.
* @dev Validates the given contract call information and marks it as approved if valid.
* @param commandId The identifier of the command to validate.
* @param sourceChain The name of the source chain.
* @param sourceAddress The address of the sender on the source chain.
* @param payloadHash The keccak256 hash of the payload data.
* @return True if the contract call is validated and approved, false otherwise.
*/
function validateContractCall(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash
) external returns (bool);
/**
* @notice Checks if a command has been executed.
* @dev Determines whether a command, identified by the commandId, has been executed.
* @param commandId The identifier of the command to check.
* @return True if the command has been executed, false otherwise.
*/
function isCommandExecuted(bytes32 commandId) external view returns (bool);
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IContractIdentifier.sol": {
"content": "// 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);
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol": {
"content": "// 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);
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IImplementation.sol": {
"content": "// 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;
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IInterchainGasEstimation.sol": {
"content": "// 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);
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IOwnable.sol": {
"content": "// 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;
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol": {
"content": "// 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;
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressString.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library StringToAddress {
error InvalidAddressString();
function toAddress(string memory addressString) internal pure returns (address) {
bytes memory stringBytes = bytes(addressString);
uint160 addressNumber = 0;
uint8 stringByte;
if (stringBytes.length != 42 || stringBytes[0] != '0' || stringBytes[1] != 'x') revert InvalidAddressString();
for (uint256 i = 2; i < 42; ++i) {
stringByte = uint8(stringBytes[i]);
if ((stringByte >= 97) && (stringByte <= 102)) stringByte -= 87;
else if ((stringByte >= 65) && (stringByte <= 70)) stringByte -= 55;
else if ((stringByte >= 48) && (stringByte <= 57)) stringByte -= 48;
else revert InvalidAddressString();
addressNumber |= uint160(uint256(stringByte) << ((41 - i) << 2));
}
return address(addressNumber);
}
}
library AddressToString {
function toString(address address_) internal pure returns (string memory) {
bytes memory addressBytes = abi.encodePacked(address_);
bytes memory characters = '0123456789abcdef';
bytes memory stringBytes = new bytes(42);
stringBytes[0] = '0';
stringBytes[1] = 'x';
for (uint256 i; i < 20; ++i) {
stringBytes[2 + i * 2] = characters[uint8(addressBytes[i] >> 4)];
stringBytes[3 + i * 2] = characters[uint8(addressBytes[i] & 0x0f)];
}
return string(stringBytes);
}
}
"
},
"@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/types/GasEstimationTypes.sol": {
"content": "// 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;
}
"
},
"src/__tests__/contracts/Factory.sol": {
"content": "// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;
import {AxelarExecutable} from "@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol";
import {IAxelarGasService} from "@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol";
import {IERC20} from "@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol";
import {StringToAddress, AddressToString} from "@updated-axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressString.sol";
import {Ownable} from "./Ownable.sol";
struct CallResult {
bool success;
bytes result;
}
struct AgoricResponse {
// false if this is a smart wallet creation, true if it's a contract call
bool isContractCallResult;
CallResult[] data;
}
struct ContractCalls {
address target;
bytes data;
}
struct CallMessage {
string id;
ContractCalls[] calls;
}
error ContractCallFailed(string messageId, uint256 step);
contract Wallet is AxelarExecutable, Ownable {
IAxelarGasService public gasService;
event CallStatus(
string indexed id,
uint256 indexed callIndex,
address indexed target,
bytes4 methodSelector,
bool success
);
event MulticallStatus(string indexed id, bool success, uint256 totalCalls);
event Received(address indexed sender, uint256 amount);
constructor(
address gateway_,
address gasReceiver_,
string memory owner_
) payable AxelarExecutable(gateway_) Ownable(owner_) {
gasService = IAxelarGasService(gasReceiver_);
}
function _multicall(bytes calldata payload) internal {
CallMessage memory callMessage = abi.decode(payload, (CallMessage));
ContractCalls[] memory calls = callMessage.calls;
uint256 len = calls.length;
for (uint256 i = 0; i < len; ) {
(bool success, ) = calls[i].target.call(calls[i].data);
if (!success) {
revert ContractCallFailed(callMessage.id, i);
}
emit CallStatus(
callMessage.id,
i,
calls[i].target,
bytes4(calls[i].data),
success
);
unchecked {
++i;
}
}
emit MulticallStatus(callMessage.id, true, calls.length);
}
function _execute(
bytes32 /*commandId*/,
string calldata /*sourceChain*/,
string calldata sourceAddress,
bytes calldata payload
) internal override onlyOwner(sourceAddress) {
_multicall(payload);
}
receive() external payable {
emit Received(msg.sender, msg.value);
}
fallback() external payable {
emit Received(msg.sender, msg.value);
}
}
contract Factory is AxelarExecutable {
using StringToAddress for string;
using AddressToString for address;
address _gateway;
IAxelarGasService public immutable gasService;
event SmartWalletCreated(
address indexed wallet,
string owner,
string sourceChain,
string sourceAddress
);
event CrossChainCallSent(
string destinationChain,
string destinationAddress,
bytes payload
);
event Received(address indexed sender, uint256 amount);
constructor(
address gateway_,
address gasReceiver_
) payable AxelarExecutable(gateway_) {
gasService = IAxelarGasService(gasReceiver_);
_gateway = gateway_;
}
function _createSmartWallet(
string memory owner
) internal returns (address) {
address newWallet = address(
new Wallet(_gateway, address(gasService), owner)
);
return newWallet;
}
function _execute(
bytes32 /*commandId*/,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) internal override {
uint256 gasAmount = abi.decode(payload, (uint256));
address smartWalletAddress = _createSmartWallet(sourceAddress);
emit SmartWalletCreated(
smartWalletAddress,
sourceAddress,
sourceChain,
sourceAddress
);
CallResult[] memory results = new CallResult[](1);
results[0] = CallResult(true, abi.encode(smartWalletAddress));
bytes memory msgPayload = abi.encodePacked(
bytes4(0x00000000),
abi.encode(AgoricResponse(false, results))
);
_send(sourceChain, sourceAddress, msgPayload, gasAmount);
}
function _send(
string calldata destinationChain,
string calldata destinationAddress,
bytes memory payload,
uint256 gasAmount
) internal {
gasService.payNativeGasForContractCall{value: gasAmount}(
address(this),
destinationChain,
destinationAddress,
payload,
address(this)
);
gateway().callContract(destinationChain, destinationAddress, payload);
emit CrossChainCallSent(destinationChain, destinationAddress, payload);
}
receive() external payable {
emit Received(msg.sender, msg.value);
}
fallback() external payable {
emit Received(msg.sender, msg.value);
}
}
"
},
"src/__tests__/contracts/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
/**
* @dev 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 initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable {
string private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(string account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(string owner);
event OwnershipTransferred(
string indexed previousOwner,
string indexed newOwner
);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(string memory initialOwner) {
// if (initialOwner == address(0)) {
// revert OwnableInvalidOwner(address(0));
// }
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner(string calldata incomingAddress) {
_checkOwner(incomingAddress);
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (string memory) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner(
string calldata incomingAddress
) internal view virtual {
if (keccak256(bytes(owner())) != keccak256(bytes(incomingAddress))) {
revert OwnableUnauthorizedAccount(incomingAddress);
}
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(string memory newOwner) internal virtual {
string memory oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000,
"details": {
"yul": true
}
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}
}}
Submitted on: 2025-10-10 10:57:32
Comments
Log in to comment.
No comments yet.