🧑‍💻Contracts

Overviews

A cross-chain swap is executed by sending a quoted swap request from the DApp to the PheasantNetworkSwap contract.

Technical Details

TransactionRequest

A structured format for sending a quoted swap request.

/// @param data Data of the quoted request.
/// @param toChainId Chain ID of the Swap destination.
/// @param swapToolIndex DEX Protocol index (for administrative use).
/// @param toolContract To address of the quoted request (DEX Protocol contract address).
/// @param fromToken Token address of the Swap source.
/// @param toToken Token address of the Swap destination.
/// @param amount Amount of the Swap source.
/// @param value Value of the quoted request.
/// @param gas Gas of the quoted request.
/// @param quoteTimestamp Timestamp of quote execution for RelayerFee determination.
struct TransactionRequest {
    bytes data;
    string toChainId;
    uint16 swapToolIndex;
    address toolContract;
    address fromToken;
    address toToken;
    uint256 amount;
    uint256 value;
    uint256 gas;
    uint256 quoteTimestamp;
}

execute()

A function that executes the swap by calling the DEX protocol.

/// @notice Executes Swap by calling the DEX Protocol based on the quoted request.
/// @param request Transaction request made based on the quoted request.
function execute(TransactionRequest calldata request) external payable;

Low-Level Call Execution

The PheasantNetworkSwap contract initiates the swap by making a low-level call to the specified DEX protocol contract. It passes the quoted request parameters (data, gas and value), forwarding the transaction to the DEX protocol for execution.

(bool success, bytes memory res) = request.toolContract.call{ gas: request.gas, value: value }(request.data);

RelayerFee

The RelayerFee is temporarily stored in the contract using a 32-byte key until the swap’s success is confirmed. Success is determined off-chain by querying the DEX protocol through the relayer.

/// @param toChainId Chain ID of the Swap destination.
/// @param swapToolIndex DEX Protocol index (for administrative use).
/// @param toolContract To address of the quoted request (DEX Protocol contract address).
/// @param toToken Token address of the Swap destination.
/// @param amount Amount of the Swap source.
/// @param relayerFee RelayerFee calculated from the amount.
/// @param quoteTimestamp Timestamp of quote execution for RelayerFee determination.
struct SwapTrade {
    string toChainId;
    uint16 swapToolIndex;
    address toolContract;
    address toToken;
    uint256 amount;
    uint256 relayerFee;
    uint256 timestamp;
}

/// @notice Generates the trade key.
/// @param userAddress Address of the user who executed the execute.
/// @param token Token address of the Swap source.
/// @param tradeHash keccak256 hash of SwapTrade.
function generateKey(address userAddress, address token, bytes32 tradeHash) internal pure returns (bytes32) {
    return keccak256(abi.encode(userAddress, token, tradeHash));
}

The following code stores the RelayerFee along with a 32-byte key:

Types.SwapTrade memory trade = Types.SwapTrade(
    request.toChainId,
    request.swapToolIndex,
    request.toolContract,
    request.toToken,
    request.amount,
    relayerFee,
    block.timestamp
);

bytes32 tradeKey = generateKey(msg.sender, request.fromToken, keccak256(abi.encode(trade)));

feeByTrade.set(tradeKey, relayerFee);

refund()

If the swap fails, the RelayerFee is refunded to the user.

/// @notice Refunds RelayerFee to user on Swap failure.
/// @param userAddress Address of the user who executed the execute.
/// @param token Token address of the Swap source.
/// @param tradeHash keccak256 hash of SwapTrade.
/// @param data Swap trade result data to be recorded in the event.
function refund(address userAddress, address token, bytes32 tradeHash, bytes calldata data) external payable;

withdraw()

If the swap succeeds, the Relayer can withdraw the earned RelayerFee.

/// @param data Swap trade result data to be recorded in the event.
/// @param tradeHash keccak256 hash of SwapTrade.
/// @param userAddress Address of the user who executed the execute.
/// @param token Token address of the Swap source.
struct SwapWithdrawRequest {
    bytes data;
    bytes32 tradeHash;
    address userAddress;
    address token;
}

/// @notice Withdraws RelayerFee obtained after swap succeeded.
/// @param request Swap trade information for Withdraw.
function withdraw(SwapWithdrawRequest calldata request) external payable;

Last updated

Was this helpful?