Skip to content

Commit

Permalink
more foundry tests
Browse files Browse the repository at this point in the history
  • Loading branch information
skosito committed Jul 8, 2024
1 parent 86b4d77 commit e881d7c
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "contracts/prototypes/evm/ERC20CustodyNew.sol";
import "contracts/prototypes/evm/TestERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./interfaces.sol";
import "../evm/interfaces.sol";
import "forge-std/console.sol";

contract GatewayEVMTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IReceiverEVMEvents {
Expand Down
103 changes: 103 additions & 0 deletions contracts/prototypes/test/GatewayIntegration.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "forge-std/Test.sol";
import "forge-std/Vm.sol";

import "contracts/prototypes/evm/GatewayEVM.sol";
import "contracts/prototypes/evm/ReceiverEVM.sol";
import "contracts/prototypes/evm/ERC20CustodyNew.sol";
import "contracts/prototypes/evm/TestERC20.sol";
import "contracts/prototypes/evm/ReceiverEVM.sol";

import "contracts/prototypes/zevm/GatewayZEVM.sol";
import "contracts/prototypes/zevm/SenderZEVM.sol";
import "contracts/zevm/ZRC20New.sol";
import "contracts/zevm/testing/SystemContractMock.sol";

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../evm/interfaces.sol";
import "../zevm/interfaces.sol";
import "forge-std/console.sol";

contract GatewayIntegrationTest is Test, IGatewayEVMErrors, IGatewayEVMEvents, IGatewayZEVMEvents, IReceiverEVMEvents {
// evm
using SafeERC20 for IERC20;

GatewayEVM gatewayEVM;
ERC20CustodyNew custody;
TestERC20 token;
ReceiverEVM receiverEVM;
address ownerEVM;
address destination;
address tssAddress;

// zevm
GatewayZEVM gatewayZEVM;
SenderZEVM senderZEVM;
SystemContractMock systemContract;
ZRC20New zrc20;
address ownerZEVM;

function setUp() public {
// evm
ownerEVM = address(this);
destination = address(0x1234);
tssAddress = address(0x5678);
ownerZEVM = address(0x4321);

token = new TestERC20("test", "TTK");
gatewayEVM = new GatewayEVM();
custody = new ERC20CustodyNew(address(gatewayEVM));

gatewayEVM.initialize(tssAddress);
gatewayEVM.setCustody(address(custody));

// Mint initial supply to the ownerEVM
token.mint(ownerEVM, 1000000);

// Transfer some tokens to the custody contract
token.transfer(address(custody), 500000);

receiverEVM = new ReceiverEVM();

// zevm
// Impersonate the fungible module account
gatewayZEVM = new GatewayZEVM();

senderZEVM = new SenderZEVM(address(gatewayZEVM));
address fungibleModuleAddress = address(0x735b14BB79463307AAcBED86DAf3322B1e6226aB);
vm.startPrank(fungibleModuleAddress);
systemContract = new SystemContractMock(address(0), address(0), address(0));
zrc20 = new ZRC20New("TOKEN", "TKN", 18, 1, CoinType.Zeta, 0, address(systemContract), address(gatewayZEVM));
systemContract.setGasCoinZRC20(1, address(zrc20));
systemContract.setGasPrice(1, 1);
zrc20.deposit(ownerZEVM, 1000000);
zrc20.deposit(address(senderZEVM), 1000000);
vm.stopPrank();

vm.prank(ownerZEVM);
zrc20.approve(address(gatewayZEVM), 1000000);
}

function testCallReceiverEVMFromZEVM() public {
string memory str = "Hello, Hardhat!";
uint256 num = 42;
bool flag = true;
uint256 value = 1 ether;

// Encode the function call data and call on zevm
bytes memory message = abi.encodeWithSelector(receiverEVM.receivePayable.selector, str, num, flag);
vm.prank(ownerZEVM);
vm.expectEmit(true, true, true, true, address(gatewayZEVM));
emit Call(address(ownerZEVM), abi.encodePacked(receiverEVM), message);
gatewayZEVM.call(abi.encodePacked(receiverEVM), message);

// Call execute on evm
vm.deal(address(gatewayEVM), value);
vm.expectEmit(true, true, true, true, address(gatewayEVM));
emit Executed(address(receiverEVM), value, message);
gatewayEVM.execute{value: value}(address(receiverEVM), message);
}
}
6 changes: 2 additions & 4 deletions contracts/prototypes/zevm/GatewayZEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "../../zevm/interfaces/IZRC20.sol";
import "../../zevm/interfaces/zContract.sol";
import "./interfaces.sol";

// The GatewayZEVM contract is the endpoint to call smart contracts on omnichain
// The contract doesn't hold any funds and should never have active allowances
contract GatewayZEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable {
contract GatewayZEVM is IGatewayZEVMEvents, Initializable, OwnableUpgradeable, UUPSUpgradeable {
address public constant FUNGIBLE_MODULE_ADDRESS = 0x735b14BB79463307AAcBED86DAf3322B1e6226aB;

error WithdrawalFailed();
Expand All @@ -20,9 +21,6 @@ contract GatewayZEVM is Initializable, OwnableUpgradeable, UUPSUpgradeable {
error CallerIsNotFungibleModule();
error InvalidTarget();

event Call(address indexed sender, bytes receiver, bytes message);
event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee, bytes message);

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
Expand Down
5 changes: 5 additions & 0 deletions contracts/prototypes/zevm/interfaces.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ interface IGatewayZEVM {
address target,
bytes calldata message
) external;
}

interface IGatewayZEVMEvents {
event Call(address indexed sender, bytes receiver, bytes message);
event Withdrawal(address indexed from, bytes to, uint256 value, uint256 gasfee, uint256 protocolFlatFee, bytes message);
}
62 changes: 0 additions & 62 deletions contracts/zevm/Interfaces.sol

This file was deleted.

8 changes: 4 additions & 4 deletions contracts/zevm/ZRC20.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "./Interfaces.sol";
import "./interfaces/IZRC20.sol";

/**
* @dev Custom errors for ZRC20
Expand All @@ -17,7 +17,7 @@ interface ZRC20Errors {
error ZeroAddress();
}

contract ZRC20 is IZRC20, IZRC20Metadata, ZRC20Errors {
contract ZRC20 is IZRC20Metadata, ZRC20Events, ZRC20Errors {
/// @notice Fungible address is always the same, maintained at the protocol level
address public constant FUNGIBLE_MODULE_ADDRESS = 0x735b14BB79463307AAcBED86DAf3322B1e6226aB;
/// @notice Chain id.abi
Expand All @@ -29,7 +29,7 @@ contract ZRC20 is IZRC20, IZRC20Metadata, ZRC20Errors {
/// @notice Gas limit.
uint256 public GAS_LIMIT;
/// @notice Protocol flat fee.
uint256 public PROTOCOL_FLAT_FEE;
uint256 public override PROTOCOL_FLAT_FEE;

mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
Expand Down Expand Up @@ -170,7 +170,7 @@ contract ZRC20 is IZRC20, IZRC20Metadata, ZRC20Errors {
* @param amount, amount to burn.
* @return true/false if succeeded/failed.
*/
function burn(uint256 amount) external returns (bool) {
function burn(uint256 amount) external override returns (bool) {
_burn(msg.sender, amount);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "../../zevm/Interfaces.sol";
import "./interfaces/IZRC20.sol";

/**
* @dev Custom errors for ZRC20
Expand All @@ -19,7 +19,7 @@ interface ZRC20Errors {

// NOTE: this is exactly the same as ZRC20, except gateway contract address is set at deployment
// and used to allow deposit. This is first version, it might change in the future.
contract ZRC20New is IZRC20, IZRC20Metadata, ZRC20Errors {
contract ZRC20New is IZRC20Metadata, ZRC20Errors, ZRC20Events {
/// @notice Fungible address is always the same, maintained at the protocol level
address public constant FUNGIBLE_MODULE_ADDRESS = 0x735b14BB79463307AAcBED86DAf3322B1e6226aB;
/// @notice Chain id.abi
Expand All @@ -33,7 +33,7 @@ contract ZRC20New is IZRC20, IZRC20Metadata, ZRC20Errors {
/// @notice Gas limit.
uint256 public GAS_LIMIT;
/// @notice Protocol flat fee.
uint256 public PROTOCOL_FLAT_FEE;
uint256 public override PROTOCOL_FLAT_FEE;

mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
Expand Down Expand Up @@ -176,7 +176,7 @@ contract ZRC20New is IZRC20, IZRC20Metadata, ZRC20Errors {
* @param amount, amount to burn.
* @return true/false if succeeded/failed.
*/
function burn(uint256 amount) external returns (bool) {
function burn(uint256 amount) external override returns (bool) {
_burn(msg.sender, amount);
return true;
}
Expand Down
19 changes: 19 additions & 0 deletions contracts/zevm/interfaces/ISystem.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

/**
* @dev Interfaces of SystemContract and ZRC20 to make easier to import.
*/
interface ISystem {
function FUNGIBLE_MODULE_ADDRESS() external view returns (address);

function wZetaContractAddress() external view returns (address);

function uniswapv2FactoryAddress() external view returns (address);

function gasPriceByChainId(uint256 chainID) external view returns (uint256);

function gasCoinZRC20ByChainId(uint256 chainID) external view returns (address);

function gasZetaPoolByChainId(uint256 chainID) external view returns (address);
}
38 changes: 34 additions & 4 deletions contracts/zevm/interfaces/IZRC20.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

/**
* @dev Interfaces of SystemContract and ZRC20 to make easier to import.
*/
interface ISystem {
function FUNGIBLE_MODULE_ADDRESS() external view returns (address);

function wZetaContractAddress() external view returns (address);

function uniswapv2FactoryAddress() external view returns (address);

function gasPriceByChainId(uint256 chainID) external view returns (uint256);

function gasCoinZRC20ByChainId(uint256 chainID) external view returns (address);

function gasZetaPoolByChainId(uint256 chainID) external view returns (address);
}

interface IZRC20 {
function totalSupply() external view returns (uint256);

Expand All @@ -12,10 +29,6 @@ interface IZRC20 {

function approve(address spender, uint256 amount) external returns (bool);

function decreaseAllowance(address spender, uint256 amount) external returns (bool);

function increaseAllowance(address spender, uint256 amount) external returns (bool);

function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

function deposit(address to, uint256 amount) external returns (bool);
Expand All @@ -27,7 +40,17 @@ interface IZRC20 {
function withdrawGasFee() external view returns (address, uint256);

function PROTOCOL_FLAT_FEE() external view returns (uint256);
}

interface IZRC20Metadata is IZRC20 {
function name() external view returns (string memory);

function symbol() external view returns (string memory);

function decimals() external view returns (uint8);
}

interface ZRC20Events {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event Deposit(bytes from, address indexed to, uint256 value);
Expand All @@ -36,3 +59,10 @@ interface IZRC20 {
event UpdatedGasLimit(uint256 gasLimit);
event UpdatedProtocolFlatFee(uint256 protocolFlatFee);
}

/// @dev Coin types for ZRC20. Zeta value should not be used.
enum CoinType {
Zeta,
Gas,
ERC20
}

0 comments on commit e881d7c

Please sign in to comment.