Skip to content

Commit

Permalink
feat: erc20 auth calls (#3012)
Browse files Browse the repository at this point in the history
* bump protocol contracts to use erc20 auth calls

* bump protocol contracts and fix test dapp

* rename current test to arbitrary call

* rename existing tests

* e2e test wip

* new test fix

* fix test

* fix

* PR comment

* revert staking abi change

* fmt

* changelog

* fix test

* PR comment

* PR comment

* fix test
  • Loading branch information
skosito authored Oct 18, 2024
1 parent 923b936 commit 9347165
Show file tree
Hide file tree
Showing 26 changed files with 290 additions and 323 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* [2896](https://github.com/zeta-chain/node/pull/2896) - add TON inbound observation
* [2987](https://github.com/zeta-chain/node/pull/2987) - add non-EVM standard inbound memo package
* [2979](https://github.com/zeta-chain/node/pull/2979) - add fungible keeper ability to lock/unlock ZRC20 tokens
* [3012](https://github.com/zeta-chain/node/pull/3012) - integrate authenticated calls erc20 smart contract functionality into protocol

### Refactor

Expand Down
1 change: 1 addition & 0 deletions cmd/zetae2e/local/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func startV2Tests(eg *errgroup.Group, conf config.Config, deployerRunner *runner
e2etests.TestV2ERC20DepositName,
e2etests.TestV2ERC20DepositAndCallName,
e2etests.TestV2ERC20WithdrawName,
e2etests.TestV2ERC20WithdrawAndArbitraryCallName,
e2etests.TestV2ERC20WithdrawAndCallName,
))

Expand Down
11 changes: 9 additions & 2 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ const (
TestV2ERC20DepositAndCallRevertName = "v2_erc20_deposit_and_call_revert"
TestV2ERC20DepositAndCallRevertWithCallName = "v2_erc20_deposit_and_call_revert_with_call"
TestV2ERC20WithdrawName = "v2_erc20_withdraw"
TestV2ERC20WithdrawAndArbitraryCallName = "v2_erc20_withdraw_and_arbitrary_call"
TestV2ERC20WithdrawAndCallName = "v2_erc20_withdraw_and_call"
TestV2ERC20WithdrawAndCallRevertName = "v2_erc20_withdraw_and_call_revert"
TestV2ERC20WithdrawAndCallRevertWithCallName = "v2_erc20_withdraw_and_call_revert_with_call"
Expand Down Expand Up @@ -835,11 +836,17 @@ var AllE2ETests = []runner.E2ETest{
TestV2ERC20Withdraw,
),
runner.NewE2ETest(
TestV2ERC20WithdrawAndCallName,
"withdraw ERC20 from ZEVM and call a contract using V2 contract",
TestV2ERC20WithdrawAndArbitraryCallName,
"withdraw ERC20 from ZEVM and arbitrary call a contract using V2 contract",
[]runner.ArgDefinition{
{Description: "amount", DefaultValue: "1000"},
},
TestV2ERC20WithdrawAndArbitraryCall,
),
runner.NewE2ETest(
TestV2ERC20WithdrawAndCallName,
"withdraw ERC20 from ZEVM and authenticated call a contract using V2 contract",
[]runner.ArgDefinition{},
TestV2ERC20WithdrawAndCall,
),
runner.NewE2ETest(
Expand Down
41 changes: 41 additions & 0 deletions e2e/e2etests/test_v2_erc20_withdraw_and_arbitrary_call.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package e2etests

import (
"math/big"

"github.com/stretchr/testify/require"
"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayzevm.sol"

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

const payloadMessageWithdrawERC20 = "this is a test ERC20 withdraw and call payload"

func TestV2ERC20WithdrawAndArbitraryCall(r *runner.E2ERunner, args []string) {
require.Len(r, args, 1)

amount, ok := big.NewInt(0).SetString(args[0], 10)
require.True(r, ok, "Invalid amount specified for TestV2ERC20WithdrawAndCall")

r.AssertTestDAppEVMCalled(false, payloadMessageWithdrawERC20, amount)

r.ApproveERC20ZRC20(r.GatewayZEVMAddr)
r.ApproveETHZRC20(r.GatewayZEVMAddr)

// perform the withdraw
tx := r.V2ERC20WithdrawAndArbitraryCall(
r.TestDAppV2EVMAddr,
amount,
r.EncodeERC20Call(r.ERC20Addr, amount, payloadMessageWithdrawERC20),
gatewayzevm.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, "withdraw")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)

r.AssertTestDAppEVMCalled(true, payloadMessageWithdrawERC20, amount)
}
30 changes: 22 additions & 8 deletions e2e/e2etests/test_v2_erc20_withdraw_and_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package e2etests
import (
"math/big"

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

Expand All @@ -11,15 +12,20 @@ import (
crosschaintypes "github.com/zeta-chain/node/x/crosschain/types"
)

const payloadMessageWithdrawERC20 = "this is a test ERC20 withdraw and call payload"
const payloadMessageWithdrawAuthenticatedCallERC20 = "this is a test ERC20 withdraw and authenticated call payload"

func TestV2ERC20WithdrawAndCall(r *runner.E2ERunner, args []string) {
require.Len(r, args, 1)
func TestV2ERC20WithdrawAndCall(r *runner.E2ERunner, _ []string) {
previousGasLimit := r.ZEVMAuth.GasLimit
r.ZEVMAuth.GasLimit = 10000000
defer func() {
r.ZEVMAuth.GasLimit = previousGasLimit
}()

amount, ok := big.NewInt(0).SetString(args[0], 10)
require.True(r, ok, "Invalid amount specified for TestV2ERC20WithdrawAndCall")
// called with fixed amount without arg since onCall implementation is for TestDappV2 is simple and generic
// without decoding the payload and amount handling for erc20, purpose of test is to verify correct sender and payload are used
amount := big.NewInt(10000)

r.AssertTestDAppEVMCalled(false, payloadMessageWithdrawERC20, amount)
r.AssertTestDAppEVMCalled(false, payloadMessageWithdrawAuthenticatedCallERC20, amount)

r.ApproveERC20ZRC20(r.GatewayZEVMAddr)
r.ApproveETHZRC20(r.GatewayZEVMAddr)
Expand All @@ -28,7 +34,7 @@ func TestV2ERC20WithdrawAndCall(r *runner.E2ERunner, args []string) {
tx := r.V2ERC20WithdrawAndCall(
r.TestDAppV2EVMAddr,
amount,
r.EncodeERC20Call(r.ERC20Addr, amount, payloadMessageWithdrawERC20),
[]byte(payloadMessageWithdrawAuthenticatedCallERC20),
gatewayzevm.RevertOptions{OnRevertGasLimit: big.NewInt(0)},
)

Expand All @@ -37,5 +43,13 @@ func TestV2ERC20WithdrawAndCall(r *runner.E2ERunner, args []string) {
r.Logger.CCTX(*cctx, "withdraw")
require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctx.CctxStatus.Status)

r.AssertTestDAppEVMCalled(true, payloadMessageWithdrawERC20, amount)
r.AssertTestDAppEVMCalled(true, payloadMessageWithdrawAuthenticatedCallERC20, big.NewInt(0))

// check expected sender was used
senderForMsg, err := r.TestDAppV2EVM.SenderWithMessage(
&bind.CallOpts{},
[]byte(payloadMessageWithdrawAuthenticatedCallERC20),
)
require.NoError(r, err)
require.Equal(r, r.ZEVMAuth.From, senderForMsg)
}
2 changes: 1 addition & 1 deletion e2e/e2etests/test_v2_erc20_withdraw_and_call_revert.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestV2ERC20WithdrawAndCallRevert(r *runner.E2ERunner, args []string) {
require.EqualValues(r, int64(0), balance.Int64())

// perform the withdraw
tx := r.V2ERC20WithdrawAndCall(
tx := r.V2ERC20WithdrawAndArbitraryCall(
r.TestDAppV2EVMAddr,
amount,
r.EncodeERC20CallRevert(r.ERC20Addr, amount),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestV2ERC20WithdrawAndCallRevertWithCall(r *runner.E2ERunner, args []string
r.ApproveETHZRC20(r.GatewayZEVMAddr)

// perform the withdraw
tx := r.V2ERC20WithdrawAndCall(
tx := r.V2ERC20WithdrawAndArbitraryCall(
r.TestDAppV2EVMAddr,
amount,
r.EncodeERC20CallRevert(r.ERC20Addr, amount),
Expand Down
2 changes: 1 addition & 1 deletion e2e/e2etests/test_v2_eth_withdraw_and_arbitrary_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestV2ETHWithdrawAndArbitraryCall(r *runner.E2ERunner, args []string) {
r.ApproveETHZRC20(r.GatewayZEVMAddr)

// perform the withdraw
tx := r.V2ETHWithdrawAndCall(
tx := r.V2ETHWithdrawAndArbitraryCall(
r.TestDAppV2EVMAddr,
amount,
r.EncodeGasCall(payloadMessageWithdrawETH),
Expand Down
7 changes: 1 addition & 6 deletions e2e/e2etests/test_v2_eth_withdraw_and_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,8 @@ func TestV2ETHWithdrawAndCall(r *runner.E2ERunner, args []string) {

r.ApproveETHZRC20(r.GatewayZEVMAddr)

// set expected sender
tx, err := r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout)

// perform the withdraw
tx = r.V2ETHWithdrawAndAuthenticatedCall(
tx := r.V2ETHWithdrawAndCall(
r.TestDAppV2EVMAddr,
amount,
[]byte(payloadMessageAuthenticatedWithdrawETH),
Expand Down
13 changes: 9 additions & 4 deletions e2e/e2etests/test_v2_eth_withdraw_and_call_revert.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ func TestV2ETHWithdrawAndCallRevert(r *runner.E2ERunner, args []string) {
require.EqualValues(r, int64(0), balance.Int64())

// perform the withdraw
tx := r.V2ETHWithdrawAndCall(r.TestDAppV2EVMAddr, amount, r.EncodeGasCall("revert"), gatewayzevm.RevertOptions{
RevertAddress: revertAddress,
OnRevertGasLimit: big.NewInt(0),
})
tx := r.V2ETHWithdrawAndArbitraryCall(
r.TestDAppV2EVMAddr,
amount,
r.EncodeGasCall("revert"),
gatewayzevm.RevertOptions{
RevertAddress: revertAddress,
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestV2ETHWithdrawAndCallRevertWithCall(r *runner.E2ERunner, args []string)
r.ApproveETHZRC20(r.GatewayZEVMAddr)

// perform the withdraw
tx := r.V2ETHWithdrawAndCall(
tx := r.V2ETHWithdrawAndArbitraryCall(
r.TestDAppV2EVMAddr,
amount,
r.EncodeGasCall("revert"),
Expand Down
23 changes: 1 addition & 22 deletions e2e/e2etests/test_v2_eth_withdraw_and_call_through_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,8 @@ func TestV2ETHWithdrawAndCallThroughContract(r *runner.E2ERunner, args []string)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

// set expected sender
tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, gatewayCallerAddr)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout)

// perform the authenticated call
tx = r.V2ETHWithdrawAndAuthenticatedCallThroughContract(gatewayCaller, r.TestDAppV2EVMAddr,
tx = r.V2ETHWithdrawAndCallThroughContract(gatewayCaller, r.TestDAppV2EVMAddr,
amount,
[]byte(payloadMessageAuthenticatedWithdrawETHThroughContract),
gatewayzevmcaller.RevertOptions{OnRevertGasLimit: big.NewInt(0)})
Expand All @@ -65,20 +60,4 @@ func TestV2ETHWithdrawAndCallThroughContract(r *runner.E2ERunner, args []string)
)
require.NoError(r, err)
require.Equal(r, gatewayCallerAddr, senderForMsg)

// set expected sender to wrong one
tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout)

// repeat authenticated call through contract, should revert because of wrong sender
tx = r.V2ETHWithdrawAndAuthenticatedCallThroughContract(gatewayCaller, r.TestDAppV2EVMAddr,
amount,
[]byte(payloadMessageAuthenticatedWithdrawETHThroughContract),
gatewayzevmcaller.RevertOptions{OnRevertGasLimit: big.NewInt(0)})

utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "withdraw")
require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status)
}
10 changes: 7 additions & 3 deletions e2e/e2etests/test_v2_zevm_to_evm_arbitrary_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ func TestV2ZEVMToEVMArbitraryCall(r *runner.E2ERunner, args []string) {
r.ApproveETHZRC20(r.GatewayZEVMAddr)

// perform the call
tx := r.V2ZEVMToEMVCall(r.TestDAppV2EVMAddr, r.EncodeSimpleCall(payloadMessageEVMCall), gatewayzevm.RevertOptions{
OnRevertGasLimit: big.NewInt(0),
})
tx := r.V2ZEVMToEMVArbitraryCall(
r.TestDAppV2EVMAddr,
r.EncodeSimpleCall(payloadMessageEVMCall),
gatewayzevm.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)
Expand Down
7 changes: 1 addition & 6 deletions e2e/e2etests/test_v2_zevm_to_evm_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,8 @@ func TestV2ZEVMToEVMCall(r *runner.E2ERunner, args []string) {
// necessary approval for fee payment
r.ApproveETHZRC20(r.GatewayZEVMAddr)

// set expected sender
tx, err := r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout)

// perform the authenticated call
tx = r.V2ZEVMToEMVAuthenticatedCall(
tx := r.V2ZEVMToEMVCall(
r.TestDAppV2EVMAddr,
[]byte(payloadMessageEVMAuthenticatedCall),
gatewayzevm.RevertOptions{
Expand Down
26 changes: 1 addition & 25 deletions e2e/e2etests/test_v2_zevm_to_evm_call_through_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,8 @@ func TestV2ZEVMToEVMCallThroughContract(r *runner.E2ERunner, args []string) {
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

// set expected sender
tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, gatewayCallerAddr)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout)

// perform the authenticated call
tx = r.V2ZEVMToEMVAuthenticatedCallThroughContract(
tx = r.V2ZEVMToEMVCallThroughContract(
gatewayCaller,
r.TestDAppV2EVMAddr,
[]byte(payloadMessageEVMAuthenticatedCallThroughContract),
Expand All @@ -61,23 +56,4 @@ func TestV2ZEVMToEVMCallThroughContract(r *runner.E2ERunner, args []string) {
)
require.NoError(r, err)
require.Equal(r, gatewayCallerAddr, senderForMsg)

// set expected sender to wrong one
tx, err = r.TestDAppV2EVM.SetExpectedOnCallSender(r.EVMAuth, r.ZEVMAuth.From)
require.NoError(r, err)
utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout)

// repeat authenticated call through contract, should revert because of wrong sender
tx = r.V2ZEVMToEMVAuthenticatedCallThroughContract(
gatewayCaller,
r.TestDAppV2EVMAddr,
[]byte(payloadMessageEVMAuthenticatedCallThroughContract),
gatewayzevmcaller.RevertOptions{
OnRevertGasLimit: big.NewInt(0),
},
)
utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)
cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "call")
require.Equal(r, crosschaintypes.CctxStatus_Reverted, cctx.CctxStatus.Status)
}
Loading

0 comments on commit 9347165

Please sign in to comment.