From a2d1863b737f655401291e45c189bcad8e9ca7ae Mon Sep 17 00:00:00 2001 From: Karel Moravec Date: Mon, 13 May 2024 19:49:03 +0200 Subject: [PATCH] feat: add test --- core/banking/oneoff_transfers.go | 2 +- core/banking/recurring_transfers.go | 4 +-- core/banking/transfer_common_test.go | 49 ++++++++++++++++++++++++++++ core/banking/transfers_common.go | 13 +++++--- 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/core/banking/oneoff_transfers.go b/core/banking/oneoff_transfers.go index 382040bb6ef..ea0950c6f0e 100644 --- a/core/banking/oneoff_transfers.go +++ b/core/banking/oneoff_transfers.go @@ -86,7 +86,7 @@ func (e *Engine) oneOffTransfer( return err } - if err := e.ensureMinimalTransferAmount(a, transfer.Amount, transfer.FromAccountType, transfer.From); err != nil { + if err := e.ensureMinimalTransferAmount(a, transfer.Amount, transfer.FromAccountType, transfer.From, transfer.FromSubAccount); err != nil { transfer.Status = types.TransferStatusRejected return err } diff --git a/core/banking/recurring_transfers.go b/core/banking/recurring_transfers.go index 7d2d9d3fe60..1520ecb4950 100644 --- a/core/banking/recurring_transfers.go +++ b/core/banking/recurring_transfers.go @@ -87,7 +87,7 @@ func (e *Engine) recurringTransfer( return err } - if err := e.ensureMinimalTransferAmount(a, transfer.Amount, transfer.FromAccountType, transfer.From); err != nil { + if err := e.ensureMinimalTransferAmount(a, transfer.Amount, transfer.FromAccountType, transfer.From, transfer.FromSubAccount); err != nil { transfer.Status = types.TransferStatusRejected return err } @@ -253,7 +253,7 @@ func (e *Engine) distributeRecurringTransfers(ctx context.Context, newEpoch uint e.log.Panic("this should never happen", logging.Error(err)) } - if err = e.ensureMinimalTransferAmount(a, amount, v.FromAccountType, v.From); err != nil { + if err = e.ensureMinimalTransferAmount(a, amount, v.FromAccountType, v.From, v.FromSubAccount); err != nil { v.Status = types.TransferStatusStopped transfersDone = append(transfersDone, events.NewRecurringTransferFundsEventWithReason(ctx, v, err.Error(), e.getGameID(v))) diff --git a/core/banking/transfer_common_test.go b/core/banking/transfer_common_test.go index 5a3b8ef9772..cb8c060b36b 100644 --- a/core/banking/transfer_common_test.go +++ b/core/banking/transfer_common_test.go @@ -127,3 +127,52 @@ func TestCheckTransferWithVestedAccount(t *testing.T) { e.CheckTransfer(transfer), ) } + +func TestCheckTransferWithVestedAccountFromSubAccount(t *testing.T) { + e := getTestEngine(t) + + subAccount := "c84fbf3442a2a9f9ca87c9cefe686aed241ff49981dd8ce819dd532cd42a8427" + asset := "eth" + + transfer := &types.TransferBase{ + From: "03ae90688632c649c4beab6040ff5bd04dbde8efbf737d8673bbda792a110301", + FromSubAccount: &subAccount, + FromAccountType: types.AccountTypeVestedRewards, + To: "03ae90688632c649c4beab6040ff5bd04dbde8efbf737d8673bbda792a110301", + ToAccountType: types.AccountTypeGeneral, + Asset: asset, + Amount: num.NewUint(10), + Reference: "someref", + } + + e.OnMinTransferQuantumMultiple(context.Background(), num.DecimalFromFloat(1)) + + // balance is under the min amount + e.col.EXPECT().GetPartyVestedRewardAccount(subAccount, gomock.Any()).Return(&types.Account{Balance: num.NewUint(90)}, nil).Times(1) + + // asset exists + e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) + // try to transfer a small balance, but not the whole balance + require.EqualError(t, + e.CheckTransfer(transfer), + "transfer from vested account under minimal transfer amount must be the full balance", + ) + + // now we try to transfer the full amount + e.col.EXPECT().GetPartyVestedRewardAccount(subAccount, gomock.Any()).Return(&types.Account{Balance: num.NewUint(90)}, nil).Times(2) + transfer.Amount = num.NewUint(90) + e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) + require.NoError(t, + e.CheckTransfer(transfer), + ) + + // now we try again, with a balance above the min amount, but not the whole balance + e.col.EXPECT().GetPartyVestedRewardAccount(subAccount, gomock.Any()).Return(&types.Account{Balance: num.NewUint(300)}, nil).Times(1) + e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) + + transfer.Amount = num.NewUint(110) + // try to transfer a small balance, but not the whole balance + require.NoError(t, + e.CheckTransfer(transfer), + ) +} diff --git a/core/banking/transfers_common.go b/core/banking/transfers_common.go index aa68e7e52d5..ca057ad5b7e 100644 --- a/core/banking/transfers_common.go +++ b/core/banking/transfers_common.go @@ -81,7 +81,7 @@ func (e *Engine) CheckTransfer(t *types.TransferBase) error { return fmt.Errorf("could not transfer funds, %w", err) } - if err := e.ensureMinimalTransferAmount(a, t.Amount, t.FromAccountType, t.From); err != nil { + if err := e.ensureMinimalTransferAmount(a, t.Amount, t.FromAccountType, t.From, t.FromSubAccount); err != nil { return err } @@ -96,6 +96,7 @@ func (e *Engine) ensureMinimalTransferAmount( amount *num.Uint, fromAccType types.AccountType, from string, + fromSubAccount *string, ) error { quantum := a.Type().Details.Quantum // no reason this would produce an error @@ -104,6 +105,9 @@ func (e *Engine) ensureMinimalTransferAmount( // no verify amount if amount.LT(minAmount) { if fromAccType == types.AccountTypeVestedRewards { + if fromSubAccount != nil { + from = *fromSubAccount + } return e.ensureMinimalTransferAmountFromVested(amount, from, a.Type().ID) } @@ -233,6 +237,7 @@ func (e *Engine) calculateFeeTransferForTransfer( amount *num.Uint, from string, fromAccountType types.AccountType, + fromSubAccount *string, to string, ) *num.Uint { return calculateFeeForTransfer( @@ -255,7 +260,7 @@ func (e *Engine) makeFeeTransferForFundsTransfer( fromSubAccount *string, to string, ) (*types.Transfer, *num.Uint, error) { - theoreticalFee := e.calculateFeeTransferForTransfer(asset, amount, from, fromAccountType, to) + theoreticalFee := e.calculateFeeTransferForTransfer(asset, amount, from, fromAccountType, fromSubAccount, to) feeAmount, discountAmount := e.ApplyFeeDiscount(ctx, asset.ID, from, theoreticalFee) if err := e.ensureEnoughFundsForTransfer(asset, amount, from, fromAccountType, fromSubAccount, feeAmount); err != nil { @@ -292,7 +297,7 @@ func (e *Engine) ensureFeeForTransferFunds( to string, ) error { assetType := asset.ToAssetType() - theoreticalFee := e.calculateFeeTransferForTransfer(assetType, amount, from, fromAccountType, to) + theoreticalFee := e.calculateFeeTransferForTransfer(assetType, amount, from, fromAccountType, fromSubAccount, to) feeAmount, _ := e.EstimateFeeDiscount(assetType.ID, from, theoreticalFee) return e.ensureEnoughFundsForTransfer(assetType, amount, from, fromAccountType, fromSubAccount, feeAmount) } @@ -317,10 +322,10 @@ func (e *Engine) ensureEnoughFundsForTransfer( return err } case types.AccountTypeVestedRewards: - // sending from sub account to owners general account if fromSubAccount != nil { from = *fromSubAccount } + account, err = e.col.GetPartyVestedRewardAccount(from, asset.ID) if err != nil { return err