code.vegaprotocol.io/vega@v0.79.0/core/banking/transfer_common_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package banking_test 17 18 import ( 19 "context" 20 "errors" 21 "testing" 22 23 "code.vegaprotocol.io/vega/core/assets" 24 "code.vegaprotocol.io/vega/core/types" 25 "code.vegaprotocol.io/vega/libs/num" 26 27 "github.com/golang/mock/gomock" 28 "github.com/stretchr/testify/require" 29 ) 30 31 func TestCheckTransfer(t *testing.T) { 32 e := getTestEngine(t) 33 34 transfer := &types.TransferBase{ 35 From: "03ae90688632c649c4beab6040ff5bd04dbde8efbf737d8673bbda792a110301", 36 FromAccountType: types.AccountTypeGeneral, 37 To: "2e05fd230f3c9f4eaf0bdc5bfb7ca0c9d00278afc44637aab60da76653d7ccf0", 38 ToAccountType: types.AccountTypeGeneral, 39 Asset: "eth", 40 Amount: num.NewUint(10), 41 Reference: "someref", 42 } 43 44 e.OnMinTransferQuantumMultiple(context.Background(), num.DecimalFromFloat(1)) 45 46 e.col.EXPECT().GetPartyGeneralAccount(gomock.Any(), gomock.Any()).Return(&types.Account{Balance: num.NewUint(200)}, nil).AnyTimes() 47 48 // asset exists 49 e.assets.EXPECT().Get(gomock.Any()).Times(2).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 50 require.EqualError(t, 51 e.CheckTransfer(transfer), 52 "could not transfer funds, less than minimal amount requested to transfer", 53 ) 54 55 // decrease quantum multiple 56 e.OnMinTransferQuantumMultiple(context.Background(), num.DecimalFromFloat(0.01)) 57 require.NoError(t, e.CheckTransfer(transfer)) 58 59 // invalid asset 60 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(nil, errors.New("asset does not exist")) 61 require.EqualError(t, 62 e.CheckTransfer(transfer), 63 "could not transfer funds, asset does not exist", 64 ) 65 66 // invalid amount 67 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 68 transfer.Amount = num.UintZero() 69 require.EqualError(t, 70 e.CheckTransfer(transfer), 71 "could not transfer funds, cannot transfer zero funds", 72 ) 73 74 e.OnTransferFeeFactorUpdate(context.Background(), num.DecimalFromFloat(0.01)) 75 e.assets.EXPECT().Get(gomock.Any()).Times(2).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 76 // sufficient balance to cover fees 77 transfer.Amount = num.NewUint(100) 78 require.NoError(t, e.CheckTransfer(transfer)) 79 80 // insufficient balance to cover fees 81 transfer.Amount = num.NewUint(200) 82 require.EqualError(t, e.CheckTransfer(transfer), "could not transfer funds, not enough funds to transfer") 83 } 84 85 func TestCheckTransferWithVestedAccount(t *testing.T) { 86 e := getTestEngine(t) 87 88 transfer := &types.TransferBase{ 89 From: "03ae90688632c649c4beab6040ff5bd04dbde8efbf737d8673bbda792a110301", 90 FromAccountType: types.AccountTypeVestedRewards, 91 To: "03ae90688632c649c4beab6040ff5bd04dbde8efbf737d8673bbda792a110301", 92 ToAccountType: types.AccountTypeGeneral, 93 Asset: "eth", 94 Amount: num.NewUint(10), 95 Reference: "someref", 96 } 97 98 e.OnMinTransferQuantumMultiple(context.Background(), num.DecimalFromFloat(1)) 99 100 // balance is under the min amount 101 e.col.EXPECT().GetPartyVestedRewardAccount(gomock.Any(), gomock.Any()).Return(&types.Account{Balance: num.NewUint(90)}, nil).Times(1) 102 103 // asset exists 104 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 105 // try to transfer a small balance, but not the whole balance 106 require.EqualError(t, 107 e.CheckTransfer(transfer), 108 "transfer from vested account under minimal transfer amount must be the full balance", 109 ) 110 111 // now we try to transfre the full amount 112 e.col.EXPECT().GetPartyVestedRewardAccount(gomock.Any(), gomock.Any()).Return(&types.Account{Balance: num.NewUint(90)}, nil).Times(2) 113 transfer.Amount = num.NewUint(90) 114 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 115 require.NoError(t, 116 e.CheckTransfer(transfer), 117 ) 118 119 // now we try again, with a balance above the min amount, but not the whole balance 120 121 e.col.EXPECT().GetPartyVestedRewardAccount(gomock.Any(), gomock.Any()).Return(&types.Account{Balance: num.NewUint(300)}, nil).Times(1) 122 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 123 124 transfer.Amount = num.NewUint(110) 125 // try to transfer a small balance, but not the whole balance 126 require.NoError(t, 127 e.CheckTransfer(transfer), 128 ) 129 } 130 131 func TestCheckTransferWithVestedAccountFromSubAccount(t *testing.T) { 132 e := getTestEngine(t) 133 134 derivedKey := "c84fbf3442a2a9f9ca87c9cefe686aed241ff49981dd8ce819dd532cd42a8427" 135 asset := "eth" 136 137 transfer := &types.TransferBase{ 138 From: "03ae90688632c649c4beab6040ff5bd04dbde8efbf737d8673bbda792a110301", 139 FromDerivedKey: &derivedKey, 140 FromAccountType: types.AccountTypeVestedRewards, 141 To: "03ae90688632c649c4beab6040ff5bd04dbde8efbf737d8673bbda792a110301", 142 ToAccountType: types.AccountTypeGeneral, 143 Asset: asset, 144 Amount: num.NewUint(10), 145 Reference: "someref", 146 } 147 148 e.OnMinTransferQuantumMultiple(context.Background(), num.DecimalFromFloat(1)) 149 150 // balance is under the min amount 151 e.col.EXPECT().GetPartyVestedRewardAccount(derivedKey, gomock.Any()).Return(&types.Account{Balance: num.NewUint(90)}, nil).Times(1) 152 153 // asset exists 154 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 155 // try to transfer a small balance, but not the whole balance 156 require.EqualError(t, 157 e.CheckTransfer(transfer), 158 "transfer from vested account under minimal transfer amount must be the full balance", 159 ) 160 161 // now we try to transfer the full amount 162 e.col.EXPECT().GetPartyVestedRewardAccount(derivedKey, gomock.Any()).Return(&types.Account{Balance: num.NewUint(90)}, nil).Times(2) 163 transfer.Amount = num.NewUint(90) 164 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 165 require.NoError(t, 166 e.CheckTransfer(transfer), 167 ) 168 169 // now we try again, with a balance above the min amount, but not the whole balance 170 e.col.EXPECT().GetPartyVestedRewardAccount(derivedKey, gomock.Any()).Return(&types.Account{Balance: num.NewUint(300)}, nil).Times(1) 171 e.assets.EXPECT().Get(gomock.Any()).Times(1).Return(assets.NewAsset(&mockAsset{name: assetNameETH, quantum: num.DecimalFromFloat(100)}), nil) 172 173 transfer.Amount = num.NewUint(110) 174 // try to transfer a small balance, but not the whole balance 175 require.NoError(t, 176 e.CheckTransfer(transfer), 177 ) 178 }