@@ -4,11 +4,14 @@ import (
44 "errors"
55 "fmt"
66 "strings"
7+ "time"
78
89 sdkmath "cosmossdk.io/math"
910
11+ "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
1012 sdk "github.com/cosmos/cosmos-sdk/types"
1113 sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
14+ vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
1215 banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
1316 banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
1417 minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
@@ -123,6 +126,62 @@ func (suite *KeeperTestSuite) TestSendTransfer() {
123126 },
124127 nil ,
125128 },
129+ {
130+ "successful transfer of entire spendable balance with vesting account" ,
131+ func () {
132+ // create vesting account
133+ vestingAccPrivKey := secp256k1 .GenPrivKey ()
134+ vestingAccAddress := sdk .AccAddress (vestingAccPrivKey .PubKey ().Address ())
135+
136+ vestingCoins := sdk .NewCoins (sdk .NewCoin (coins [0 ].Denom , ibctesting .DefaultCoinAmount ))
137+ _ , err := suite .chainA .SendMsgs (vestingtypes .NewMsgCreateVestingAccount (
138+ suite .chainA .SenderAccount .GetAddress (),
139+ vestingAccAddress ,
140+ vestingCoins ,
141+ suite .chainA .GetContext ().BlockTime ().Add (time .Hour ).Unix (),
142+ false ,
143+ ))
144+ suite .Require ().NoError (err )
145+ sender = vestingAccAddress
146+
147+ // transfer some spendable coins to vesting account
148+ transferCoins := sdk .NewCoins (sdk .NewCoin (coins [0 ].Denom , sdkmath .NewInt (42 )))
149+ _ , err = suite .chainA .SendMsgs (banktypes .NewMsgSend (suite .chainA .SenderAccount .GetAddress (), vestingAccAddress , transferCoins ))
150+ suite .Require ().NoError (err )
151+
152+ coins = sdk .NewCoins (sdk .NewCoin (coins [0 ].Denom , types .UnboundedSpendLimit ()))
153+ expEscrowAmounts [0 ] = transferCoins [0 ].Amount
154+ },
155+ nil ,
156+ },
157+ {
158+ "failure: no spendable coins for vesting account" ,
159+ func () {
160+ // create vesting account
161+ vestingAccPrivKey := secp256k1 .GenPrivKey ()
162+ vestingAccAddress := sdk .AccAddress (vestingAccPrivKey .PubKey ().Address ())
163+
164+ vestingCoins := sdk .NewCoins (sdk .NewCoin (coins [0 ].Denom , ibctesting .DefaultCoinAmount ))
165+ _ , err := suite .chainA .SendMsgs (vestingtypes .NewMsgCreateVestingAccount (
166+ suite .chainA .SenderAccount .GetAddress (),
167+ vestingAccAddress ,
168+ vestingCoins ,
169+ suite .chainA .GetContext ().BlockTime ().Add (time .Hour ).Unix (),
170+ false ,
171+ ))
172+ suite .Require ().NoError (err )
173+ sender = vestingAccAddress
174+
175+ // just to prove that the vesting account has a balance (but not spendable)
176+ vestingAccBalance := suite .chainA .GetSimApp ().BankKeeper .GetBalance (suite .chainA .GetContext (), vestingAccAddress , coins [0 ].Denom )
177+ suite .Require ().Equal (vestingCoins [0 ].Amount .Int64 (), vestingAccBalance .Amount .Int64 ())
178+ vestinSpendableBalance := suite .chainA .GetSimApp ().BankKeeper .SpendableCoins (suite .chainA .GetContext (), vestingAccAddress )
179+ suite .Require ().Zero (vestinSpendableBalance .AmountOf (coins [0 ].Denom ).Int64 ())
180+
181+ coins = sdk .NewCoins (sdk .NewCoin (coins [0 ].Denom , types .UnboundedSpendLimit ()))
182+ },
183+ types .ErrInvalidAmount ,
184+ },
126185 {
127186 "failure: source channel not found" ,
128187 func () {
@@ -233,8 +292,8 @@ func (suite *KeeperTestSuite) TestSendTransfer() {
233292
234293 expPass := tc .expError == nil
235294 if expPass {
236- suite .Require ().NotNil (res )
237295 suite .Require ().NoError (err )
296+ suite .Require ().NotNil (res )
238297 } else {
239298 suite .Require ().Nil (res )
240299 suite .Require ().Error (err )
0 commit comments