Skip to content

Commit

Permalink
test: add unit tests for crosschain evm hooks (#1787)
Browse files Browse the repository at this point in the history
* make staking keeper private

* process logs test case

* add more test cases

* add tests for parsing ZETA sent event

* add unit tests for process ZRC20 withdraw

* add more unit tests

* add changelog.md

* Update e2e/e2etests/test_bitcoin_withdraw.go

Co-authored-by: Lucas Bertrand <[email protected]>

* Update x/crosschain/keeper/evm_hooks.go

Co-authored-by: Lucas Bertrand <[email protected]>

* Update x/crosschain/keeper/evm_hooks_test.go

Co-authored-by: Lucas Bertrand <[email protected]>

* move block data to sample package

* move helpers to the top

* move withdraw for btc legacy address to a separate test

* remove invalid withdraw of 0.1 BTC

* increase approval amount

---------

Co-authored-by: Lucas Bertrand <[email protected]>
  • Loading branch information
kingpinXD and lumtis authored Mar 5, 2024
1 parent 01526a5 commit 4db8436
Show file tree
Hide file tree
Showing 9 changed files with 825 additions and 68 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

* [1767](https://github.com/zeta-chain/node/pull/1767) - add unit tests for emissions module begin blocker
* [1791](https://github.com/zeta-chain/node/pull/1791) - add e2e tests for feature of restricted address
* [1787](https://github.com/zeta-chain/node/pull/1787) - add unit tests for cross-chain evm hooks and e2e test failed withdraw to BTC legacy address

### Chores

Expand Down
1 change: 1 addition & 0 deletions cmd/zetae2e/local/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func bitcoinTestRoutine(
// to make it faster to catch up with the latest block header
if err := bitcoinRunner.RunE2ETestsFromNames(
e2etests.AllE2ETests,
e2etests.TestBitcoinWithdrawInvalidAddressName,
e2etests.TestBitcoinWithdrawName,
e2etests.TestZetaWithdrawBTCRevertName,
e2etests.TestCrosschainSwapName,
Expand Down
44 changes: 25 additions & 19 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,26 @@ import (
// TODO : Add smoke test for abort refund
// https://github.com/zeta-chain/node/issues/1745
const (
TestContextUpgradeName = "context_upgrade"
TestDepositAndCallRefundName = "deposit_and_call_refund"
TestMultipleERC20DepositName = "erc20_multiple_deposit"
TestMultipleWithdrawsName = "erc20_multiple_withdraw"
TestZetaWithdrawName = "zeta_withdraw"
TestZetaWithdrawBTCRevertName = "zeta_withdraw_btc_revert" // #nosec G101 - not a hardcoded password
TestMessagePassingName = "message_passing"
TestZRC20SwapName = "zrc20_swap"
TestBitcoinWithdrawName = "bitcoin_withdraw"
TestBitcoinWithdrawRestrictedName = "bitcoin_withdraw_restricted"
TestCrosschainSwapName = "crosschain_swap"
TestMessagePassingRevertFailName = "message_passing_revert_fail"
TestMessagePassingRevertSuccessName = "message_passing_revert_success"
TestPauseZRC20Name = "pause_zrc20"
TestERC20DepositAndCallRefundName = "erc20_deposit_and_call_refund"
TestUpdateBytecodeName = "update_bytecode"
TestEtherDepositAndCallName = "eth_deposit_and_call"
TestDepositEtherLiquidityCapName = "deposit_eth_liquidity_cap"
TestMyTestName = "my_test"
TestContextUpgradeName = "context_upgrade"
TestDepositAndCallRefundName = "deposit_and_call_refund"
TestMultipleERC20DepositName = "erc20_multiple_deposit"
TestMultipleWithdrawsName = "erc20_multiple_withdraw"
TestZetaWithdrawName = "zeta_withdraw"
TestZetaWithdrawBTCRevertName = "zeta_withdraw_btc_revert" // #nosec G101 - not a hardcoded password
TestMessagePassingName = "message_passing"
TestZRC20SwapName = "zrc20_swap"
TestBitcoinWithdrawName = "bitcoin_withdraw"
TestBitcoinWithdrawInvalidAddressName = "bitcoin_withdraw_invalid"
TestBitcoinWithdrawRestrictedName = "bitcoin_withdraw_restricted"
TestCrosschainSwapName = "crosschain_swap"
TestMessagePassingRevertFailName = "message_passing_revert_fail"
TestMessagePassingRevertSuccessName = "message_passing_revert_success"
TestPauseZRC20Name = "pause_zrc20"
TestERC20DepositAndCallRefundName = "erc20_deposit_and_call_refund"
TestUpdateBytecodeName = "update_bytecode"
TestEtherDepositAndCallName = "eth_deposit_and_call"
TestDepositEtherLiquidityCapName = "deposit_eth_liquidity_cap"
TestMyTestName = "my_test"

TestERC20WithdrawName = "erc20_withdraw"
TestERC20DepositName = "erc20_deposit"
Expand Down Expand Up @@ -103,6 +104,11 @@ var AllE2ETests = []runner.E2ETest{
"withdraw BTC from ZEVM",
TestBitcoinWithdraw,
},
{
TestBitcoinWithdrawInvalidAddressName,
"withdraw BTC from ZEVM to an unsupported btc address",
TestBitcoinWithdrawToInvalidAddress,
},
{
TestCrosschainSwapName,
"testing Bitcoin ERC20 cross-chain swap",
Expand Down
45 changes: 45 additions & 0 deletions e2e/e2etests/test_bitcoin_withdraw_invalid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package e2etests

import (
"fmt"
"math/big"

"github.com/btcsuite/btcutil"
"github.com/zeta-chain/zetacore/e2e/runner"
"github.com/zeta-chain/zetacore/e2e/utils"
)

func TestBitcoinWithdrawToInvalidAddress(r *runner.E2ERunner) {
WithdrawToInvalidAddress(r)
}

func WithdrawToInvalidAddress(r *runner.E2ERunner) {

amount := big.NewInt(0.00001 * btcutil.SatoshiPerBitcoin)
approvalAmount := 1000000000000000000
// approve the ZRC20 contract to spend approvalAmount BTC from the deployer address.
// the actual amount transferred is 0.00001 BTC, but we approve more to cover withdraw fee
tx, err := r.BTCZRC20.Approve(r.ZevmAuth, r.BTCZRC20Addr, big.NewInt(int64(approvalAmount)))
if err != nil {
panic(err)
}
receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZevmClient, tx, r.Logger, r.ReceiptTimeout)
if receipt.Status != 1 {
panic(fmt.Errorf("approve receipt status is not 1"))
}

// mine blocks
stop := r.MineBlocks()

// withdraw 0.00001 BTC from ZRC20 to BTC legacy address
tx, err = r.BTCZRC20.Withdraw(r.ZevmAuth, []byte("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3"), amount)
if err != nil {
panic(err)
}
receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZevmClient, tx, r.Logger, r.ReceiptTimeout)
if receipt.Status == 1 {
panic(fmt.Errorf("withdraw receipt status is successful for an invalid BTC address"))
}
// stop mining
stop <- struct{}{}
}
2 changes: 1 addition & 1 deletion testutil/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import (
func NewContext(stateStore sdk.CommitMultiStore) sdk.Context {
header := tmproto.Header{
Height: 1,
ChainID: "test_1-1",
ChainID: "test_7000-1",
Time: time.Now().UTC(),
LastBlockId: tmproto.BlockID{
Hash: tmhash.Sum([]byte("block_id")),
Expand Down
34 changes: 34 additions & 0 deletions testutil/sample/crosschain.go

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions x/crosschain/keeper/evm_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ func (k Keeper) ProcessLogs(ctx sdk.Context, logs []*ethtypes.Log, emittingContr
if connectorZEVMAddr == (ethcommon.Address{}) {
return fmt.Errorf("connectorZEVM address is empty")
}

for _, log := range logs {
eventZrc20Withdrawal, errZrc20 := ParseZRC20WithdrawalEvent(*log)
eventZetaSent, errZetaSent := ParseZetaSentEvent(*log, connectorZEVMAddr)
Expand Down Expand Up @@ -103,6 +102,7 @@ func (k Keeper) ProcessLogs(ctx sdk.Context, logs []*ethtypes.Log, emittingContr
ctx.Logger().Info(fmt.Sprintf("cannot find foreign coin with contract address %s", eventZrc20Withdrawal.Raw.Address.Hex()))
continue
}

// If Validation fails, we will not process the event and return and error. This condition means that the event was correct, and emitted from a registered ZRC20 contract
// But the information entered by the user is incorrect. In this case we can return an error and roll back the transaction
if err := ValidateZrc20WithdrawEvent(eventZrc20Withdrawal, coin.ForeignChainId); err != nil {
Expand Down Expand Up @@ -133,8 +133,10 @@ func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20W
if !found {
return fmt.Errorf("cannot find foreign coin with emittingContract address %s", event.Raw.Address.Hex())
}

receiverChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, foreignCoin.ForeignChainId)
if receiverChain == nil {
return errorsmod.Wrapf(observertypes.ErrSupportedChains, "chain with chainID %d not supported", foreignCoin.ForeignChainId)
}
senderChain, err := common.ZetaChainFromChainID(ctx.ChainID())
if err != nil {
return fmt.Errorf("ProcessZRC20WithdrawalEvent: failed to convert chainID: %s", err.Error())
Expand Down
Loading

0 comments on commit 4db8436

Please sign in to comment.