Skip to content

Commit

Permalink
add v2 deposit and call with swap test
Browse files Browse the repository at this point in the history
  • Loading branch information
skosito committed Nov 20, 2024
1 parent 9d299f0 commit 42cc396
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 4 deletions.
1 change: 1 addition & 0 deletions cmd/zetae2e/local/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func startV2Tests(eg *errgroup.Group, conf config.Config, deployerRunner *runner
e2etests.TestV2ERC20WithdrawAndCallName,
e2etests.TestV2ERC20DepositAndCallNoMessageName,
e2etests.TestV2ERC20WithdrawAndCallNoMessageName,
e2etests.TestV2DepositAndCallSwapName,
))

// Test revert cases for gas token workflow
Expand Down
45 changes: 45 additions & 0 deletions e2e/contracts/zevmswap/ZEVMSwapApp.abi
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,51 @@
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "bytes",
"name": "origin",
"type": "bytes"
},
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint256",
"name": "chainID",
"type": "uint256"
}
],
"internalType": "struct Context",
"name": "",
"type": "tuple"
},
{
"internalType": "address",
"name": "zrc20",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "message",
"type": "bytes"
}
],
"name": "onCall",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down
2 changes: 1 addition & 1 deletion e2e/contracts/zevmswap/ZEVMSwapApp.bin

Large diffs are not rendered by default.

25 changes: 23 additions & 2 deletions e2e/contracts/zevmswap/ZEVMSwapApp.go

Large diffs are not rendered by default.

47 changes: 46 additions & 1 deletion e2e/contracts/zevmswap/ZEVMSwapApp.json

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions e2e/contracts/zevmswap/ZEVMSwapApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,28 @@ contract ZEVMSwapApp is zContract {
IZRC20(targetZRC20).approve(address(targetZRC20), amounts[1]*10);
IZRC20(targetZRC20).withdraw(recipient, amounts[1]);
}

// used with v2 contracts
function onCall(Context calldata, address zrc20, uint256 amount, bytes calldata message) external {
address targetZRC20;
bytes memory recipient;
address[] memory path;

(targetZRC20, recipient) = decodeMemo(message);
path = new address[](2);
path[0] = zrc20;
path[1] = targetZRC20;

// approve the usage of this token by router02
IZRC20(zrc20).approve(address(router02), amount);

// swap for target token
uint256[] memory amounts = IUniswapV2Router02(router02).swapExactTokensForTokens(amount, 0, path, address(this), _DEADLINE);

// perform withdrawal with the target token
(address gasZRC20Addr,uint256 gasFee) = IZRC20(targetZRC20).withdrawGasFee();
IZRC20(gasZRC20Addr).approve(address(targetZRC20), gasFee);
IZRC20(targetZRC20).approve(address(targetZRC20), amounts[1]*10);
IZRC20(targetZRC20).withdraw(recipient, amounts[1]);
}
}
7 changes: 7 additions & 0 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ const (
TestV2ZEVMToEVMCallName = "v2_zevm_to_evm_call"
TestV2ZEVMToEVMCallThroughContractName = "v2_zevm_to_evm_call_through_contract"
TestV2EVMToZEVMCallName = "v2_evm_to_zevm_call"
TestV2DepositAndCallSwapName = "v2_deposit_and_call_swap_name"

/*
Operational tests
Expand Down Expand Up @@ -1066,6 +1067,12 @@ var AllE2ETests = []runner.E2ETest{
[]runner.ArgDefinition{},
TestV2EVMToZEVMCall,
),
runner.NewE2ETest(
TestV2DepositAndCallSwapName,
"evm -> zevm deposit and call with swap and withdraw",
[]runner.ArgDefinition{},
TestV2DepositAndCallSwap,
),
/*
Special tests
*/
Expand Down
88 changes: 88 additions & 0 deletions e2e/e2etests/test_v2_deposit_and_call_swap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package e2etests

import (
"math/big"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol"

"github.com/zeta-chain/node/e2e/runner"
"github.com/zeta-chain/node/e2e/utils"
crosschaintypes "github.com/zeta-chain/node/x/crosschain/types"
)

// TODO: This test is similar to TestCrosschainSwap
// purpose is to test similar scenario with v2 contracts where there is swap + withdraw in onCall
// to showcase that it's not reverting with gas limit issues
// this test should be removed when this issue is completed: https://github.com/zeta-chain/node/issues/2711
func TestV2DepositAndCallSwap(r *runner.E2ERunner, _ []string) {
// create tokens pair (erc20 and eth)
tx, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.ETHZRC20Addr)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

// approve router to spend tokens being swapped
tx, err = r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18))
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

tx, err = r.ETHZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18))
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

// fund ZEVMSwapApp with gas ZRC20s for withdraw
tx, err = r.ETHZRC20.Transfer(r.ZEVMAuth, r.ZEVMSwapAppAddr, big.NewInt(1e10))
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

tx, err = r.ERC20ZRC20.Transfer(r.ZEVMAuth, r.ZEVMSwapAppAddr, big.NewInt(1e6))
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

// temporarily increase gas limit to 400000
previousGasLimit := r.ZEVMAuth.GasLimit
defer func() {
r.ZEVMAuth.GasLimit = previousGasLimit
}()

// add liquidity for swap
r.ZEVMAuth.GasLimit = 400000
tx, err = r.UniswapV2Router.AddLiquidity(
r.ZEVMAuth,
r.ERC20ZRC20Addr,
r.ETHZRC20Addr,
big.NewInt(1e8),
big.NewInt(1e8),
big.NewInt(1e8),
big.NewInt(1e5),
r.EVMAddress(),
big.NewInt(time.Now().Add(10*time.Minute).Unix()),
)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

// memobytes is dApp specific; see the contracts/ZEVMSwapApp.sol for details
// it is [targetZRC20, receiver]
memobytes, err := r.ZEVMSwapApp.EncodeMemo(
&bind.CallOpts{},
r.ETHZRC20Addr,
r.EVMAddress().Bytes(),
)
require.NoError(r, err)

// perform the deposit and call
r.ApproveERC20OnEVM(r.GatewayEVMAddr)
tx = r.V2ERC20DepositAndCall(
r.ZEVMSwapAppAddr,
big.NewInt(8e7),
memobytes,
gatewayevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)},
)

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit_and_call")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)
}

0 comments on commit 42cc396

Please sign in to comment.