Hard: delete borrow/deposit from store on 0 amount (#766)

* delete borrow/deposit on 0 balance

* add/update tests to ensure deletion

* delete from LTV index
This commit is contained in:
Denali Marsh 2021-01-18 10:43:20 +01:00 committed by GitHub
parent 293bfd6f1a
commit fba6b8c4f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 33 deletions

View File

@ -268,6 +268,10 @@ func (k Keeper) IsWithinValidLtvRange(ctx sdk.Context, deposit types.Deposit, bo
// UpdateBorrowAndLtvIndex updates a borrow and its LTV index value in the store // UpdateBorrowAndLtvIndex updates a borrow and its LTV index value in the store
func (k Keeper) UpdateBorrowAndLtvIndex(ctx sdk.Context, borrow types.Borrow, newLtv, oldLtv sdk.Dec) { func (k Keeper) UpdateBorrowAndLtvIndex(ctx sdk.Context, borrow types.Borrow, newLtv, oldLtv sdk.Dec) {
k.RemoveFromLtvIndex(ctx, oldLtv, borrow.Borrower) k.RemoveFromLtvIndex(ctx, oldLtv, borrow.Borrower)
if borrow.Amount.Empty() {
k.DeleteBorrow(ctx, borrow)
return
}
k.SetBorrow(ctx, borrow) k.SetBorrow(ctx, borrow)
k.InsertIntoLtvIndex(ctx, newLtv, borrow.Borrower) k.InsertIntoLtvIndex(ctx, newLtv, borrow.Borrower)
} }
@ -275,6 +279,10 @@ func (k Keeper) UpdateBorrowAndLtvIndex(ctx sdk.Context, borrow types.Borrow, ne
// UpdateDepositAndLtvIndex updates a deposit and its LTV index value in the store // UpdateDepositAndLtvIndex updates a deposit and its LTV index value in the store
func (k Keeper) UpdateDepositAndLtvIndex(ctx sdk.Context, deposit types.Deposit, newLtv, oldLtv sdk.Dec) { func (k Keeper) UpdateDepositAndLtvIndex(ctx sdk.Context, deposit types.Deposit, newLtv, oldLtv sdk.Dec) {
k.RemoveFromLtvIndex(ctx, oldLtv, deposit.Depositor) k.RemoveFromLtvIndex(ctx, oldLtv, deposit.Depositor)
if deposit.Amount.Empty() {
k.DeleteDeposit(ctx, deposit)
return
}
k.SetDeposit(ctx, deposit) k.SetDeposit(ctx, deposit)
k.InsertIntoLtvIndex(ctx, newLtv, deposit.Depositor) k.InsertIntoLtvIndex(ctx, newLtv, deposit.Depositor)
} }

View File

@ -28,8 +28,9 @@ func (suite *KeeperTestSuite) TestRepay() {
} }
type errArgs struct { type errArgs struct {
expectPass bool expectPass bool
contains string expectDelete bool
contains string
} }
type borrowTest struct { type borrowTest struct {
@ -52,8 +53,9 @@ func (suite *KeeperTestSuite) TestRepay() {
repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF))), repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF))),
}, },
errArgs{ errArgs{
expectPass: true, expectPass: true,
contains: "", expectDelete: false,
contains: "",
}, },
}, },
{ {
@ -67,8 +69,9 @@ func (suite *KeeperTestSuite) TestRepay() {
repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(50*KAVA_CF))), repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(50*KAVA_CF))),
}, },
errArgs{ errArgs{
expectPass: true, expectPass: true,
contains: "", expectDelete: true,
contains: "",
}, },
}, },
{ {
@ -82,8 +85,9 @@ func (suite *KeeperTestSuite) TestRepay() {
repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(60*KAVA_CF))), // Exceeds borrowed coins but not user's balance repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(60*KAVA_CF))), // Exceeds borrowed coins but not user's balance
}, },
errArgs{ errArgs{
expectPass: true, expectPass: true,
contains: "", expectDelete: true,
contains: "",
}, },
}, },
{ {
@ -97,8 +101,9 @@ func (suite *KeeperTestSuite) TestRepay() {
repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*KAVA_CF))), repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*KAVA_CF))),
}, },
errArgs{ errArgs{
expectPass: false, expectPass: false,
contains: "account can only repay up to 0bnb", expectDelete: false,
contains: "account can only repay up to 0bnb",
}, },
}, },
{ {
@ -112,8 +117,9 @@ func (suite *KeeperTestSuite) TestRepay() {
repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(51*KAVA_CF))), // Exceeds user's KAVA balance repayCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(51*KAVA_CF))), // Exceeds user's KAVA balance
}, },
errArgs{ errArgs{
expectPass: false, expectPass: false,
contains: "account can only repay up to 50000000ukava", expectDelete: false,
contains: "account can only repay up to 50000000ukava",
}, },
}, },
} }
@ -232,9 +238,15 @@ func (suite *KeeperTestSuite) TestRepay() {
suite.Require().Equal(expectedModuleCoins, mAcc.GetCoins()) suite.Require().Equal(expectedModuleCoins, mAcc.GetCoins())
// Check user's borrow object // Check user's borrow object
borrow, _ := suite.keeper.GetBorrow(suite.ctx, tc.args.borrower) borrow, foundBorrow := suite.keeper.GetBorrow(suite.ctx, tc.args.borrower)
expectedBorrowCoins := tc.args.borrowCoins.Sub(repaymentCoins) expectedBorrowCoins := tc.args.borrowCoins.Sub(repaymentCoins)
suite.Require().Equal(expectedBorrowCoins, borrow.Amount)
if tc.errArgs.expectDelete {
suite.Require().False(foundBorrow)
} else {
suite.Require().True(foundBorrow)
suite.Require().Equal(expectedBorrowCoins, borrow.Amount)
}
} else { } else {
suite.Require().Error(err) suite.Require().Error(err)
suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains)) suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
@ -250,7 +262,8 @@ func (suite *KeeperTestSuite) TestRepay() {
suite.Require().Equal(expectedModuleCoins, mAcc.GetCoins()) suite.Require().Equal(expectedModuleCoins, mAcc.GetCoins())
// Check user's borrow object (no repay coins) // Check user's borrow object (no repay coins)
borrow, _ := suite.keeper.GetBorrow(suite.ctx, tc.args.borrower) borrow, foundBorrow := suite.keeper.GetBorrow(suite.ctx, tc.args.borrower)
suite.Require().True(foundBorrow)
suite.Require().Equal(tc.args.borrowCoins, borrow.Amount) suite.Require().Equal(tc.args.borrowCoins, borrow.Amount)
} }
}) })

