From a6e845a19e48c31623be50ea63c43394ad7360ef Mon Sep 17 00:00:00 2001 From: Charlie Chen Date: Thu, 20 Jun 2024 13:56:16 -0500 Subject: [PATCH 1/7] set 1000 sats as minimum amount that can be withdrawn --- x/crosschain/keeper/evm_hooks.go | 3 ++- x/crosschain/keeper/evm_hooks_test.go | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index 863bdd991b..fc472652f4 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -20,6 +20,7 @@ import ( "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/coin" + "github.com/zeta-chain/zetacore/pkg/constant" "github.com/zeta-chain/zetacore/x/crosschain/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" @@ -327,7 +328,7 @@ func ValidateZrc20WithdrawEvent(event *zrc20.ZRC20Withdrawal, chainID int64) err // The event was parsed; that means the user has deposited tokens to the contract. if chains.IsBitcoinChain(chainID) { - if event.Value.Cmp(big.NewInt(0)) <= 0 { + if event.Value.Cmp(big.NewInt(constant.BTCWithdrawalDustAmount)) <= 0 { return fmt.Errorf("ParseZRC20WithdrawalEvent: invalid amount %s", event.Value.String()) } addr, err := chains.DecodeBtcAddress(string(event.To), chainID) diff --git a/x/crosschain/keeper/evm_hooks_test.go b/x/crosschain/keeper/evm_hooks_test.go index 80f8c3b28b..b2e9ef1abe 100644 --- a/x/crosschain/keeper/evm_hooks_test.go +++ b/x/crosschain/keeper/evm_hooks_test.go @@ -15,6 +15,7 @@ import ( "github.com/zeta-chain/zetacore/cmd/zetacored/config" "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/pkg/constant" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" crosschainkeeper "github.com/zeta-chain/zetacore/x/crosschain/keeper" @@ -169,7 +170,9 @@ func TestValidateZrc20WithdrawEvent(t *testing.T) { *sample.GetValidZRC20WithdrawToBTC(t).Logs[3], ) require.NoError(t, err) - btcMainNetWithdrawalEvent.Value = big.NewInt(0) + + // 1000 satoshis is the minimum amount that can be withdrawn + btcMainNetWithdrawalEvent.Value = big.NewInt(constant.BTCWithdrawalDustAmount - 1) err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BitcoinMainnet.ChainId) require.ErrorContains(t, err, "ParseZRC20WithdrawalEvent: invalid amount") }) From 78d03820451528a2b381ae5d4d42db04b05e05ef Mon Sep 17 00:00:00 2001 From: Charlie Chen Date: Thu, 20 Jun 2024 14:01:33 -0500 Subject: [PATCH 2/7] added changelog entry --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 2f15b653ba..6611a74426 100644 --- a/changelog.md +++ b/changelog.md @@ -72,6 +72,7 @@ * [2243](https://github.com/zeta-chain/node/pull/2243) - fix incorrect bitcoin outbound height in the CCTX outbound parameter * [2256](https://github.com/zeta-chain/node/pull/2256) - fix rate limiter falsely included reverted non-withdraw cctxs * [2327](https://github.com/zeta-chain/node/pull/2327) - partially cherry picked the fix to Bitcoin outbound dust amount +* [2362](https://github.com/zeta-chain/node/pull/2362) - set 1000 satoshis as minimum BTC amount that can be withdrawn from zEVM ### CI From ca9dad93871ea915fc182d4ba6f1d2087daff6ef Mon Sep 17 00:00:00 2001 From: Charlie Chen Date: Thu, 20 Jun 2024 14:09:11 -0500 Subject: [PATCH 3/7] allow 1000 satoshis to be withdrawn --- x/crosschain/keeper/evm_hooks.go | 2 +- x/crosschain/keeper/evm_hooks_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index fc472652f4..ac2a5165fc 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -328,7 +328,7 @@ func ValidateZrc20WithdrawEvent(event *zrc20.ZRC20Withdrawal, chainID int64) err // The event was parsed; that means the user has deposited tokens to the contract. if chains.IsBitcoinChain(chainID) { - if event.Value.Cmp(big.NewInt(constant.BTCWithdrawalDustAmount)) <= 0 { + if event.Value.Cmp(big.NewInt(constant.BTCWithdrawalDustAmount)) < 0 { return fmt.Errorf("ParseZRC20WithdrawalEvent: invalid amount %s", event.Value.String()) } addr, err := chains.DecodeBtcAddress(string(event.To), chainID) diff --git a/x/crosschain/keeper/evm_hooks_test.go b/x/crosschain/keeper/evm_hooks_test.go index b2e9ef1abe..5518595a36 100644 --- a/x/crosschain/keeper/evm_hooks_test.go +++ b/x/crosschain/keeper/evm_hooks_test.go @@ -172,6 +172,11 @@ func TestValidateZrc20WithdrawEvent(t *testing.T) { require.NoError(t, err) // 1000 satoshis is the minimum amount that can be withdrawn + btcMainNetWithdrawalEvent.Value = big.NewInt(constant.BTCWithdrawalDustAmount) + err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BitcoinMainnet.ChainId) + require.NoError(t, err) + + // 999 satoshis cannot be withdrawn btcMainNetWithdrawalEvent.Value = big.NewInt(constant.BTCWithdrawalDustAmount - 1) err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BitcoinMainnet.ChainId) require.ErrorContains(t, err, "ParseZRC20WithdrawalEvent: invalid amount") From 7b122ebee5b2067759cf95fd2594becd0cb7a576 Mon Sep 17 00:00:00 2001 From: Charlie Chen Date: Thu, 20 Jun 2024 15:30:03 -0500 Subject: [PATCH 4/7] added minimum withdraw amount to error message --- x/crosschain/keeper/evm_hooks.go | 3 ++- x/crosschain/keeper/evm_hooks_test.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index ac2a5165fc..fb6e129cd6 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -329,7 +329,8 @@ func ValidateZrc20WithdrawEvent(event *zrc20.ZRC20Withdrawal, chainID int64) err if chains.IsBitcoinChain(chainID) { if event.Value.Cmp(big.NewInt(constant.BTCWithdrawalDustAmount)) < 0 { - return fmt.Errorf("ParseZRC20WithdrawalEvent: invalid amount %s", event.Value.String()) + return fmt.Errorf("ParseZRC20WithdrawalEvent: withdraw amount %s is less than minimum amount %d", + event.Value.String(), constant.BTCWithdrawalDustAmount) } addr, err := chains.DecodeBtcAddress(string(event.To), chainID) if err != nil { diff --git a/x/crosschain/keeper/evm_hooks_test.go b/x/crosschain/keeper/evm_hooks_test.go index 5518595a36..60367745eb 100644 --- a/x/crosschain/keeper/evm_hooks_test.go +++ b/x/crosschain/keeper/evm_hooks_test.go @@ -179,7 +179,7 @@ func TestValidateZrc20WithdrawEvent(t *testing.T) { // 999 satoshis cannot be withdrawn btcMainNetWithdrawalEvent.Value = big.NewInt(constant.BTCWithdrawalDustAmount - 1) err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BitcoinMainnet.ChainId) - require.ErrorContains(t, err, "ParseZRC20WithdrawalEvent: invalid amount") + require.ErrorContains(t, err, "less than minimum amount") }) t.Run("unable to validate a event with an invalid chain ID", func(t *testing.T) { From 28973eaa3086ba0cbfafcddf5ad78c09efa9386b Mon Sep 17 00:00:00 2001 From: Charlie Chen Date: Thu, 20 Jun 2024 17:06:33 -0500 Subject: [PATCH 5/7] define an error for invalid withdrawal amount --- x/crosschain/keeper/evm_hooks.go | 6 +++--- x/crosschain/keeper/evm_hooks_test.go | 2 +- x/crosschain/types/errors.go | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index fb6e129cd6..3ead05e604 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -329,15 +329,15 @@ func ValidateZrc20WithdrawEvent(event *zrc20.ZRC20Withdrawal, chainID int64) err if chains.IsBitcoinChain(chainID) { if event.Value.Cmp(big.NewInt(constant.BTCWithdrawalDustAmount)) < 0 { - return fmt.Errorf("ParseZRC20WithdrawalEvent: withdraw amount %s is less than minimum amount %d", + return errorsmod.Wrapf(types.ErrInvalidWithdrawalAmount, "withdraw amount %s is less than minimum amount %d", event.Value.String(), constant.BTCWithdrawalDustAmount) } addr, err := chains.DecodeBtcAddress(string(event.To), chainID) if err != nil { - return fmt.Errorf("ParseZRC20WithdrawalEvent: invalid address %s: %s", event.To, err) + return errorsmod.Wrapf(types.ErrInvalidAddress, "invalid address %s", string(event.To)) } if !chains.IsBtcAddressSupported(addr) { - return fmt.Errorf("ParseZRC20WithdrawalEvent: unsupported address %s", string(event.To)) + return errorsmod.Wrapf(types.ErrInvalidAddress, "unsupported address %s", string(event.To)) } } return nil diff --git a/x/crosschain/keeper/evm_hooks_test.go b/x/crosschain/keeper/evm_hooks_test.go index 60367745eb..fc0c33bd5d 100644 --- a/x/crosschain/keeper/evm_hooks_test.go +++ b/x/crosschain/keeper/evm_hooks_test.go @@ -165,7 +165,7 @@ func TestValidateZrc20WithdrawEvent(t *testing.T) { require.NoError(t, err) }) - t.Run("unable to validate a event with an invalid amount", func(t *testing.T) { + t.Run("unable to validate a btc withdrawal event with an invalid amount", func(t *testing.T) { btcMainNetWithdrawalEvent, err := crosschainkeeper.ParseZRC20WithdrawalEvent( *sample.GetValidZRC20WithdrawToBTC(t).Logs[3], ) diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 232bf229db..6f430e5e1a 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -49,4 +49,5 @@ var ( ErrInvalidRateLimiterFlags = errorsmod.Register(ModuleName, 1152, "invalid rate limiter flags") ErrMaxTxOutTrackerHashesReached = errorsmod.Register(ModuleName, 1153, "max tx out tracker hashes reached") ErrInitiatitingOutbound = errorsmod.Register(ModuleName, 1154, "cannot initiate outbound") + ErrInvalidWithdrawalAmount = errorsmod.Register(ModuleName, 1155, "invalid withdrawal amount") ) From 9afb6a9015e4f0169679441531249d2583678536 Mon Sep 17 00:00:00 2001 From: Charlie Chen Date: Fri, 21 Jun 2024 09:02:33 -0500 Subject: [PATCH 6/7] fix unit test --- x/crosschain/keeper/evm_hooks_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/crosschain/keeper/evm_hooks_test.go b/x/crosschain/keeper/evm_hooks_test.go index 7cc0b32f28..20b1c87e47 100644 --- a/x/crosschain/keeper/evm_hooks_test.go +++ b/x/crosschain/keeper/evm_hooks_test.go @@ -830,7 +830,7 @@ func TestKeeper_ProcessLogs(t *testing.T) { } err := k.ProcessLogs(ctx, block.Logs, sample.EthAddress(), "") - require.ErrorContains(t, err, "ParseZRC20WithdrawalEvent: invalid address") + require.ErrorContains(t, err, "invalid address") cctxList := k.GetAllCrossChainTx(ctx) require.Len(t, cctxList, 0) }) From abbe673fa43783248dc17c5f2f8ffaad8dcf1c2f Mon Sep 17 00:00:00 2001 From: Charlie Chen Date: Fri, 21 Jun 2024 09:15:35 -0500 Subject: [PATCH 7/7] fix code format --- x/crosschain/keeper/evm_hooks.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index 5480668cc4..2fc6310800 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -288,8 +288,12 @@ func ValidateZrc20WithdrawEvent(event *zrc20.ZRC20Withdrawal, chainID int64) err if chains.IsBitcoinChain(chainID) { if event.Value.Cmp(big.NewInt(constant.BTCWithdrawalDustAmount)) < 0 { - return errorsmod.Wrapf(types.ErrInvalidWithdrawalAmount, "withdraw amount %s is less than minimum amount %d", - event.Value.String(), constant.BTCWithdrawalDustAmount) + return errorsmod.Wrapf( + types.ErrInvalidWithdrawalAmount, + "withdraw amount %s is less than minimum amount %d", + event.Value.String(), + constant.BTCWithdrawalDustAmount, + ) } addr, err := chains.DecodeBtcAddress(string(event.To), chainID) if err != nil {