diff --git a/v2/src/evm/GatewayEVM.sol b/v2/src/evm/GatewayEVM.sol index 071f3898..dd4f9420 100644 --- a/v2/src/evm/GatewayEVM.sol +++ b/v2/src/evm/GatewayEVM.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.26; import "./ZetaConnectorBase.sol"; - import "./interfaces/IERC20Custody.sol"; import "./interfaces/IGatewayEVM.sol"; diff --git a/v2/src/zevm/interfaces/IGatewayZEVM.sol b/v2/src/zevm/interfaces/IGatewayZEVM.sol index 63d4b592..394a8478 100644 --- a/v2/src/zevm/interfaces/IGatewayZEVM.sol +++ b/v2/src/zevm/interfaces/IGatewayZEVM.sol @@ -3,6 +3,16 @@ pragma solidity 0.8.26; import "./UniversalContract.sol"; +/// @notice Struct containing revert options +/// @param revertAddress Address to receive revert. +/// @param callOnRevert Flag if onRevert hook should be called. +/// @pararm abortAddress Address to receive funds if aborted. +struct RevertOptions { + address revertAddress; + bool callOnRevert; + address abortAddress; +} + /// @title IGatewayZEVMEvents /// @notice Interface for the events emitted by the GatewayZEVM contract. interface IGatewayZEVMEvents { @@ -76,16 +86,6 @@ interface IGatewayZEVMErrors { error OnlyWZETAOrFungible(); } -/// @notice Struct containing revert options -/// @param revertAddress Address to receive revert. -/// @param callOnRevert Flag if onRevert hook should be called. -/// @pararm abortAddress Address to receive funds if aborted. -struct RevertOptions { - address revertAddress; - bool callOnRevert; - address abortAddress; -} - /// @title IGatewayZEVM /// @notice Interface for the GatewayZEVM contract. /// @dev Defines functions for cross-chain interactions and token handling. diff --git a/v2/test/GatewayEVM.t.sol b/v2/test/GatewayEVM.t.sol index 5cbbd13c..b5350350 100644 --- a/v2/test/GatewayEVM.t.sol +++ b/v2/test/GatewayEVM.t.sol @@ -350,7 +350,7 @@ contract GatewayEVMInboundTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IR custody.unwhitelist(address(token)); vm.expectRevert(NotWhitelistedInCustody.selector); - gateway.deposit(destination, amount, address(token)); + gateway.deposit(destination, amount, address(token), revertOptions); } function testDepositZetaToConnector() public { @@ -380,12 +380,6 @@ contract GatewayEVMInboundTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IR gateway.deposit(address(0), amount, address(token), revertOptions); } - function testFailDepositERC20ToCustodyIfReceiverIsZeroAddress() public { - uint256 amount = 1; - vm.expectRevert("ZeroAddress"); - gateway.deposit(address(0), amount, address(token)); - } - function testDepositEthToTss() public { uint256 amount = 100_000; uint256 tssBalanceBefore = tssAddress.balance; @@ -412,13 +406,6 @@ contract GatewayEVMInboundTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IR gateway.deposit{ value: amount }(address(0), revertOptions); } - function testFailDepositEthToTssIfReceiverIsZeroAddress() public { - uint256 amount = 1; - - vm.expectRevert("ZeroAddress"); - gateway.deposit{ value: amount }(address(0)); - } - function testDepositERC20ToCustodyWithPayloadFailsIfTokenIsNotWhitelisted() public { uint256 amount = 100_000; bytes memory payload = abi.encodeWithSignature("hello(address)", destination); @@ -429,7 +416,7 @@ contract GatewayEVMInboundTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IR custody.unwhitelist(address(token)); vm.expectRevert(NotWhitelistedInCustody.selector); - gateway.depositAndCall(destination, amount, address(token), payload); + gateway.depositAndCall(destination, amount, address(token), payload, revertOptions); } function testDepositERC20ToCustodyWithPayload() public { @@ -470,15 +457,6 @@ contract GatewayEVMInboundTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IR gateway.depositAndCall(address(0), amount, address(token), payload, revertOptions); } - function testFailDepositERC20ToCustodyWithPayloadIfReceiverIsZeroAddress() public { - uint256 amount = 1; - - bytes memory payload = abi.encodeWithSignature("hello(address)", destination); - - vm.expectRevert("ZeroAddress"); - gateway.depositAndCall(address(0), amount, address(token), payload); - } - function testDepositEthToTssWithPayload() public { uint256 amount = 100_000; uint256 tssBalanceBefore = tssAddress.balance; @@ -508,14 +486,6 @@ contract GatewayEVMInboundTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IR gateway.depositAndCall{ value: amount }(address(0), payload, revertOptions); } - function testFailDepositEthToTssWithPayloadIfReceiverIsZeroAddress() public { - uint256 amount = 1; - bytes memory payload = abi.encodeWithSignature("hello(address)", destination); - - vm.expectRevert("ZeroAddress"); - gateway.depositAndCall{ value: amount }(address(0), payload); - } - function testCallWithPayload() public { bytes memory payload = abi.encodeWithSignature("hello(address)", destination); @@ -528,6 +498,6 @@ contract GatewayEVMInboundTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IR bytes memory payload = abi.encodeWithSignature("hello(address)", destination); vm.expectRevert(ZeroAddress.selector); - gateway.call(address(0), payload); + gateway.call(address(0), payload, revertOptions); } } diff --git a/v2/test/GatewayZEVM.t.sol b/v2/test/GatewayZEVM.t.sol index 9ec41ac3..5f8c20fa 100644 --- a/v2/test/GatewayZEVM.t.sol +++ b/v2/test/GatewayZEVM.t.sol @@ -31,9 +31,6 @@ contract GatewayZEVMInboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors error ZeroAddress(); error LowBalance(); - error ZeroAddress(); - error LowBalance(); - function setUp() public { owner = address(this); addr1 = address(0x1234); @@ -186,24 +183,24 @@ contract GatewayZEVMInboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testWithdrawZETAFailsIfAmountIsZero() public { vm.expectRevert(InsufficientZetaAmount.selector); - gateway.withdraw(abi.encodePacked(addr1), 0, 1); + gateway.withdraw(abi.encodePacked(addr1), 0, 1, revertOptions); } function testWithdrawZETAFailsIfReceiverIsZeroAddress() public { vm.expectRevert(ZeroAddress.selector); - gateway.withdraw(abi.encodePacked(""), 0, 1); + gateway.withdraw(abi.encodePacked(""), 0, 1, revertOptions); } function testWithdrawAndCallZETAFailsIfAmountIsZero() public { bytes memory message = abi.encodeWithSignature("hello(address)", addr1); vm.expectRevert(InsufficientZetaAmount.selector); - gateway.withdrawAndCall(abi.encodePacked(addr1), 0, 1, message); + gateway.withdrawAndCall(abi.encodePacked(addr1), 0, 1, message, revertOptions); } function testWithdrawAndCallZETAFailsIfAmountIsReceiverIsZeroAddress() public { bytes memory message = abi.encodeWithSignature("hello(address)", addr1); vm.expectRevert(ZeroAddress.selector); - gateway.withdrawAndCall(abi.encodePacked(""), 1, 1, message); + gateway.withdrawAndCall(abi.encodePacked(""), 1, 1, message, revertOptions); } function testWithdrawZETA() public { @@ -336,6 +333,7 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors address owner; address addr1; address fungibleModule; + RevertOptions revertOptions; event ContextData(bytes origin, address sender, uint256 chainID, address msgSender, string message); event ContextDataRevert(bytes origin, address sender, uint256 chainID, address msgSender, string message); @@ -543,8 +541,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testExecuteRevertUniversalContractFailsIfTargetIsZeroAddress() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.prank(fungibleModule); vm.expectRevert(ZeroAddress.selector); @@ -553,8 +551,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testExecuteRevertUniversalContractFailsIfAmountIsZero() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.prank(fungibleModule); vm.expectRevert(InsufficientZRC20Amount.selector); @@ -563,8 +561,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testExecuteRevertUniversalContractFailsIfZeroAddress() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.prank(fungibleModule); vm.expectRevert(ZeroAddress.selector); @@ -573,8 +571,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testExecuteRevertUniversalContractFailsIfZRC20IsZeroAddress() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.prank(fungibleModule); vm.expectRevert(ZeroAddress.selector); @@ -583,8 +581,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testExecuteRevertUniversalContract() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.expectEmit(true, true, true, true, address(testUniversalContract)); emit ContextDataRevert(abi.encodePacked(gateway), fungibleModule, 1, address(gateway), "hello"); @@ -681,8 +679,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testDepositAndRevertZRC20AndCallUniversalContractFailsIfZRC20IsZeroAddress() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.prank(fungibleModule); vm.expectRevert(ZeroAddress.selector); @@ -691,8 +689,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testDepositAndRevertZRC20AndCallUniversalContractFailsIfTargetIsZeroAddress() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.prank(fungibleModule); vm.expectRevert(ZeroAddress.selector); @@ -701,8 +699,8 @@ contract GatewayZEVMOutboundTest is Test, IGatewayZEVMEvents, IGatewayZEVMErrors function testDepositAndRevertZRC20AndCallUniversalContractFailsIfAmountIsZero() public { bytes memory message = abi.encode("hello"); - revertContext memory context = - revertContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); + zContext memory context = + zContext({ origin: abi.encodePacked(address(gateway)), sender: fungibleModule, chainID: 1 }); vm.prank(fungibleModule); vm.expectRevert(InsufficientZRC20Amount.selector); diff --git a/v2/test/utils/GatewayEVMUpgradeTest.sol b/v2/test/utils/GatewayEVMUpgradeTest.sol index 83ec2239..dfc97907 100644 --- a/v2/test/utils/GatewayEVMUpgradeTest.sol +++ b/v2/test/utils/GatewayEVMUpgradeTest.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.26; import "src/evm/ZetaConnectorBase.sol"; import "src/evm/interfaces/IGatewayEVM.sol"; +import "src/evm/interfaces/IERC20Custody.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; @@ -21,8 +22,6 @@ contract GatewayEVMUpgradeTest is AccessControlUpgradeable, UUPSUpgradeable, IGatewayEVM, - IGatewayEVMErrors, - IGatewayEVMEvents, ReentrancyGuardUpgradeable, PausableUpgradeable { @@ -313,6 +312,7 @@ contract GatewayEVMUpgradeTest is whenNotPaused nonReentrant { + if (receiver == address(0)) revert ZeroAddress(); emit Call(msg.sender, receiver, payload, revertOptions); } @@ -362,6 +362,7 @@ contract GatewayEVMUpgradeTest is ZetaConnectorBase(zetaConnector).receiveTokens(amount); } else { // transfer to custody + if (!IERC20Custody(custody).whitelisted(token)) revert NotWhitelistedInCustody(); IERC20(token).safeTransferFrom(from, custody, amount); } } @@ -380,6 +381,7 @@ contract GatewayEVMUpgradeTest is ZetaConnectorBase(zetaConnector).receiveTokens(amount); } else { // transfer to custody + if (!IERC20Custody(custody).whitelisted(token)) revert NotWhitelistedInCustody(); IERC20(token).safeTransfer(custody, amount); } }