Skip to content

Commit

Permalink
fix: set 1000 sats as minimum amount that can be withdrawn (#2362)
Browse files Browse the repository at this point in the history
* set 1000 sats as minimum amount that can be withdrawn

* added changelog entry

* allow 1000 satoshis to be withdrawn

* added minimum withdraw amount to error message

* define an error for invalid withdrawal amount

* fix unit test

* fix code format
  • Loading branch information
ws4charlie authored Jun 21, 2024
1 parent f95f0e9 commit 2946edd
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 8 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,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

Expand Down
14 changes: 10 additions & 4 deletions x/crosschain/keeper/evm_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,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"
Expand Down Expand Up @@ -286,15 +287,20 @@ 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 {
return fmt.Errorf("ParseZRC20WithdrawalEvent: invalid amount %s", event.Value.String())
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,
)
}
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
Expand Down
16 changes: 12 additions & 4 deletions x/crosschain/keeper/evm_hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -164,14 +165,21 @@ 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],
)
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)
err = crosschainkeeper.ValidateZrc20WithdrawEvent(btcMainNetWithdrawalEvent, chains.BitcoinMainnet.ChainId)
require.ErrorContains(t, err, "ParseZRC20WithdrawalEvent: invalid amount")
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, "less than minimum amount")
})

t.Run("unable to validate a event with an invalid chain ID", func(t *testing.T) {
Expand Down Expand Up @@ -822,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)
})
Expand Down
1 change: 1 addition & 0 deletions x/crosschain/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
)

0 comments on commit 2946edd

Please sign in to comment.