View File

@ -24,12 +24,12 @@ func (suite *KeeperTestSuite) TestWithdraw() {
createDeposit bool createDeposit bool
expectedAccountBalance sdk.Coins expectedAccountBalance sdk.Coins
expectedModAccountBalance sdk.Coins expectedModAccountBalance sdk.Coins
depositExists bool
finalDepositAmount sdk.Coins finalDepositAmount sdk.Coins
} }
type errArgs struct { type errArgs struct {
expectPass bool expectPass bool
contains string expectDelete bool
contains string
} }
type withdrawTest struct { type withdrawTest struct {
name string name string
@ -47,12 +47,12 @@ func (suite *KeeperTestSuite) TestWithdraw() {
createDeposit: true, createDeposit: true,
expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(900)), sdk.NewCoin("btcb", sdk.NewInt(1000))), expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(900)), sdk.NewCoin("btcb", sdk.NewInt(1000))),
expectedModAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))), expectedModAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))),
depositExists: true,
finalDepositAmount: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))), finalDepositAmount: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))),
}, },
errArgs{ errArgs{
expectPass: true, expectPass: true,
contains: "", expectDelete: false,
contains: "",
}, },
}, },
{ {
@ -65,12 +65,12 @@ func (suite *KeeperTestSuite) TestWithdraw() {
createDeposit: true, createDeposit: true,
expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000))), expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000))),
expectedModAccountBalance: sdk.Coins(nil), expectedModAccountBalance: sdk.Coins(nil),
depositExists: false,
finalDepositAmount: sdk.Coins{}, finalDepositAmount: sdk.Coins{},
}, },
errArgs{ errArgs{
expectPass: true, expectPass: true,
contains: "", expectDelete: true,
contains: "",
}, },
}, },
{ {
@ -83,12 +83,12 @@ func (suite *KeeperTestSuite) TestWithdraw() {
createDeposit: true, createDeposit: true,
expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000))), expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000))),
expectedModAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000))), expectedModAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000))),
depositExists: false,
finalDepositAmount: sdk.Coins{}, finalDepositAmount: sdk.Coins{},
}, },
errArgs{ errArgs{
expectPass: true, expectPass: true,
contains: "", expectDelete: true,
contains: "",
}, },
}, },
{ {
@ -101,12 +101,12 @@ func (suite *KeeperTestSuite) TestWithdraw() {
createDeposit: true, createDeposit: true,
expectedAccountBalance: sdk.Coins{}, expectedAccountBalance: sdk.Coins{},
expectedModAccountBalance: sdk.Coins{}, expectedModAccountBalance: sdk.Coins{},
depositExists: false,
finalDepositAmount: sdk.Coins{}, finalDepositAmount: sdk.Coins{},
}, },
errArgs{ errArgs{
expectPass: false, expectPass: false,
contains: "no coins of this type deposited", expectDelete: false,
contains: "no coins of this type deposited",
}, },
}, },
} }
@ -198,11 +198,11 @@ func (suite *KeeperTestSuite) TestWithdraw() {
mAcc := suite.getModuleAccount(types.ModuleAccountName) mAcc := suite.getModuleAccount(types.ModuleAccountName)
suite.Require().Equal(tc.args.expectedModAccountBalance, mAcc.GetCoins()) suite.Require().Equal(tc.args.expectedModAccountBalance, mAcc.GetCoins())
testDeposit, f := suite.keeper.GetDeposit(suite.ctx, tc.args.depositor) testDeposit, f := suite.keeper.GetDeposit(suite.ctx, tc.args.depositor)
if tc.args.depositExists { if tc.errArgs.expectDelete {
suite.Require().False(f)
} else {
suite.Require().True(f) suite.Require().True(f)
suite.Require().Equal(tc.args.finalDepositAmount, testDeposit.Amount) suite.Require().Equal(tc.args.finalDepositAmount, testDeposit.Amount)
} else {
suite.Require().False(f)
} }
} else { } else {
suite.Require().Error(err) suite.Require().Error(err)