diff --git a/v2/package.json b/v2/package.json index 1935e987..d2fba154 100644 --- a/v2/package.json +++ b/v2/package.json @@ -8,7 +8,7 @@ "test": "test" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "forge clean && forge test -vv" }, "devDependencies": { }, diff --git a/v2/src/evm/ERC20CustodyNew.sol b/v2/src/evm/ERC20CustodyNew.sol index 5e269135..963afa3d 100644 --- a/v2/src/evm/ERC20CustodyNew.sol +++ b/v2/src/evm/ERC20CustodyNew.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; +import "./interfaces//IGatewayEVM.sol"; +import "./interfaces/IERC20CustodyNew.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; -import "./interfaces//IGatewayEVM.sol"; -import "./interfaces/IERC20CustodyNew.sol"; /// @title ERC20CustodyNew /// @notice Holds the ERC20 tokens deposited on ZetaChain and includes functionality to call a contract. @@ -51,7 +51,16 @@ contract ERC20CustodyNew is IERC20CustodyNewEvents, IERC20CustodyNewErrors, Reen /// @param to Address of the contract to call. /// @param amount Amount of tokens to withdraw. /// @param data Calldata to pass to the contract call. - function withdrawAndCall(address token, address to, uint256 amount, bytes calldata data) public nonReentrant onlyTSS { + function withdrawAndCall( + address token, + address to, + uint256 amount, + bytes calldata data + ) + public + nonReentrant + onlyTSS + { // Transfer the tokens to the Gateway contract IERC20(token).safeTransfer(address(gateway), amount); @@ -61,13 +70,23 @@ contract ERC20CustodyNew is IERC20CustodyNewEvents, IERC20CustodyNewErrors, Reen emit WithdrawAndCall(token, to, amount, data); } - /// @notice WithdrawAndRevert transfers tokens to Gateway and call a contract with a revert functionality through the Gateway. + /// @notice WithdrawAndRevert transfers tokens to Gateway and call a contract with a revert functionality through + /// the Gateway. /// @dev This function can only be called by the TSS address. /// @param token Address of the ERC20 token. /// @param to Address of the contract to call. /// @param amount Amount of tokens to withdraw. /// @param data Calldata to pass to the contract call. - function withdrawAndRevert(address token, address to, uint256 amount, bytes calldata data) public nonReentrant onlyTSS { + function withdrawAndRevert( + address token, + address to, + uint256 amount, + bytes calldata data + ) + public + nonReentrant + onlyTSS + { // Transfer the tokens to the Gateway contract IERC20(token).safeTransfer(address(gateway), amount); @@ -76,4 +95,4 @@ contract ERC20CustodyNew is IERC20CustodyNewEvents, IERC20CustodyNewErrors, Reen emit WithdrawAndRevert(token, to, amount, data); } -} \ No newline at end of file +} diff --git a/v2/src/evm/GatewayEVM.sol b/v2/src/evm/GatewayEVM.sol index 0e707593..e69abb1b 100644 --- a/v2/src/evm/GatewayEVM.sol +++ b/v2/src/evm/GatewayEVM.sol @@ -3,17 +3,25 @@ pragma solidity ^0.8.20; import "./ZetaConnectorNewBase.sol"; import "./interfaces/IGatewayEVM.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; + import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /// @title GatewayEVM /// @notice The GatewayEVM contract is the endpoint to call smart contracts on external chains. /// @dev The contract doesn't hold any funds and should never have active allowances. -contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGatewayEVMErrors, IGatewayEVMEvents, ReentrancyGuardUpgradeable { +contract GatewayEVM is + Initializable, + OwnableUpgradeable, + UUPSUpgradeable, + IGatewayEVMErrors, + IGatewayEVMEvents, + ReentrancyGuardUpgradeable +{ using SafeERC20 for IERC20; /// @notice The address of the custody contract. @@ -61,7 +69,7 @@ contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGate /// @dev Authorizes the upgrade of the contract, sender must be owner. /// @param newImplementation Address of the new implementation. - function _authorizeUpgrade(address newImplementation) internal override onlyOwner() {} + function _authorizeUpgrade(address newImplementation) internal override onlyOwner { } /// @dev Internal function to execute a call to a destination address. /// @param destination Address to call. @@ -79,7 +87,7 @@ contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGate /// @param destination Address to call. /// @param data Calldata to pass to the call. function executeRevert(address destination, bytes calldata data) public payable onlyTSS { - (bool success, bytes memory result) = destination.call{value: msg.value}(""); + (bool success, bytes memory result) = destination.call{ value: msg.value }(""); if (!success) revert ExecutionFailed(); Revertable(destination).onRevert(data); @@ -91,7 +99,7 @@ contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGate /// @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) external payable onlyTSS returns (bytes memory) { + function execute(address destination, bytes calldata data) external payable onlyTSS returns (bytes memory) { bytes memory result = _execute(destination, data); emit Executed(destination, msg.value, data); @@ -111,7 +119,11 @@ contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGate address to, uint256 amount, bytes calldata data - ) public nonReentrant onlyAssetHandler { + ) + public + nonReentrant + onlyAssetHandler + { if (amount == 0) revert InsufficientERC20Amount(); // Approve the target contract to spend the tokens if (!resetApproval(token, to)) revert ApprovalFailed(); @@ -142,7 +154,11 @@ contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGate address to, uint256 amount, bytes calldata data - ) external nonReentrant onlyAssetHandler { + ) + external + nonReentrant + onlyAssetHandler + { if (amount == 0) revert InsufficientERC20Amount(); IERC20(token).safeTransfer(address(to), amount); @@ -234,7 +250,8 @@ contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGate } /// @dev Transfers tokens from the sender to the asset handler. - /// This function handles the transfer of tokens to either the connector or custody contract based on the asset type. + /// This function handles the transfer of tokens to either the connector or custody contract based on the asset + /// type. /// @param from Address of the sender. /// @param token Address of the ERC20 token. /// @param amount Amount of tokens to transfer. @@ -254,7 +271,8 @@ contract GatewayEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable, IGate } /// @dev Transfers tokens to the asset handler. - /// This function handles the transfer of tokens to either the connector or custody contract based on the asset type. + /// This function handles the transfer of tokens to either the connector or custody contract based on the asset + /// type. /// @param token Address of the ERC20 token. /// @param amount Amount of tokens to transfer. function transferToAssetHandler(address token, uint256 amount) private { diff --git a/v2/src/evm/ZetaConnectorNative.sol b/v2/src/evm/ZetaConnectorNative.sol index a781e1b3..860c4f6d 100644 --- a/v2/src/evm/ZetaConnectorNative.sol +++ b/v2/src/evm/ZetaConnectorNative.sol @@ -11,9 +11,13 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract ZetaConnectorNative is ZetaConnectorNewBase { using SafeERC20 for IERC20; - constructor(address _gateway, address _zetaToken, address _tssAddress) + constructor( + address _gateway, + address _zetaToken, + address _tssAddress + ) ZetaConnectorNewBase(_gateway, _zetaToken, _tssAddress) - {} + { } /// @notice Withdraw tokens to a specified address. /// @param to The address to withdraw tokens to. @@ -31,7 +35,17 @@ contract ZetaConnectorNative is ZetaConnectorNewBase { /// @param data The calldata to pass to the contract call. /// @param internalSendHash A hash used for internal tracking of the transaction. /// @dev This function can only be called by the TSS address. - function withdrawAndCall(address to, uint256 amount, bytes calldata data, bytes32 internalSendHash) external override nonReentrant onlyTSS { + function withdrawAndCall( + address to, + uint256 amount, + bytes calldata data, + bytes32 internalSendHash + ) + external + override + nonReentrant + onlyTSS + { // Transfer zetaToken to the Gateway contract IERC20(zetaToken).safeTransfer(address(gateway), amount); @@ -47,7 +61,17 @@ contract ZetaConnectorNative is ZetaConnectorNewBase { /// @param data The calldata to pass to the contract call. /// @param internalSendHash A hash used for internal tracking of the transaction. /// @dev This function can only be called by the TSS address. - function withdrawAndRevert(address to, uint256 amount, bytes calldata data, bytes32 internalSendHash) external override nonReentrant onlyTSS { + function withdrawAndRevert( + address to, + uint256 amount, + bytes calldata data, + bytes32 internalSendHash + ) + external + override + nonReentrant + onlyTSS + { // Transfer zetaToken to the Gateway contract IERC20(zetaToken).safeTransfer(address(gateway), amount); diff --git a/v2/src/evm/ZetaConnectorNewBase.sol b/v2/src/evm/ZetaConnectorNewBase.sol index bf1a0fe2..7295ecde 100644 --- a/v2/src/evm/ZetaConnectorNewBase.sol +++ b/v2/src/evm/ZetaConnectorNewBase.sol @@ -54,14 +54,28 @@ abstract contract ZetaConnectorNewBase is IZetaConnectorEvents, ReentrancyGuard /// @param amount The amount of tokens to withdraw. /// @param data The calldata to pass to the contract call. /// @param internalSendHash A hash used for internal tracking of the transaction. - function withdrawAndCall(address to, uint256 amount, bytes calldata data, bytes32 internalSendHash) external virtual; + function withdrawAndCall( + address to, + uint256 amount, + bytes calldata data, + bytes32 internalSendHash + ) + external + virtual; /// @notice Withdraw tokens and call a contract with a revert callback through Gateway. /// @param to The address to withdraw tokens to. /// @param amount The amount of tokens to withdraw. /// @param data The calldata to pass to the contract call. /// @param internalSendHash A hash used for internal tracking of the transaction. - function withdrawAndRevert(address to, uint256 amount, bytes calldata data, bytes32 internalSendHash) external virtual; + function withdrawAndRevert( + address to, + uint256 amount, + bytes calldata data, + bytes32 internalSendHash + ) + external + virtual; /// @notice Handle received tokens. /// @param amount The amount of tokens received. diff --git a/v2/src/evm/ZetaConnectorNonNative.sol b/v2/src/evm/ZetaConnectorNonNative.sol index e1a336b0..a9870e18 100644 --- a/v2/src/evm/ZetaConnectorNonNative.sol +++ b/v2/src/evm/ZetaConnectorNonNative.sol @@ -15,17 +15,21 @@ contract ZetaConnectorNonNative is ZetaConnectorNewBase { /// @notice Event triggered when max supply is updated. /// @param maxSupply New max supply. event MaxSupplyUpdated(uint256 maxSupply); + error ExceedsMaxSupply(); - constructor(address _gateway, address _zetaToken, address _tssAddress) + constructor( + address _gateway, + address _zetaToken, + address _tssAddress + ) ZetaConnectorNewBase(_gateway, _zetaToken, _tssAddress) - {} + { } - /// @notice Set max supply for minting. /// @param _maxSupply New max supply. /// @dev This function can only be called by the TSS address. - function setMaxSupply(uint256 _maxSupply) external onlyTSS() { + function setMaxSupply(uint256 _maxSupply) external onlyTSS { maxSupply = _maxSupply; emit MaxSupplyUpdated(_maxSupply); } @@ -48,7 +52,17 @@ contract ZetaConnectorNonNative is ZetaConnectorNewBase { /// @param data The calldata to pass to the contract call. /// @param internalSendHash A hash used for internal tracking of the transaction. /// @dev This function can only be called by the TSS address, and mints if supply is not reached. - function withdrawAndCall(address to, uint256 amount, bytes calldata data, bytes32 internalSendHash) external override nonReentrant onlyTSS { + function withdrawAndCall( + address to, + uint256 amount, + bytes calldata data, + bytes32 internalSendHash + ) + external + override + nonReentrant + onlyTSS + { if (amount + IERC20(zetaToken).totalSupply() > maxSupply) revert ExceedsMaxSupply(); // Mint zetaToken to the Gateway contract @@ -66,7 +80,17 @@ contract ZetaConnectorNonNative is ZetaConnectorNewBase { /// @param data The calldata to pass to the contract call. /// @param internalSendHash A hash used for internal tracking of the transaction. /// @dev This function can only be called by the TSS address, and mints if supply is not reached. - function withdrawAndRevert(address to, uint256 amount, bytes calldata data, bytes32 internalSendHash) external override nonReentrant onlyTSS { + function withdrawAndRevert( + address to, + uint256 amount, + bytes calldata data, + bytes32 internalSendHash + ) + external + override + nonReentrant + onlyTSS + { if (amount + IERC20(zetaToken).totalSupply() > maxSupply) revert ExceedsMaxSupply(); // Mint zetaToken to the Gateway contract diff --git a/v2/src/evm/interfaces/IERC20CustodyNew.sol b/v2/src/evm/interfaces/IERC20CustodyNew.sol index 027758bc..e4015f98 100644 --- a/v2/src/evm/interfaces/IERC20CustodyNew.sol +++ b/v2/src/evm/interfaces/IERC20CustodyNew.sol @@ -33,4 +33,4 @@ interface IERC20CustodyNewErrors { /// @notice Error for invalid sender. error InvalidSender(); -} \ No newline at end of file +} diff --git a/v2/src/evm/interfaces/IGatewayEVM.sol b/v2/src/evm/interfaces/IGatewayEVM.sol index b9bb7ecb..424dbba7 100644 --- a/v2/src/evm/interfaces/IGatewayEVM.sol +++ b/v2/src/evm/interfaces/IGatewayEVM.sol @@ -81,12 +81,7 @@ interface IGatewayEVM { /// @param to The address of the contract to call. /// @param amount The amount of tokens to transfer. /// @param data The calldata to pass to the contract call. - function executeWithERC20( - address token, - address to, - uint256 amount, - bytes calldata data - ) external; + function executeWithERC20(address token, address to, uint256 amount, bytes calldata data) external; /// @notice Executes a call to a contract. /// @param destination The address of the contract to call. @@ -99,12 +94,7 @@ interface IGatewayEVM { /// @param to The address of the contract to call. /// @param amount The amount of tokens to transfer. /// @param data The calldata to pass to the contract call. - function revertWithERC20( - address token, - address to, - uint256 amount, - bytes calldata data - ) external; + function revertWithERC20(address token, address to, uint256 amount, bytes calldata data) external; } /// @title Revertable diff --git a/v2/src/evm/interfaces/IZetaNonEthNew.sol b/v2/src/evm/interfaces/IZetaNonEthNew.sol index a92f833f..094debdf 100644 --- a/v2/src/evm/interfaces/IZetaNonEthNew.sol +++ b/v2/src/evm/interfaces/IZetaNonEthNew.sol @@ -18,4 +18,4 @@ interface IZetaNonEthNew is IERC20 { /// @param internalSendHash A hash used for internal tracking of the minting transaction. /// @dev Emits a {Transfer} event with `from` set to the zero address. function mint(address mintee, uint256 value, bytes32 internalSendHash) external; -} \ No newline at end of file +} diff --git a/v2/src/zevm/GatewayZEVM.sol b/v2/src/zevm/GatewayZEVM.sol index fbdd4371..426475d8 100644 --- a/v2/src/zevm/GatewayZEVM.sol +++ b/v2/src/zevm/GatewayZEVM.sol @@ -13,7 +13,14 @@ import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol /// @title GatewayZEVM /// @notice The GatewayZEVM contract is the endpoint to call smart contracts on omnichain. /// @dev The contract doesn't hold any funds and should never have active allowances. -contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, OwnableUpgradeable, UUPSUpgradeable, ReentrancyGuardUpgradeable { +contract GatewayZEVM is + IGatewayZEVMEvents, + IGatewayZEVMErrors, + Initializable, + OwnableUpgradeable, + UUPSUpgradeable, + ReentrancyGuardUpgradeable +{ /// @notice Error indicating a zero address was provided. error ZeroAddress(); @@ -48,7 +55,7 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O /// @dev Authorizes the upgrade of the contract. /// @param newImplementation The address of the new implementation. - function _authorizeUpgrade(address newImplementation) internal override onlyOwner() {} + function _authorizeUpgrade(address newImplementation) internal override onlyOwner { } /// @dev Receive function to receive ZETA from WETH9.withdraw(). receive() external payable { @@ -98,7 +105,15 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O /// @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. - function withdrawAndCall(bytes memory receiver, uint256 amount, address zrc20, bytes calldata message) external nonReentrant { + function withdrawAndCall( + bytes memory receiver, + uint256 amount, + address zrc20, + bytes calldata message + ) + external + nonReentrant + { uint256 gasFee = _withdrawZRC20(amount, zrc20); emit Withdrawal(msg.sender, zrc20, receiver, amount, gasFee, IZRC20(zrc20).PROTOCOL_FLAT_FEE(), message); } @@ -131,11 +146,7 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O /// @param zrc20 The address of the ZRC20 token. /// @param amount The amount of tokens to deposit. /// @param target The target address to receive the deposited tokens. - function deposit( - address zrc20, - uint256 amount, - address target - ) external onlyFungible { + function deposit(address zrc20, uint256 amount, address target) external onlyFungible { if (target == FUNGIBLE_MODULE_ADDRESS || target == address(this)) revert InvalidTarget(); IZRC20(zrc20).deposit(target, amount); @@ -153,7 +164,10 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O uint256 amount, address target, bytes calldata message - ) external onlyFungible { + ) + external + onlyFungible + { UniversalContract(target).onCrossChainCall(context, zrc20, amount, message); } @@ -169,7 +183,10 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O uint256 amount, address target, bytes calldata message - ) external onlyFungible { + ) + external + onlyFungible + { if (target == FUNGIBLE_MODULE_ADDRESS || target == address(this)) revert InvalidTarget(); IZRC20(zrc20).deposit(target, amount); @@ -186,7 +203,10 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O uint256 amount, address target, bytes calldata message - ) external onlyFungible { + ) + external + onlyFungible + { if (target == FUNGIBLE_MODULE_ADDRESS || target == address(this)) revert InvalidTarget(); _transferZETA(amount, target); @@ -205,7 +225,10 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O uint256 amount, address target, bytes calldata message - ) external onlyFungible { + ) + external + onlyFungible + { UniversalContract(target).onRevert(context, zrc20, amount, message); } @@ -221,7 +244,10 @@ contract GatewayZEVM is IGatewayZEVMEvents, IGatewayZEVMErrors, Initializable, O uint256 amount, address target, bytes calldata message - ) external onlyFungible { + ) + external + onlyFungible + { if (target == FUNGIBLE_MODULE_ADDRESS || target == address(this)) revert InvalidTarget(); IZRC20(zrc20).deposit(target, amount); diff --git a/v2/src/zevm/interfaces/IGatewayZEVM.sol b/v2/src/zevm/interfaces/IGatewayZEVM.sol index de394d24..2b9a7ff6 100644 --- a/v2/src/zevm/interfaces/IGatewayZEVM.sol +++ b/v2/src/zevm/interfaces/IGatewayZEVM.sol @@ -29,11 +29,7 @@ interface IGatewayZEVM { /// @param zrc20 The address of the ZRC20 token. /// @param amount The amount of tokens to deposit. /// @param target The target address to receive the deposited tokens. - function deposit( - address zrc20, - uint256 amount, - address target - ) external; + function deposit(address zrc20, uint256 amount, address target) external; /// @notice Execute a user-specified contract on ZEVM. /// @param context The context of the cross-chain call. @@ -83,7 +79,15 @@ interface IGatewayZEVMEvents { /// @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. - event Withdrawal(address indexed from, address zrc20, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee, bytes message); + event Withdrawal( + address indexed from, + address zrc20, + bytes to, + uint256 value, + uint256 gasfee, + uint256 protocolFlatFee, + bytes message + ); } /// @title IGatewayZEVMErrors diff --git a/v2/test/GatewayEVM.t.sol b/v2/test/GatewayEVM.t.sol index 52405fa6..b1b6c5c0 100644 --- a/v2/test/GatewayEVM.t.sol +++ b/v2/test/GatewayEVM.t.sol @@ -7,17 +7,18 @@ import "forge-std/Vm.sol"; import "./utils/ReceiverEVM.sol"; import "./utils/TestERC20.sol"; + +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; +import { Upgrades } from "openzeppelin-foundry-upgrades/Upgrades.sol"; -import "src/evm/interfaces/IGatewayEVM.sol"; -import "src/evm/GatewayEVM.sol"; -import "src/evm/interfaces/IERC20CustodyNew.sol"; +import "./utils/IReceiverEVM.sol"; import "src/evm/ERC20CustodyNew.sol"; +import "src/evm/GatewayEVM.sol"; import "src/evm/ZetaConnectorNonNative.sol"; -import "./utils/IReceiverEVM.sol"; +import "src/evm/interfaces/IERC20CustodyNew.sol"; +import "src/evm/interfaces/IGatewayEVM.sol"; contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiverEVMEvents, IERC20CustodyNewEvents { using SafeERC20 for IERC20; @@ -56,8 +57,8 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver gateway.setConnector(address(zetaConnector)); vm.stopPrank(); - token.mint(owner, 1000000); - token.transfer(address(custody), 500000); + token.mint(owner, 1_000_000); + token.transfer(address(custody), 500_000); vm.deal(tssAddress, 1 ether); } @@ -87,7 +88,7 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver num[0] = 42; bool flag = true; bytes memory data = abi.encodeWithSignature("receiveNonPayable(string[],uint256[],bool)", str, num, flag); - + vm.prank(owner); vm.expectRevert(InvalidSender.selector); gateway.execute(address(receiver), data); @@ -108,7 +109,7 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver vm.expectEmit(true, true, true, true, address(gateway)); emit Executed(address(receiver), 1 ether, data); vm.prank(tssAddress); - gateway.execute{value: value}(address(receiver), data); + gateway.execute{ value: value }(address(receiver), data); assertEq(value, address(receiver).balance); } @@ -126,8 +127,9 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver } function testExecuteWithERC20FailsIfNotCustoryOrConnector() public { - uint256 amount = 100000; - bytes memory data = abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); + uint256 amount = 100_000; + bytes memory data = + abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); vm.prank(owner); vm.expectRevert(InvalidSender.selector); @@ -135,8 +137,9 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver } function testRevertWithERC20FailsIfNotCustoryOrConnector() public { - uint256 amount = 100000; - bytes memory data = abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); + uint256 amount = 100_000; + bytes memory data = + abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); vm.prank(owner); vm.expectRevert(InvalidSender.selector); @@ -178,8 +181,9 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver } function testForwardCallToReceiveERC20ThroughCustodyFailsIfSenderIsNotTSS() public { - uint256 amount = 100000; - bytes memory data = abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); + uint256 amount = 100_000; + bytes memory data = + abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); vm.prank(owner); vm.expectRevert(InvalidSender.selector); @@ -188,8 +192,9 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver function testForwardCallToReceiveERC20ThroughCustodyFailsIfAmountIs0() public { uint256 amount = 0; - bytes memory data = abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); - + bytes memory data = + abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(token), destination); + vm.prank(tssAddress); vm.expectRevert(InsufficientERC20Amount.selector); custody.withdrawAndCall(address(token), address(receiver), amount, data); @@ -230,9 +235,10 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver } function testForwardCallToReceiveERC20PartialThroughCustodyFailsIfSenderIsNotTSS() public { - uint256 amount = 100000; - bytes memory data = abi.encodeWithSignature("receiveERC20Partial(uint256,address,address)", amount, address(token), destination); - + uint256 amount = 100_000; + bytes memory data = + abi.encodeWithSignature("receiveERC20Partial(uint256,address,address)", amount, address(token), destination); + vm.prank(owner); vm.expectRevert(InvalidSender.selector); custody.withdrawAndCall(address(token), address(receiver), amount, data); @@ -240,8 +246,9 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver function testForwardCallToReceiveERC20PartialThroughCustodyFailsIfAmountIs0() public { uint256 amount = 0; - bytes memory data = abi.encodeWithSignature("receiveERC20Partial(uint256,address,address)", amount, address(token), destination); - + bytes memory data = + abi.encodeWithSignature("receiveERC20Partial(uint256,address,address)", amount, address(token), destination); + vm.prank(tssAddress); vm.expectRevert(InsufficientERC20Amount.selector); custody.withdrawAndCall(address(token), address(receiver), amount, data); @@ -307,7 +314,7 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver } function testWithdrawThroughCustodyFailsIfSenderIsNotTSS() public { - uint256 amount = 100000; + uint256 amount = 100_000; vm.prank(owner); vm.expectRevert(InvalidSender.selector); @@ -351,7 +358,7 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver } function testWithdrawAndRevertThroughCustodyFailsIfSenderIsNotTSS() public { - uint256 amount = 100000; + uint256 amount = 100_000; bytes memory data = abi.encodePacked("hello"); vm.prank(owner); @@ -380,7 +387,7 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver vm.expectEmit(true, true, true, true, address(gateway)); emit Reverted(address(receiver), 1 ether, data); vm.prank(tssAddress); - gateway.executeRevert{value: value}(address(receiver), data); + gateway.executeRevert{ value: value }(address(receiver), data); // Verify that the tokens were transferred to the receiver address uint256 balanceAfter = address(receiver).balance; @@ -393,7 +400,7 @@ contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiver vm.prank(owner); vm.expectRevert(InvalidSender.selector); - gateway.executeRevert{value: value}(address(receiver), data); + gateway.executeRevert{ value: value }(address(receiver), data); } } diff --git a/v2/test/GatewayEVMUpgrade.t.sol b/v2/test/GatewayEVMUpgrade.t.sol index f46374d1..c9581dc6 100644 --- a/v2/test/GatewayEVMUpgrade.t.sol +++ b/v2/test/GatewayEVMUpgrade.t.sol @@ -9,17 +9,19 @@ import "./utils/GatewayEVMUpgradeTest.sol"; import "./utils/IReceiverEVM.sol"; import "./utils/ReceiverEVM.sol"; import "./utils/TestERC20.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; +import { Upgrades } from "openzeppelin-foundry-upgrades/Upgrades.sol"; -import "src/evm/interfaces/IGatewayEVM.sol"; import "./utils/IReceiverEVM.sol"; -import "src/evm/GatewayEVM.sol"; + import "src/evm/ERC20CustodyNew.sol"; +import "src/evm/GatewayEVM.sol"; import "src/evm/ZetaConnectorNonNative.sol"; +import "src/evm/interfaces/IGatewayEVM.sol"; contract GatewayEVMUUPSUpgradeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiverEVMEvents { using SafeERC20 for IERC20; @@ -61,8 +63,8 @@ contract GatewayEVMUUPSUpgradeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents gateway.setConnector(address(zetaConnector)); vm.stopPrank(); - token.mint(owner, 1000000); - token.transfer(address(custody), 500000); + token.mint(owner, 1_000_000); + token.transfer(address(custody), 500_000); vm.deal(tssAddress, 1 ether); } @@ -87,7 +89,7 @@ contract GatewayEVMUUPSUpgradeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents vm.expectEmit(true, true, true, true, address(gateway)); emit ExecutedV2(address(receiver), value, data); vm.prank(tssAddress); - gatewayUpgradeTest.execute{value: value}(address(receiver), data); + gatewayUpgradeTest.execute{ value: value }(address(receiver), data); assertEq(custodyBeforeUpgrade, gateway.custody()); assertEq(tssBeforeUpgrade, gateway.tssAddress()); diff --git a/v2/test/GatewayEVMZEVM.t.sol b/v2/test/GatewayEVMZEVM.t.sol index 20c0671b..cb62da47 100644 --- a/v2/test/GatewayEVMZEVM.t.sol +++ b/v2/test/GatewayEVMZEVM.t.sol @@ -102,7 +102,7 @@ contract GatewayEVMZEVMTest is vm.stopPrank(); vm.prank(ownerZEVM); - zrc20.approve(address(gatewayZEVM), 1000000); + zrc20.approve(address(gatewayZEVM), 1_000_000); vm.deal(tssAddress, 1 ether); } @@ -125,7 +125,7 @@ contract GatewayEVMZEVMTest is vm.expectEmit(true, true, true, true, address(gatewayEVM)); emit Executed(address(receiverEVM), value, message); vm.prank(tssAddress); - gatewayEVM.execute{value: value}(address(receiverEVM), message); + gatewayEVM.execute{ value: value }(address(receiverEVM), message); } function testCallReceiverEVMFromSenderZEVM() public { @@ -148,7 +148,7 @@ contract GatewayEVMZEVMTest is vm.expectEmit(true, true, true, true, address(gatewayEVM)); emit Executed(address(receiverEVM), value, message); vm.prank(tssAddress); - gatewayEVM.execute{value: value}(address(receiverEVM), message); + gatewayEVM.execute{ value: value }(address(receiverEVM), message); } function testWithdrawAndCallReceiverEVMFromZEVM() public { @@ -177,7 +177,7 @@ contract GatewayEVMZEVMTest is vm.expectEmit(true, true, true, true, address(gatewayEVM)); emit Executed(address(receiverEVM), value, message); vm.prank(tssAddress); - gatewayEVM.execute{value: value}(address(receiverEVM), message); + gatewayEVM.execute{ value: value }(address(receiverEVM), message); } function testWithdrawAndCallReceiverEVMFromSenderZEVM() public { @@ -207,7 +207,7 @@ contract GatewayEVMZEVMTest is vm.expectEmit(true, true, true, true, address(gatewayEVM)); emit Executed(address(receiverEVM), value, message); vm.prank(tssAddress); - gatewayEVM.execute{value: value}(address(receiverEVM), message); + gatewayEVM.execute{ value: value }(address(receiverEVM), message); // Check the balance after withdrawal uint256 senderBalanceAfterWithdrawal = IZRC20(zrc20).balanceOf(address(senderZEVM)); diff --git a/v2/test/ZetaConnectorNative.t.sol b/v2/test/ZetaConnectorNative.t.sol index 2eba5093..9960da26 100644 --- a/v2/test/ZetaConnectorNative.t.sol +++ b/v2/test/ZetaConnectorNative.t.sol @@ -7,19 +7,27 @@ import "forge-std/Vm.sol"; import "./utils/ReceiverEVM.sol"; import "./utils/TestERC20.sol"; + +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol"; +import { Upgrades } from "openzeppelin-foundry-upgrades/Upgrades.sol"; -import "src/evm/interfaces/IGatewayEVM.sol"; import "./utils/IReceiverEVM.sol"; -import "src/evm/interfaces/IZetaConnector.sol"; -import "src/evm/GatewayEVM.sol"; + import "src/evm/ERC20CustodyNew.sol"; +import "src/evm/GatewayEVM.sol"; import "src/evm/ZetaConnectorNative.sol"; +import "src/evm/interfaces/IGatewayEVM.sol"; +import "src/evm/interfaces/IZetaConnector.sol"; -contract ZetaConnectorNativeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiverEVMEvents, IZetaConnectorEvents { +contract ZetaConnectorNativeTest is + Test, + IGatewayEVMErrors, + IGatewayEVMEvents, + IReceiverEVMEvents, + IZetaConnectorEvents +{ using SafeERC20 for IERC20; address proxy; @@ -55,13 +63,13 @@ contract ZetaConnectorNativeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, gateway.setConnector(address(zetaConnector)); vm.stopPrank(); - zetaToken.mint(address(zetaConnector), 5000000); + zetaToken.mint(address(zetaConnector), 5_000_000); vm.deal(tssAddress, 1 ether); } function testWithdraw() public { - uint256 amount = 100000; + uint256 amount = 100_000; bytes32 internalSendHash = ""; uint256 balanceBefore = zetaToken.balanceOf(destination); assertEq(balanceBefore, 0); @@ -77,7 +85,7 @@ contract ZetaConnectorNativeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, } function testWithdrawFailsIfSenderIsNotTSS() public { - uint256 amount = 100000; + uint256 amount = 100_000; bytes32 internalSendHash = ""; vm.prank(owner); @@ -121,9 +129,10 @@ contract ZetaConnectorNativeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, } function testWithdrawAndCallReceiveERC20FailsIfSenderIsNotTSS() public { - uint256 amount = 100000; + uint256 amount = 100_000; bytes32 internalSendHash = ""; - bytes memory data = abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(zetaToken), destination); + bytes memory data = + abi.encodeWithSignature("receiveERC20(uint256,address,address)", amount, address(zetaToken), destination); vm.prank(owner); vm.expectRevert(InvalidSender.selector); @@ -238,7 +247,7 @@ contract ZetaConnectorNativeTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, } function testWithdrawAndRevertFailsIfSenderIsNotTSS() public { - uint256 amount = 100000; + uint256 amount = 100_000; bytes32 internalSendHash = ""; bytes memory data = abi.encodePacked("hello"); diff --git a/v2/test/utils/GatewayEVMUpgradeTest.sol b/v2/test/utils/GatewayEVMUpgradeTest.sol index a587de95..7e910379 100644 --- a/v2/test/utils/GatewayEVMUpgradeTest.sol +++ b/v2/test/utils/GatewayEVMUpgradeTest.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "src/evm/interfaces/IGatewayEVM.sol"; import "src/evm/ZetaConnectorNewBase.sol"; +import "src/evm/interfaces/IGatewayEVM.sol"; /// @title GatewayEVMUpgradeTest /// @notice Modified GatewayEVM contract for testing upgrades @@ -37,7 +37,6 @@ contract GatewayEVMUpgradeTest is /// @dev Modified event for testing upgrade. event ExecutedV2(address indexed destination, uint256 value, bytes data); - /// @notice Only TSS address allowed modifier. modifier onlyTSS() { if (msg.sender != tssAddress) { @@ -60,7 +59,7 @@ contract GatewayEVMUpgradeTest is if (_tssAddress == address(0) || _zetaToken == address(0)) { revert ZeroAddress(); } - + __Ownable_init(msg.sender); __UUPSUpgradeable_init(); __ReentrancyGuard_init(); @@ -71,7 +70,7 @@ contract GatewayEVMUpgradeTest is /// @dev Authorizes the upgrade of the contract, sender must be owner. /// @param newImplementation Address of the new implementation. - function _authorizeUpgrade(address newImplementation) internal override onlyOwner() {} + function _authorizeUpgrade(address newImplementation) internal override onlyOwner { } /// @dev Internal function to execute a call to a destination address. /// @param destination Address to call. @@ -89,7 +88,7 @@ contract GatewayEVMUpgradeTest is /// @param destination Address to call. /// @param data Calldata to pass to the call. function executeRevert(address destination, bytes calldata data) public payable onlyTSS { - (bool success, bytes memory result) = destination.call{value: msg.value}(""); + (bool success, bytes memory result) = destination.call{ value: msg.value }(""); if (!success) revert ExecutionFailed(); Revertable(destination).onRevert(data); @@ -101,7 +100,7 @@ contract GatewayEVMUpgradeTest 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) external payable onlyTSS returns (bytes memory) { + function execute(address destination, bytes calldata data) external payable onlyTSS returns (bytes memory) { bytes memory result = _execute(destination, data); emit ExecutedV2(destination, msg.value, data); @@ -121,11 +120,15 @@ contract GatewayEVMUpgradeTest is address to, uint256 amount, bytes calldata data - ) public nonReentrant onlyCustodyOrConnector { + ) + public + nonReentrant + onlyCustodyOrConnector + { if (amount == 0) revert InsufficientERC20Amount(); // Approve the target contract to spend the tokens - if(!resetApproval(token, to)) revert ApprovalFailed(); - if(!IERC20(token).approve(to, amount)) revert ApprovalFailed(); + if (!resetApproval(token, to)) revert ApprovalFailed(); + if (!IERC20(token).approve(to, amount)) revert ApprovalFailed(); // Execute the call on the target contract bytes memory result = _execute(to, data); @@ -152,7 +155,11 @@ contract GatewayEVMUpgradeTest is address to, uint256 amount, bytes calldata data - ) external nonReentrant onlyCustodyOrConnector { + ) + external + nonReentrant + onlyCustodyOrConnector + { if (amount == 0) revert InsufficientERC20Amount(); IERC20(token).safeTransfer(address(to), amount); @@ -244,7 +251,8 @@ contract GatewayEVMUpgradeTest is } /// @dev Transfers tokens from the sender to the asset handler. - /// This function handles the transfer of tokens to either the connector or custody contract based on the asset type. + /// This function handles the transfer of tokens to either the connector or custody contract based on the asset + /// type. /// @param from Address of the sender. /// @param token Address of the ERC20 token. /// @param amount Amount of tokens to transfer. @@ -264,7 +272,8 @@ contract GatewayEVMUpgradeTest is } /// @dev Transfers tokens to the asset handler. - /// This function handles the transfer of tokens to either the connector or custody contract based on the asset type. + /// This function handles the transfer of tokens to either the connector or custody contract based on the asset + /// type. /// @param token Address of the ERC20 token. /// @param amount Amount of tokens to transfer. function transferToAssetHandler(address token, uint256 amount) private { diff --git a/v2/test/utils/ReceiverEVM.sol b/v2/test/utils/ReceiverEVM.sol index 568fab62..a0d49a4e 100644 --- a/v2/test/utils/ReceiverEVM.sol +++ b/v2/test/utils/ReceiverEVM.sol @@ -72,8 +72,8 @@ contract ReceiverEVM is IReceiverEVMEvents, ReentrancyGuard { } /// @notice Receives ETH. - receive() external payable {} + receive() external payable { } /// @notice Fallback function to receive ETH. - fallback() external payable {} + fallback() external payable { } } diff --git a/v2/test/utils/SenderZEVM.sol b/v2/test/utils/SenderZEVM.sol index 448091c4..5398647c 100644 --- a/v2/test/utils/SenderZEVM.sol +++ b/v2/test/utils/SenderZEVM.sol @@ -41,7 +41,16 @@ contract SenderZEVM { /// @param num A numeric parameter to pass to the receiver's function. /// @param flag A boolean parameter to pass to the receiver's function. /// @dev Approves the gateway to withdraw tokens and encodes the function call to pass to the gateway. - function withdrawAndCallReceiver(bytes memory receiver, uint256 amount, address zrc20, string memory str, uint256 num, bool flag) external { + function withdrawAndCallReceiver( + bytes memory receiver, + uint256 amount, + address zrc20, + string memory str, + uint256 num, + bool flag + ) + external + { // Encode the function call to the receiver's receivePayable method bytes memory message = abi.encodeWithSignature("receivePayable(string,uint256,bool)", str, num, flag); diff --git a/v2/test/utils/TestZContract.sol b/v2/test/utils/TestZContract.sol index 4b7d6ed1..c3f0837e 100644 --- a/v2/test/utils/TestZContract.sol +++ b/v2/test/utils/TestZContract.sol @@ -69,8 +69,8 @@ contract TestZContract is UniversalContract { } /// @notice Allows the contract to receive ETH. - receive() external payable {} + receive() external payable { } /// @notice Fallback function to receive ETH. - fallback() external payable {} + fallback() external payable { } }