Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(evm)!: update evm examples with AxelarExecutable and AxelarExecutableWithToken #198

Merged
merged 11 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { AxelarExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol';
import { AxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutable.sol';
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';
import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
Expand All @@ -10,21 +10,21 @@ import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interf
* @title CallContractGasEstimation
* @notice Send a message from chain A to chain B and stores gmp message
*/
contract CallContractGasEstimation is AxelarExecutable {
contract CallContractGasEstimation is AxelarGMPExecutable {
string public message;
string public sourceChain;
string public sourceAddress;
IAxelarGasService public immutable gasService;
uint256 public constant GAS_LIMIT = 200000;

event Executed(string _from, string _message);
event Executed(bytes32 commandId, string _from, string _message);

/**
*
* @param _gateway address of axl gateway on deployed chain
* @param _gasReceiver address of axl gas service on deployed chain
*/
constructor(address _gateway, address _gasReceiver) AxelarExecutable(_gateway) {
constructor(address _gateway, address _gasReceiver) AxelarGMPExecutable(_gateway) {
gasService = IAxelarGasService(_gasReceiver);
}

Expand Down Expand Up @@ -76,7 +76,7 @@ contract CallContractGasEstimation is AxelarExecutable {
msg.sender,
new bytes(0)
);
gateway.callContract(destinationChain, destinationAddress, payload);
gateway().callContract(destinationChain, destinationAddress, payload);
}

/**
Expand All @@ -86,11 +86,11 @@ contract CallContractGasEstimation is AxelarExecutable {
* @param _sourceAddress address on src chain where tx is originating from
* @param _payload encoded gmp message sent from src chain
*/
function _execute(string calldata _sourceChain, string calldata _sourceAddress, bytes calldata _payload) internal override {
function _execute(bytes32 commandId,string calldata _sourceChain, string calldata _sourceAddress, bytes calldata _payload) internal override {
(message) = abi.decode(_payload, (string));
sourceChain = _sourceChain;
sourceAddress = _sourceAddress;

emit Executed(sourceAddress, message);
emit Executed(commandId, sourceAddress, message);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
pragma solidity ^0.8.0;

import { AxelarExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol';
import { AxelarExpressExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/AxelarExpressExecutable.sol';
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
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 { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol';

contract CallContractWithTokenExpress is AxelarExpressExecutable {
IAxelarGasService public immutable gasService;

event Executed(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload);
event ExecutedWithToken(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload, string tokenSymbol, uint256 amount);

constructor(address gateway_, address gasReceiver_) AxelarExpressExecutable(gateway_) {
gasService = IAxelarGasService(gasReceiver_);
}
Expand All @@ -22,9 +23,9 @@ contract CallContractWithTokenExpress is AxelarExpressExecutable {
string memory symbol,
uint256 amount
) external payable {
address tokenAddress = gateway.tokenAddresses(symbol);
address tokenAddress = gatewayWithToken().tokenAddresses(symbol);
IERC20(tokenAddress).transferFrom(msg.sender, address(this), amount);
IERC20(tokenAddress).approve(address(gateway), amount);
IERC20(tokenAddress).approve(address(gatewayWithToken()), amount);
bytes memory payload = abi.encode(destinationAddresses);
if (msg.value > 0) {
gasService.payNativeGasForContractCallWithToken{ value: msg.value }(
Expand All @@ -37,23 +38,35 @@ contract CallContractWithTokenExpress is AxelarExpressExecutable {
msg.sender
);
}
gateway.callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount);
gatewayWithToken().callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount);
}

function _execute(
ahramy marked this conversation as resolved.
Show resolved Hide resolved
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) internal override {
emit Executed(commandId,sourceChain, sourceAddress, payload);
}

function _executeWithToken(
string calldata,
string calldata,
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) internal override {
address[] memory recipients = abi.decode(payload, (address[]));
address tokenAddress = gateway.tokenAddresses(tokenSymbol);
address tokenAddress = gatewayWithToken().tokenAddresses(tokenSymbol);

uint256 sentAmount = amount / recipients.length;
for (uint256 i = 0; i < recipients.length; i++) {
IERC20(tokenAddress).transfer(recipients[i], sentAmount);
}

emit ExecutedWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount);
}

function contractId() external pure returns (bytes32) {
Expand Down
38 changes: 22 additions & 16 deletions examples/evm/call-contract-with-token/CallContractWithToken.sol
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { AxelarExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol';
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { AxelarGMPExecutableWithToken } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutableWithToken.sol';
import { IAxelarGMPGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGMPGateway.sol';
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';


/**
* @title Call Contract With Token
* @title Call Contract With Token
* @notice Send a token along with an Axelar GMP message between two blockchains
*/
contract CallContractWithToken is AxelarExecutable {
contract CallContractWithToken is AxelarGMPExecutableWithToken {
IAxelarGasService public immutable gasService;

event Executed();
event Executed(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload);
ahramy marked this conversation as resolved.
Show resolved Hide resolved
event ExecutedWithToken(bytes32 commandId, string sourceChain, string sourceAddress, bytes payload, string tokenSymbol, uint256 amount);

/**
*
*
* @param _gateway address of axl gateway on deployed chain
* @param _gasReceiver address of axl gas service on deployed chain
*/
constructor(address _gateway, address _gasReceiver) AxelarExecutable(_gateway) {
constructor(address _gateway, address _gasReceiver) AxelarGMPExecutableWithToken(_gateway) {
gasService = IAxelarGasService(_gasReceiver);
}

Expand All @@ -30,7 +30,7 @@ contract CallContractWithToken is AxelarExecutable {
* @dev destinationAddresses will be passed in as gmp message in this tx
* @param destinationChain name of the dest chain (ex. "Fantom")
* @param destinationAddress address on dest chain this tx is going to
* @param destinationAddresses recipient addresses receiving sent funds
* @param destinationAddresses recipient addresses receiving sent funds
* @param symbol symbol of token being sent
* @param amount amount of tokens being sent
*/
Expand All @@ -43,9 +43,9 @@ contract CallContractWithToken is AxelarExecutable {
) external payable {
require(msg.value > 0, 'Gas payment is required');

address tokenAddress = gateway.tokenAddresses(symbol);
address tokenAddress = gatewayWithToken().tokenAddresses(symbol);
IERC20(tokenAddress).transferFrom(msg.sender, address(this), amount);
IERC20(tokenAddress).approve(address(gateway), amount);
IERC20(tokenAddress).approve(address(gatewayWithToken()), amount);
bytes memory payload = abi.encode(destinationAddresses);
gasService.payNativeGasForContractCallWithToken{ value: msg.value }(
address(this),
Expand All @@ -56,7 +56,11 @@ contract CallContractWithToken is AxelarExecutable {
amount,
msg.sender
);
gateway.callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount);
gatewayWithToken().callContractWithToken(destinationChain, destinationAddress, payload, symbol, amount);
}

function _execute(bytes32 commandId,string calldata sourceChain, string calldata sourceAddress, bytes calldata payload) internal override {
emit Executed(commandId,sourceChain, sourceAddress, payload);
}

/**
Expand All @@ -67,20 +71,22 @@ contract CallContractWithToken is AxelarExecutable {
* @param amount amount of tokens sent from src chain
*/
function _executeWithToken(
string calldata,
string calldata,
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) internal override {
address[] memory recipients = abi.decode(payload, (address[]));
address tokenAddress = gateway.tokenAddresses(tokenSymbol);
address tokenAddress = gatewayWithToken().tokenAddresses(tokenSymbol);

uint256 sentAmount = amount / recipients.length;
for (uint256 i = 0; i < recipients.length; i++) {
IERC20(tokenAddress).transfer(recipients[i], sentAmount);
}

emit Executed();
emit ExecutedWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount);
}

}
14 changes: 7 additions & 7 deletions examples/evm/call-contract/CallContract.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { AxelarExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol';
import { AxelarGMPExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarGMPExecutable.sol';
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';
import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
Expand All @@ -10,20 +10,20 @@ import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interf
* @title CallContract
* @notice Send a message from chain A to chain B and stores gmp message
*/
contract CallContract is AxelarExecutable {
contract CallContract is AxelarGMPExecutable {
string public message;
string public sourceChain;
string public sourceAddress;
IAxelarGasService public immutable gasService;

event Executed(string _from, string _message);
event Executed(bytes32 commandId, string _from, string _message);

/**
*
* @param _gateway address of axl gateway on deployed chain
* @param _gasReceiver address of axl gas service on deployed chain
*/
constructor(address _gateway, address _gasReceiver) AxelarExecutable(_gateway) {
constructor(address _gateway, address _gasReceiver) AxelarGMPExecutable(_gateway) {
gasService = IAxelarGasService(_gasReceiver);
}

Expand All @@ -49,7 +49,7 @@ contract CallContract is AxelarExecutable {
payload,
msg.sender
);
gateway.callContract(destinationChain, destinationAddress, payload);
gateway().callContract(destinationChain, destinationAddress, payload);
}

/**
Expand All @@ -59,11 +59,11 @@ contract CallContract is AxelarExecutable {
* @param _sourceAddress address on src chain where tx is originating from
* @param _payload encoded gmp message sent from src chain
*/
function _execute(string calldata _sourceChain, string calldata _sourceAddress, bytes calldata _payload) internal override {
function _execute(bytes32 commandId, string calldata _sourceChain, string calldata _sourceAddress, bytes calldata _payload) internal override {
(message) = abi.decode(_payload, (string));
sourceChain = _sourceChain;
sourceAddress = _sourceAddress;

emit Executed(sourceAddress, message);
emit Executed(commandId, sourceAddress, message);
}
}
2 changes: 1 addition & 1 deletion hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require("@nomicfoundation/hardhat-chai-matchers")
*/
module.exports = {
solidity: {
version: '0.8.9',
version: '0.8.19',
ahramy marked this conversation as resolved.
Show resolved Hide resolved
settings: {
evmVersion: process.env.EVM_VERSION || 'london',
optimizer: {
Expand Down
Loading
Loading