Skip to content

Commit

Permalink
refactor(express)!: split express executable with token functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
milapsheth committed Oct 29, 2024
1 parent 7c97827 commit ef7044b
Show file tree
Hide file tree
Showing 14 changed files with 423 additions and 246 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ import { AxelarExecutable } from '../executable/AxelarExecutable.sol';
import { AxelarExecutableWithToken } from '../executable/AxelarExecutableWithToken.sol';
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';
import { IAxelarExecutableWithToken } from '../interfaces/IAxelarExecutableWithToken.sol';
import { IAxelarExpressExecutableWithToken } from '../interfaces/IAxelarExpressExecutableWithToken.sol';
import { ExpressExecutorTracker } from './ExpressExecutorTracker.sol';
import { SafeTokenTransferFrom, SafeTokenTransfer } from '../libs/SafeTransfer.sol';
import { IERC20 } from '../interfaces/IERC20.sol';

abstract contract AxelarExpressExecutable is ExpressExecutorTracker, AxelarExecutableWithToken {
abstract contract AxelarExpressExecutableWithToken is
IAxelarExpressExecutableWithToken,
ExpressExecutorTracker,
AxelarExecutableWithToken
{
using SafeTokenTransfer for IERC20;
using SafeTokenTransferFrom for IERC20;

Expand Down Expand Up @@ -141,4 +146,49 @@ abstract contract AxelarExpressExecutable is ExpressExecutorTracker, AxelarExecu

_executeWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount);
}

/**
* @notice Returns the express executor for a given command.
* @param commandId The commandId for the contractCall.
* @param sourceChain The source chain.
* @param sourceAddress The source address.
* @param payloadHash The hash of the payload.
* @return expressExecutor The address of the express executor.
*/
function getExpressExecutor(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash
) external view returns (address expressExecutor) {
expressExecutor = _getExpressExecutor(commandId, sourceChain, sourceAddress, payloadHash);
}

/**
* @notice Returns the express executor with token for a given command.
* @param commandId The commandId for the contractCallWithToken.
* @param sourceChain The source chain.
* @param sourceAddress The source address.
* @param payloadHash The hash of the payload.
* @param symbol The token symbol.
* @param amount The amount of tokens.
* @return expressExecutor The address of the express executor.
*/
function getExpressExecutorWithToken(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external view returns (address expressExecutor) {
expressExecutor = _getExpressExecutorWithToken(
commandId,
sourceChain,
sourceAddress,
payloadHash,
symbol,
amount
);
}
}
137 changes: 14 additions & 123 deletions contracts/express/AxelarValuedExpressExecutable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
pragma solidity ^0.8.0;

import { AxelarExecutable } from '../executable/AxelarExecutable.sol';
import { AxelarExecutableWithToken } from '../executable/AxelarExecutableWithToken.sol';
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';
import { IAxelarExecutableWithToken } from '../interfaces/IAxelarExecutableWithToken.sol';
import { IERC20 } from '../interfaces/IERC20.sol';
import { IAxelarValuedExpressExecutable } from '../interfaces/IAxelarValuedExpressExecutable.sol';
import { SafeTokenTransferFrom, SafeTokenTransfer } from '../libs/SafeTransfer.sol';
Expand All @@ -14,14 +12,14 @@ import { ExpressExecutorTracker } from './ExpressExecutorTracker.sol';

abstract contract AxelarValuedExpressExecutable is
ExpressExecutorTracker,
AxelarExecutableWithToken,
AxelarExecutable,
IAxelarValuedExpressExecutable
{
using SafeTokenTransfer for IERC20;
using SafeTokenTransferFrom for IERC20;
using SafeNativeTransfer for address payable;

constructor(address gateway_) AxelarExecutableWithToken(gateway_) {}
constructor(address gateway_) AxelarExecutable(gateway_) {}

// Returns the amount of token that this call is worth. If `tokenAddress` is `0`, then value is in terms of the native token, otherwise it's in terms of the token address.
function contractCallValue(
Expand All @@ -30,16 +28,6 @@ abstract contract AxelarValuedExpressExecutable is
bytes calldata payload
) public view virtual returns (address tokenAddress, uint256 value);

// Returns the amount of token that this call is worth. If `tokenAddress` is `0`, then value is in terms of the native token, otherwise it's in terms of the token address.
// The returned call value is in addition to the `amount` of token `symbol` being transferred with the call.
function contractCallWithTokenValue(
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) public view virtual returns (address tokenAddress, uint256 value);

function execute(
bytes32 commandId,
string calldata sourceChain,
Expand Down Expand Up @@ -67,68 +55,6 @@ abstract contract AxelarValuedExpressExecutable is
}
}

function executeWithToken(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata tokenSymbol,
uint256 amount
) external override(AxelarExecutableWithToken, IAxelarExecutableWithToken) {
bytes32 payloadHash = keccak256(payload);
if (
!gatewayWithToken().validateContractCallAndMint(
commandId,
sourceChain,
sourceAddress,
payloadHash,
tokenSymbol,
amount
)
) revert NotApprovedByGateway();

address expressExecutor = _popExpressExecutorWithToken(
commandId,
sourceChain,
sourceAddress,
payloadHash,
tokenSymbol,
amount
);

if (expressExecutor == address(0)) {
_executeWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount);
return;
}

// slither-disable-next-line reentrancy-events
emit ExpressExecutionWithTokenFulfilled(
commandId,
sourceChain,
sourceAddress,
payloadHash,
tokenSymbol,
amount,
expressExecutor
);

{
(address tokenAddress, uint256 value) = contractCallWithTokenValue(
sourceChain,
sourceAddress,
payload,
tokenSymbol,
amount
);
_transferToExecutor(expressExecutor, tokenAddress, value);
}

{
address gatewayToken = gatewayWithToken().tokenAddresses(tokenSymbol);
IERC20(gatewayToken).safeTransfer(expressExecutor, amount);
}
}

function expressExecute(
bytes32 commandId,
string calldata sourceChain,
Expand All @@ -152,56 +78,21 @@ abstract contract AxelarValuedExpressExecutable is
_execute(commandId, sourceChain, sourceAddress, payload);
}

function expressExecuteWithToken(
/**
* @notice Returns the express executor for a given command.
* @param commandId The commandId for the contractCall.
* @param sourceChain The source chain.
* @param sourceAddress The source address.
* @param payloadHash The hash of the payload.
* @return expressExecutor The address of the express executor.
*/
function getExpressExecutor(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) external payable virtual {
if (gatewayWithToken().isCommandExecuted(commandId)) revert AlreadyExecuted();

address expressExecutor = msg.sender;
bytes32 payloadHash = keccak256(payload);

emit ExpressExecutedWithToken(
commandId,
sourceChain,
sourceAddress,
payloadHash,
symbol,
amount,
expressExecutor
);

_setExpressExecutorWithToken(
commandId,
sourceChain,
sourceAddress,
payloadHash,
symbol,
amount,
expressExecutor
);

{
(address tokenAddress, uint256 value) = contractCallWithTokenValue(
sourceChain,
sourceAddress,
payload,
symbol,
amount
);
_transferFromExecutor(expressExecutor, tokenAddress, value);
}

{
address gatewayToken = gatewayWithToken().tokenAddresses(symbol);
IERC20(gatewayToken).safeTransferFrom(expressExecutor, address(this), amount);
}

_executeWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount);
bytes32 payloadHash
) external view returns (address expressExecutor) {
expressExecutor = _getExpressExecutor(commandId, sourceChain, sourceAddress, payloadHash);
}

function _transferToExecutor(
Expand Down
Loading

0 comments on commit ef7044b

Please sign in to comment.