Skip to content

Commit

Permalink
Check for blocked address before withdrawing to it
Browse files Browse the repository at this point in the history
  • Loading branch information
roy-dydx committed Jan 30, 2025
1 parent afa37ec commit 08b49b6
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
3 changes: 2 additions & 1 deletion protocol/testutil/keeper/bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/dydxprotocol/v4-chain/protocol/app"
"github.com/dydxprotocol/v4-chain/protocol/lib"
)

Expand All @@ -25,7 +26,7 @@ func createBankKeeper(
cdc,
runtime.NewKVStoreService(storeKey),
accountKeeper,
map[string]bool{},
app.BlockedAddresses(),
lib.GovModuleAddress.String(),
log.NewNopLogger(),
)
Expand Down
5 changes: 5 additions & 0 deletions protocol/x/subaccounts/keeper/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/dydxprotocol/v4-chain/protocol/lib"
"github.com/dydxprotocol/v4-chain/protocol/lib/metrics"
Expand Down Expand Up @@ -196,6 +197,10 @@ func (k Keeper) WithdrawFundsFromSubaccountToAccount(
return err
}

if k.bankKeeper.BlockedAddr(toAccount) {
return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", toAccount)
}

// Send coins from `fromModule` to the `subaccounts` module account.
if err := k.bankKeeper.SendCoins(
ctx,
Expand Down
37 changes: 29 additions & 8 deletions protocol/x/subaccounts/keeper/transfer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/dydxprotocol/v4-chain/protocol/lib"
auth_testutil "github.com/dydxprotocol/v4-chain/protocol/testutil/auth"
bank_testutil "github.com/dydxprotocol/v4-chain/protocol/testutil/bank"
Expand Down Expand Up @@ -330,9 +331,26 @@ func TestWithdrawFundsFromSubaccountToAccount_DepositFundsFromAccountToSubaccoun
// Transfer details
quantums *big.Int

// Optional. Defaults to an arbitrary test account if nil
optionalRecipient sdk.AccAddress

// Expectations.
expectedErr error
}{
"WithdrawFundsFromSubaccountToAccount: recipient is blocked address": {
testTransferFundToAccount: true,
asset: *constants.Usdc,
accAddressBalance: big.NewInt(0),
subaccountModuleAccBalance: big.NewInt(0),
quantums: big.NewInt(500),
assetPositions: testutil.CreateUsdcAssetPositions(big.NewInt(500)),
perpetualPositions: []*types.PerpetualPosition{
&constants.PerpetualPosition_OneBTCLong,
},
collateralPoolAddr: types.ModuleAddress,
optionalRecipient: authtypes.NewModuleAddress(distrtypes.ModuleName),
expectedErr: sdkerrors.ErrUnauthorized,
},
"WithdrawFundsFromSubaccountToAccount: subaccount does not have enough balance to transfer": {
testTransferFundToAccount: true,
asset: *constants.Usdc,
Expand Down Expand Up @@ -467,18 +485,21 @@ func TestWithdrawFundsFromSubaccountToAccount_DepositFundsFromAccountToSubaccoun
auth_testutil.CreateTestModuleAccount(ctx, accountKeeper, types.ModuleName, []string{})

// Set up test account address.
addressStr := sample_testutil.AccAddress()
testAccAddress, err := sdk.AccAddressFromBech32(addressStr)
require.NoError(t, err)
var err error
if tc.optionalRecipient == nil {
addressStr := sample_testutil.AccAddress()
tc.optionalRecipient, err = sdk.AccAddressFromBech32(addressStr)
require.NoError(t, err)
}

testAcc := authtypes.NewBaseAccount(testAccAddress, nil, accountKeeper.NextAccountNumber(ctx), 0)
testAcc := authtypes.NewBaseAccount(tc.optionalRecipient, nil, accountKeeper.NextAccountNumber(ctx), 0)
accountKeeper.SetAccount(ctx, testAcc)

if tc.accAddressBalance.Sign() > 0 {
// Mint asset in the receipt/sender account address for transfer.
err := bank_testutil.FundAccount(
ctx,
testAccAddress,
tc.optionalRecipient,
sdk.Coins{
sdk.NewCoin(tc.asset.Denom, sdkmath.NewIntFromBigInt(tc.accAddressBalance)),
},
Expand Down Expand Up @@ -530,14 +551,14 @@ func TestWithdrawFundsFromSubaccountToAccount_DepositFundsFromAccountToSubaccoun
err = keeper.WithdrawFundsFromSubaccountToAccount(
ctx,
*subaccount.Id,
testAccAddress,
tc.optionalRecipient,
tc.asset.Id,
tc.quantums,
)
} else {
err = keeper.DepositFundsFromAccountToSubaccount(
ctx,
testAccAddress,
tc.optionalRecipient,
*subaccount.Id,
tc.asset.Id,
tc.quantums,
Expand Down Expand Up @@ -566,7 +587,7 @@ func TestWithdrawFundsFromSubaccountToAccount_DepositFundsFromAccountToSubaccoun

// Check the test account balance stays the same.
testAccountBalance := bankKeeper.GetBalance(
ctx, testAccAddress,
ctx, tc.optionalRecipient,
tc.asset.Denom,
)
require.Equal(t,
Expand Down
2 changes: 2 additions & 0 deletions protocol/x/subaccounts/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type BankKeeper interface {
SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error
SendCoins(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error
GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin
BlockedAddr(addr sdk.AccAddress) bool
GetBlockedAddresses() map[string]bool
}

type BlocktimeKeeper interface {
Expand Down

0 comments on commit 08b49b6

Please sign in to comment.