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: add sender when calling connected chain contracts from zetachain #350

Closed
wants to merge 12 commits into from
18 changes: 14 additions & 4 deletions v2/contracts/evm/GatewayEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.8.26;
import { RevertContext, RevertOptions, Revertable } from "../../contracts/Revert.sol";
import { ZetaConnectorBase } from "./ZetaConnectorBase.sol";
import { IERC20Custody } from "./interfaces/IERC20Custody.sol";
import { IGatewayEVM } from "./interfaces/IGatewayEVM.sol";
import { IGatewayEVM, Callable, MessageContext } from "./interfaces/IGatewayEVM.sol";

import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
Expand Down Expand Up @@ -75,13 +75,17 @@ contract GatewayEVM is
/// @param destination Address to call.
/// @param data Calldata to pass to the call.
/// @return The result of the call.
function _execute(address destination, bytes calldata data) internal returns (bytes memory) {
function _executeArbitraryCall(address destination, bytes calldata data) internal returns (bytes memory) {
lumtis marked this conversation as resolved.
Show resolved Hide resolved
(bool success, bytes memory result) = destination.call{ value: msg.value }(data);
if (!success) revert ExecutionFailed();

return result;
}

function _executeAuthenticatedCall(MessageContext calldata messageContext, address destination, bytes calldata data) internal returns (bytes memory) {
return Callable(destination).onCall(messageContext.sender, data);
}

/// @notice Pause contract.
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
Expand Down Expand Up @@ -121,6 +125,7 @@ contract GatewayEVM is
/// @param data Calldata to pass to the call.
/// @return The result of the call.
function execute(
MessageContext calldata messageContext,
address destination,
bytes calldata data
)
Expand All @@ -132,7 +137,12 @@ contract GatewayEVM is
returns (bytes memory)
{
if (destination == address(0)) revert ZeroAddress();
bytes memory result = _execute(destination, data);
bytes memory result;
if (messageContext.isArbitraryCall) {
result = _executeArbitraryCall(destination, data);
} else {
result = _executeAuthenticatedCall(messageContext, destination, data);
}

emit Executed(destination, msg.value, data);

Expand Down Expand Up @@ -163,7 +173,7 @@ contract GatewayEVM is
if (!resetApproval(token, to)) revert ApprovalFailed();
if (!IERC20(token).approve(to, amount)) revert ApprovalFailed();
// Execute the call on the target contract
_execute(to, data);
_executeArbitraryCall(to, data);

// Reset approval
if (!resetApproval(token, to)) revert ApprovalFailed();
Expand Down
14 changes: 13 additions & 1 deletion v2/contracts/evm/interfaces/IGatewayEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ interface IGatewayEVM is IGatewayEVMErrors, IGatewayEVMEvents {
/// @param destination The address of the contract to call.
/// @param data The calldata to pass to the contract call.
/// @return The result of the contract call.
function execute(address destination, bytes calldata data) external payable returns (bytes memory);
function execute(MessageContext calldata messageContext, address destination, bytes calldata data) external payable returns (bytes memory);

/// @notice Executes a revertable call to a contract using ERC20 tokens.
/// @param token The address of the ERC20 token.
Expand Down Expand Up @@ -171,3 +171,15 @@ interface IGatewayEVM is IGatewayEVMErrors, IGatewayEVMEvents {
/// @param revertOptions Revert options.
function call(address receiver, bytes calldata payload, RevertOptions calldata revertOptions) external;
}

struct MessageContext {
address sender;
bool isArbitraryCall;
}

interface Callable {
function onCall(
address sender,
bytes calldata message
) external returns (bytes memory);
}
10 changes: 5 additions & 5 deletions v2/contracts/zevm/GatewayZEVM.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import { IGatewayZEVM } from "./interfaces/IGatewayZEVM.sol";
import { IGatewayZEVM, CallOptions } from "./interfaces/IGatewayZEVM.sol";

import { RevertContext, RevertOptions } from "../../contracts/Revert.sol";
import "./interfaces/IWZETA.sol";
Expand Down Expand Up @@ -242,13 +242,13 @@ contract GatewayZEVM is
/// @param receiver The receiver address on the external chain.
/// @param zrc20 Address of zrc20 to pay fees.
/// @param message The calldata to pass to the contract call.
/// @param gasLimit Gas limit.
/// @param callOptions Call options including gas limit and arbirtrary call flag.
/// @param revertOptions Revert options.
function call(
bytes memory receiver,
address zrc20,
bytes calldata message,
uint256 gasLimit,
CallOptions calldata callOptions,
RevertOptions calldata revertOptions
)
external
Expand All @@ -258,12 +258,12 @@ contract GatewayZEVM is
if (receiver.length == 0) revert ZeroAddress();
if (message.length == 0) revert EmptyMessage();

(address gasZRC20, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(gasLimit);
(address gasZRC20, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(callOptions.gasLimit);
if (!IZRC20(gasZRC20).transferFrom(msg.sender, FUNGIBLE_MODULE_ADDRESS, gasFee)) {
revert GasFeeTransferFailed();
}

emit Called(msg.sender, zrc20, receiver, message, gasLimit, revertOptions);
emit Called(msg.sender, zrc20, receiver, message, callOptions, revertOptions);
}

/// @notice Deposit foreign coins into ZRC20.
Expand Down
9 changes: 7 additions & 2 deletions v2/contracts/zevm/interfaces/IGatewayZEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ interface IGatewayZEVMEvents {
/// @param zrc20 Address of zrc20 to pay fees.
/// @param receiver The receiver address on the external chain.
/// @param message The calldata passed to the contract call.
/// @param gasLimit Gas limit.
/// @param callOptions Call options including gas limit and arbirtrary call flag.
/// @param revertOptions Revert options.
event Called(
address indexed sender,
address indexed zrc20,
bytes receiver,
bytes message,
uint256 gasLimit,
CallOptions callOptions,
RevertOptions revertOptions
);

Expand Down Expand Up @@ -231,3 +231,8 @@ interface IGatewayZEVM is IGatewayZEVMErrors, IGatewayZEVMEvents {
)
external;
}

struct CallOptions {
uint256 gasLimit;
bool isArbitraryCall;
}
Loading