Skip to content

Commit

Permalink
test: e2e tests for zetaclient restricted addresses (#1791)
Browse files Browse the repository at this point in the history
* initiated feature of zetaclient-banned-address

* fix some issues in e2e tests

* added e2e tests for banned addresses

* fix gosec issues

* some unit tests, comments and refactor

* unified log prints for restricted address detection

* renamed tests and variables

* move restricted address to Unreleased section

* move restricted address to Unreleased section

* improved compliance log prints

* removed unnecessary tests and made bitcoin withdrawal to restricted address a separate test

* made OFAC tests separate and moved them to bottom of list

* fix nosec false positive
  • Loading branch information
ws4charlie authored Mar 4, 2024
1 parent 85eda62 commit fcbb639
Show file tree
Hide file tree
Showing 15 changed files with 140 additions and 25 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
### Tests

* [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

### 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 @@ -69,6 +69,7 @@ func bitcoinTestRoutine(
e2etests.TestBitcoinWithdrawName,
e2etests.TestZetaWithdrawBTCRevertName,
e2etests.TestCrosschainSwapName,
e2etests.TestBitcoinWithdrawRestrictedName,
); err != nil {
return fmt.Errorf("bitcoin tests failed: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions cmd/zetae2e/local/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func erc20TestRoutine(
e2etests.TestMultipleWithdrawsName,
e2etests.TestERC20DepositAndCallRefundName,
e2etests.TestZRC20SwapName,
e2etests.TestERC20DepositRestrictedName,
); err != nil {
return fmt.Errorf("erc20 tests failed: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions cmd/zetae2e/local/ethereum.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func ethereumTestRoutine(
e2etests.TestContextUpgradeName,
e2etests.TestEtherDepositAndCallName,
e2etests.TestDepositAndCallRefundName,
e2etests.TestEtherWithdrawRestrictedName,
); err != nil {
return fmt.Errorf("ethereum tests failed: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions cmd/zetae2e/local/zeta.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func zetaTestRoutine(
e2etests.TestMessagePassingName,
e2etests.TestMessagePassingRevertFailName,
e2etests.TestMessagePassingRevertSuccessName,
e2etests.TestZetaDepositRestrictedName,
); err != nil {
return fmt.Errorf("zeta tests failed: %v", err)
}
Expand Down
37 changes: 31 additions & 6 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
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"
Expand All @@ -26,12 +27,16 @@ const (
TestDepositEtherLiquidityCapName = "deposit_eth_liquidity_cap"
TestMyTestName = "my_test"

TestERC20WithdrawName = "erc20_withdraw"
TestERC20DepositName = "erc20_deposit"
TestEtherDepositName = "eth_deposit"
TestEtherWithdrawName = "eth_withdraw"
TestBitcoinDepositName = "bitcoin_deposit"
TestZetaDepositName = "zeta_deposit"
TestERC20WithdrawName = "erc20_withdraw"
TestERC20DepositName = "erc20_deposit"
// #nosec G101: Potential hardcoded credentials (gosec), not a credential
TestERC20DepositRestrictedName = "erc20_deposit_restricted"
TestEtherDepositName = "eth_deposit"
TestEtherWithdrawName = "eth_withdraw"
TestEtherWithdrawRestrictedName = "eth_withdraw_restricted"
TestBitcoinDepositName = "bitcoin_deposit"
TestZetaDepositName = "zeta_deposit"
TestZetaDepositRestrictedName = "zeta_deposit_restricted"

TestDonationEtherName = "donation_ether"

Expand Down Expand Up @@ -188,4 +193,24 @@ var AllE2ETests = []runner.E2ETest{
"stress test BTC deposit",
TestStressBTCDeposit,
},
{
TestZetaDepositRestrictedName,
"deposit ZETA from Ethereum to ZEVM restricted address",
TestZetaDepositRestricted,
},
{
TestERC20DepositRestrictedName,
"deposit ERC20 into ZEVM restricted address",
TestERC20DepositRestricted,
},
{
TestEtherWithdrawRestrictedName,
"withdraw Ether from ZEVM to restricted address",
TestEtherWithdrawRestricted,
},
{
TestBitcoinWithdrawRestrictedName,
"withdraw Bitcoin from ZEVM to restricted address",
TestBitcoinWithdrawRestricted,
},
}
44 changes: 36 additions & 8 deletions e2e/e2etests/test_bitcoin_withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,27 @@ import (
"fmt"
"math/big"

"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil"
"github.com/zeta-chain/zetacore/common"
"github.com/zeta-chain/zetacore/e2e/runner"
"github.com/zeta-chain/zetacore/e2e/utils"
"github.com/zeta-chain/zetacore/zetaclient/testutils"
)

func TestBitcoinWithdraw(r *runner.E2ERunner) {
// withdraw 0.1 BTC from ZRC20 to BTC address
// first, approve the ZRC20 contract to spend 1 BTC from the deployer address
// withdraw 0.01 BTC from ZRC20 to BTC address
WithdrawBitcoin(r)
}

func WithdrawBitcoin(r *runner.E2ERunner) {
amount := big.NewInt(0.1 * btcutil.SatoshiPerBitcoin)
func TestBitcoinWithdrawRestricted(r *runner.E2ERunner) {
// withdraw 0.01 BTC from ZRC20 to BTC restricted address
WithdrawBitcoinRestricted(r)
}

// approve the ZRC20 contract to spend 1 BTC from the deployer address
func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) *btcjson.TxRawResult {
// approve the ZRC20 contract to spend 'amount' of BTC from the deployer address
tx, err := r.BTCZRC20.Approve(r.ZevmAuth, r.BTCZRC20Addr, big.NewInt(amount.Int64()*2)) // approve more to cover withdraw fee
if err != nil {
panic(err)
Expand All @@ -32,8 +37,8 @@ func WithdrawBitcoin(r *runner.E2ERunner) {
// mine blocks
stop := r.MineBlocks()

// withdraw 0.1 BTC from ZRC20 to BTC address
tx, err = r.BTCZRC20.Withdraw(r.ZevmAuth, []byte(r.BTCDeployerAddress.EncodeAddress()), amount)
// withdraw 'amount' of BTC from ZRC20 to BTC address
tx, err = r.BTCZRC20.Withdraw(r.ZevmAuth, []byte(to.EncodeAddress()), amount)
if err != nil {
panic(err)
}
Expand All @@ -43,7 +48,7 @@ func WithdrawBitcoin(r *runner.E2ERunner) {
}

// mine 10 blocks to confirm the withdraw tx
_, err = r.BtcRPCClient.GenerateToAddress(10, r.BTCDeployerAddress, nil)
_, err = r.BtcRPCClient.GenerateToAddress(10, to, nil)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -75,6 +80,29 @@ func WithdrawBitcoin(r *runner.E2ERunner) {

// stop mining
stop <- struct{}{}

return rawTx
}

func WithdrawBitcoin(r *runner.E2ERunner) {
amount := big.NewInt(0.01 * btcutil.SatoshiPerBitcoin)
withdrawBTCZRC20(r, r.BTCDeployerAddress, amount)
}

func WithdrawBitcoinRestricted(r *runner.E2ERunner) {
amount := big.NewInt(0.01 * btcutil.SatoshiPerBitcoin)

// use restricted BTC P2WPKH address
addressRestricted, err := common.DecodeBtcAddress(testutils.RestrictedBtcAddressTest, common.BtcRegtestChain().ChainId)
if err != nil {
panic(err)
}

// the cctx should be cancelled
rawTx := withdrawBTCZRC20(r, addressRestricted, amount)
if len(rawTx.Vout) != 2 {
panic(fmt.Errorf("BTC cancelled outtx rawTx.Vout should have 2 outputs"))
}
}

// WithdrawBitcoinMultipleTimes ...
Expand Down
2 changes: 1 addition & 1 deletion e2e/e2etests/test_crosschain_swap.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func TestCrosschainSwap(r *runner.E2ERunner) {

r.Logger.Info("***** First test: USDT -> BTC")
// Should deposit USDT for swap, swap for BTC and withdraw BTC
txHash := r.DepositERC20WithAmountAndMessage(big.NewInt(8e7), msg)
txHash := r.DepositERC20WithAmountAndMessage(r.DeployerAddress, big.NewInt(8e7), msg)
cctx1 := utils.WaitCctxMinedByInTxHash(r.Ctx, txHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)

// check the cctx status
Expand Down
9 changes: 8 additions & 1 deletion e2e/e2etests/test_erc20_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@ package e2etests
import (
"math/big"

ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/zeta-chain/zetacore/e2e/runner"
"github.com/zeta-chain/zetacore/e2e/utils"
"github.com/zeta-chain/zetacore/zetaclient/testutils"
)

func TestERC20Deposit(r *runner.E2ERunner) {
hash := r.DepositERC20WithAmountAndMessage(big.NewInt(100000), []byte{})
hash := r.DepositERC20WithAmountAndMessage(r.DeployerAddress, big.NewInt(100000), []byte{})

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, hash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit")
}

func TestERC20DepositRestricted(r *runner.E2ERunner) {
// deposit ERC20 to restricted address
r.DepositERC20WithAmountAndMessage(ethcommon.HexToAddress(testutils.RestrictedEVMAddressTest), big.NewInt(100000), []byte{})
}
2 changes: 1 addition & 1 deletion e2e/e2etests/test_erc20_refund.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func TestERC20DepositAndCallRefund(r *runner.E2ERunner) {

func createZetaERC20LiquidityPool(r *runner.E2ERunner) error {
amount := big.NewInt(1e10)
txHash := r.DepositERC20WithAmountAndMessage(amount, []byte{})
txHash := r.DepositERC20WithAmountAndMessage(r.DeployerAddress, amount, []byte{})
utils.WaitCctxMinedByInTxHash(r.Ctx, txHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)

tx, err := r.USDTZRC20.Approve(r.ZevmAuth, r.UniswapV2RouterAddr, big.NewInt(1e10))
Expand Down
43 changes: 43 additions & 0 deletions e2e/e2etests/test_eth_withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package e2etests
import (
"math/big"

ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/zeta-chain/zetacore/e2e/runner"
"github.com/zeta-chain/zetacore/e2e/utils"
crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types"
"github.com/zeta-chain/zetacore/zetaclient/testutils"
)

// TestEtherWithdraw tests the withdraw of ether
Expand Down Expand Up @@ -44,3 +46,44 @@ func TestEtherWithdraw(r *runner.E2ERunner) {
panic("cctx status is not outbound mined")
}
}

// TestEtherWithdrawRestricted tests the withdrawal to a restricted receiver address
func TestEtherWithdrawRestricted(r *runner.E2ERunner) {
// approve
tx, err := r.ETHZRC20.Approve(r.ZevmAuth, r.ETHZRC20Addr, big.NewInt(1e18))
if err != nil {
panic(err)
}
r.Logger.EVMTransaction(*tx, "approve")

receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZevmClient, tx, r.Logger, r.ReceiptTimeout)
if receipt.Status == 0 {
panic("approve failed")
}
r.Logger.EVMReceipt(*receipt, "approve")

// withdraw
restrictedAddress := ethcommon.HexToAddress(testutils.RestrictedEVMAddressTest)
tx, err = r.ETHZRC20.Withdraw(r.ZevmAuth, restrictedAddress.Bytes(), big.NewInt(100000))
if err != nil {
panic(err)
}
r.Logger.EVMTransaction(*tx, "withdraw to restricted address")

receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZevmClient, tx, r.Logger, r.ReceiptTimeout)
if receipt.Status == 0 {
panic("withdraw failed")
}
r.Logger.EVMReceipt(*receipt, "withdraw")
r.Logger.ZRC20Withdrawal(r.ETHZRC20, *receipt, "withdraw")

// verify the withdraw value
cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "withdraw")
if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined {
panic("cctx status is not outbound mined")
}

// the cctx should be cancelled with zero value
verifyTransferAmountFromCCTX(r, cctx, 0)
}
2 changes: 1 addition & 1 deletion e2e/e2etests/test_stress_eth_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestStressEtherDeposit(r *runner.E2ERunner) {
// send the deposits
for i := 0; i < numDeposits; i++ {
i := i
hash := r.DepositERC20WithAmountAndMessage(big.NewInt(100000), []byte{})
hash := r.DepositERC20WithAmountAndMessage(r.DeployerAddress, big.NewInt(100000), []byte{})
r.Logger.Print("index %d: starting deposit, tx hash: %s", i, hash.Hex())

eg.Go(func() error {
Expand Down
9 changes: 8 additions & 1 deletion e2e/e2etests/test_zeta_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ package e2etests
import (
"math/big"

ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/zeta-chain/zetacore/e2e/runner"
"github.com/zeta-chain/zetacore/e2e/utils"
"github.com/zeta-chain/zetacore/zetaclient/testutils"
)

func TestZetaDeposit(r *runner.E2ERunner) {
// Deposit 1 Zeta
hash := r.DepositZetaWithAmount(big.NewInt(1e18))
hash := r.DepositZetaWithAmount(r.DeployerAddress, big.NewInt(1e18))

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, hash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit")
}

func TestZetaDepositRestricted(r *runner.E2ERunner) {
// Deposit 1 Zeta to restricted address
r.DepositZetaWithAmount(ethcommon.HexToAddress(testutils.RestrictedEVMAddressTest), big.NewInt(1e18))
}
6 changes: 3 additions & 3 deletions e2e/runner/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ func (runner *E2ERunner) SendUSDTOnEvm(address ethcommon.Address, amountUSDT int
func (runner *E2ERunner) DepositERC20() ethcommon.Hash {
runner.Logger.Print("⏳ depositing ERC20 into ZEVM")

return runner.DepositERC20WithAmountAndMessage(big.NewInt(1e18), []byte{})
return runner.DepositERC20WithAmountAndMessage(runner.DeployerAddress, big.NewInt(1e18), []byte{})
}

func (runner *E2ERunner) DepositERC20WithAmountAndMessage(amount *big.Int, msg []byte) ethcommon.Hash {
func (runner *E2ERunner) DepositERC20WithAmountAndMessage(to ethcommon.Address, amount *big.Int, msg []byte) ethcommon.Hash {
// reset allowance, necessary for USDT
tx, err := runner.USDTERC20.Approve(runner.GoerliAuth, runner.ERC20CustodyAddr, big.NewInt(0))
if err != nil {
Expand All @@ -97,7 +97,7 @@ func (runner *E2ERunner) DepositERC20WithAmountAndMessage(amount *big.Int, msg [
}
runner.Logger.Info("USDT Approve receipt tx hash: %s", tx.Hash().Hex())

tx, err = runner.ERC20Custody.Deposit(runner.GoerliAuth, runner.DeployerAddress.Bytes(), runner.USDTERC20Addr, amount, msg)
tx, err = runner.ERC20Custody.Deposit(runner.GoerliAuth, to.Bytes(), runner.USDTERC20Addr, amount, msg)
runner.Logger.Print("TX: %v", tx)
if err != nil {
panic(err)
Expand Down
6 changes: 3 additions & 3 deletions e2e/runner/zeta.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ func (runner *E2ERunner) DepositZeta() ethcommon.Hash {
amount := big.NewInt(1e18)
amount = amount.Mul(amount, big.NewInt(100)) // 100 Zeta

return runner.DepositZetaWithAmount(amount)
return runner.DepositZetaWithAmount(runner.DeployerAddress, amount)
}

// DepositZetaWithAmount deposits ZETA on ZetaChain from the ZETA smart contract on EVM with the specified amount
func (runner *E2ERunner) DepositZetaWithAmount(amount *big.Int) ethcommon.Hash {
func (runner *E2ERunner) DepositZetaWithAmount(to ethcommon.Address, amount *big.Int) ethcommon.Hash {
tx, err := runner.ZetaEth.Approve(runner.GoerliAuth, runner.ConnectorEthAddr, amount)
if err != nil {
panic(err)
Expand All @@ -78,7 +78,7 @@ func (runner *E2ERunner) DepositZetaWithAmount(amount *big.Int) ethcommon.Hash {
// TODO: allow user to specify destination chain id
// https://github.com/zeta-chain/node-private/issues/41
DestinationChainId: zetaChainID,
DestinationAddress: runner.DeployerAddress.Bytes(),
DestinationAddress: to.Bytes(),
DestinationGasLimit: big.NewInt(250_000),
Message: nil,
ZetaValueAndGas: amount,
Expand Down

0 comments on commit fcbb639

Please sign in to comment.