Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 9 additions & 3 deletions contracts/evm/GatewayEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { INotSupportedMethods } from "../../contracts/Errors.sol";
import { RevertContext, RevertOptions, Revertable } from "../../contracts/Revert.sol";
import { ZetaConnectorBase } from "./ZetaConnectorBase.sol";
import { IERC20Custody } from "./interfaces/IERC20Custody.sol";
import { Callable, IGatewayEVM, MessageContext } from "./interfaces/IGatewayEVM.sol";
import "./interfaces/IGatewayEVM.sol";

import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
Expand Down Expand Up @@ -561,7 +561,13 @@ contract GatewayEVM is
private
returns (bytes memory)
{
return Callable(destination).onCall{ value: msg.value }(messageContext, data);
if (messageContext.amount == 0) {
return Callable(destination).onCall{ value: msg.value }(
LegacyMessageContext({ sender: messageContext.sender }), data
);
} else {
return CallableV2(destination).onCall{ value: msg.value }(messageContext, data);
}
}

// @dev prevent spoofing onCall and onRevert functions
Expand All @@ -572,7 +578,7 @@ contract GatewayEVM is
functionSelector := calldataload(data.offset)
}

if (functionSelector == Callable.onCall.selector) {
if (functionSelector == Callable.onCall.selector || functionSelector == CallableV2.onCall.selector) {
revert NotAllowedToCallOnCall();
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/evm/Registry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract Registry is BaseRegistry, IRegistry {
/// @param context Information about the cross-chain message
/// @param data The encoded function call to execute
function onCall(
MessageContext calldata context,
LegacyMessageContext calldata context,
bytes calldata data
)
external
Expand Down
7 changes: 1 addition & 6 deletions contracts/evm/ZetaConnectorBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import { RevertContext } from "../../contracts/Revert.sol";
import {
IGatewayEVM,
IGatewayEVMErrors,
IGatewayEVMEvents,
MessageContext
} from "../../contracts/evm/interfaces/IGatewayEVM.sol";
import { IGatewayEVM, MessageContext } from "../../contracts/evm/interfaces/IGatewayEVM.sol";
import "../../contracts/evm/interfaces/IZetaConnector.sol";

/// @title ZetaConnectorBase
Expand Down
23 changes: 22 additions & 1 deletion contracts/evm/interfaces/IGatewayEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -282,12 +282,33 @@ interface IGatewayEVM is IGatewayEVMErrors, IGatewayEVMEvents {

/// @notice Message context passed to execute function.
/// @param sender Sender from omnichain contract.
struct MessageContext {
struct LegacyMessageContext {
address sender;
}

/// @notice Interface implemented by contracts receiving authenticated calls.
interface Callable {
function onCall(
LegacyMessageContext calldata context,
bytes calldata message
)
external
payable
returns (bytes memory);
}

/// @notice Message context passed to execute function.
/// @param sender Sender from omnichain contract.
/// @param asset The address of the asset.
/// @param amount The amount of the asset.
struct MessageContext {
address sender;
address asset;
uint256 amount;
}

/// @notice Interface implemented by contracts receiving authenticated calls with new MessageContext.
interface CallableV2 {
function onCall(
MessageContext calldata context,
bytes calldata message
Expand Down
41 changes: 41 additions & 0 deletions contracts/zevm/GatewayZEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,47 @@ contract GatewayZEVM is
);
}

/// @notice Withdraw ZRC20 tokens and call a smart contract on an external chain.
/// @param receiver The receiver address on the external chain.
/// @param amount The amount of tokens to withdraw.
/// @param zrc20 The address of the ZRC20 token.
/// @param message The calldata to pass to the contract call.
/// @param version The number representing message context version.
/// @param callOptions Call options including gas limit, arbirtrary call flag and message context version.
/// @param revertOptions Revert options.
function withdrawAndCall(
bytes memory receiver,
uint256 amount,
address zrc20,
bytes calldata message,
uint256 version,
CallOptions calldata callOptions,
RevertOptions calldata revertOptions
)
external
whenNotPaused
{
if (receiver.length == 0) revert ZeroAddress();
if (amount == 0) revert InsufficientZRC20Amount();
if (callOptions.gasLimit < MIN_GAS_LIMIT) revert InsufficientGasLimit();
if (message.length + revertOptions.revertMessage.length > MAX_MESSAGE_SIZE) revert MessageSizeExceeded();

uint256 gasFee = _withdrawZRC20WithGasLimit(amount, zrc20, callOptions.gasLimit);
emit WithdrawnAndCalledV2(
msg.sender,
0,
receiver,
zrc20,
amount,
gasFee,
IZRC20(zrc20).PROTOCOL_FLAT_FEE(),
message,
version,
callOptions,
revertOptions
);
}

/// @notice Withdraw ZETA tokens to an external chain.
//// @param receiver The receiver address on the external chain.
//// @param amount The amount of tokens to withdraw.
Expand Down
45 changes: 45 additions & 0 deletions contracts/zevm/interfaces/IGatewayZEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,32 @@ interface IGatewayZEVMEvents {
CallOptions callOptions,
RevertOptions revertOptions
);

/// @notice Emitted when a withdraw and call is made.
/// @param sender The address from which the tokens are withdrawn.
/// @param chainId Chain id of external chain.
/// @param receiver The receiver address on the external chain.
/// @param zrc20 The address of the ZRC20 token.
/// @param value The amount of tokens withdrawn.
/// @param gasfee The gas fee for the withdrawal.
/// @param protocolFlatFee The protocol flat fee for the withdrawal.
/// @param message The calldata passed to the contract call.
/// @param version The number representing message context version.
/// @param callOptions Call options including gas limit, arbirtrary call flag and message context version.
/// @param revertOptions Revert options.
event WithdrawnAndCalledV2(
address indexed sender,
uint256 indexed chainId,
bytes receiver,
address zrc20,
uint256 value,
uint256 gasfee,
uint256 protocolFlatFee,
bytes message,
uint256 version,
CallOptions callOptions,
RevertOptions revertOptions
);
}

/// @title IGatewayZEVMErrors
Expand Down Expand Up @@ -161,6 +187,25 @@ interface IGatewayZEVM is IGatewayZEVMErrors, IGatewayZEVMEvents {
)
external;

/// @notice Withdraw ZRC20 tokens and call a smart contract on an external chain.
/// @param receiver The receiver address on the external chain.
/// @param amount The amount of tokens to withdraw.
/// @param zrc20 The address of the ZRC20 token.
/// @param message The calldata to pass to the contract call.
/// @param version The number representing message context version.
/// @param callOptions Call options including gas limit, arbirtrary call flag and message context version.
/// @param revertOptions Revert options.
function withdrawAndCall(
bytes memory receiver,
uint256 amount,
address zrc20,
bytes calldata message,
uint256 version,
CallOptions calldata callOptions,
RevertOptions calldata revertOptions
)
external;

/// @notice Withdraw ZETA tokens and call a smart contract on an external chain.
/// @param receiver The receiver address on the external chain.
/// @param amount The amount of tokens to withdraw.
Expand Down
2 changes: 1 addition & 1 deletion data/addresses.testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"type": "zetaToken"
},
{
"address": "0x6b2fe12c605d64e14ca69f9aba51550593ba92ff43376d0a6cc26a5ca226f9bd,0x6fc08f682551e52c2cc34362a20f744ba6a3d8d17f6583fa2f774887c4079700",
"address": "0x28acc3a03af7658e52456617ac5ba6933ebf8dfb03469697b3673577a4262e24,0x6fc08f682551e52c2cc34362a20f744ba6a3d8d17f6583fa2f774887c4079700,0x01f724edef5461e280e533649b08c191a39af5f677025a226664a6626373b393,0x6b2fe12c605d64e14ca69f9aba51550593ba92ff43376d0a6cc26a5ca226f9bd,0x6b2fe12c605d64e14ca69f9aba51550593ba92ff43376d0a6cc26a5ca226f9bd",
"category": "omnichain",
"chain_id": 103,
"chain_name": "sui_testnet",
Expand Down
Loading