mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 23:35:19 +00:00
Hard Audit: decrement total borrowed on liquidation (#823)
* decrement total borrow on liquidation * copy kevin's decrement changes * check error in liquidation * extend decrement borrowed changes * mimic negative check on the supplied coins side * update liquidation test
This commit is contained in:
parent
7e39c1d0a8
commit
a5b72363d0
@ -240,9 +240,15 @@ func (k Keeper) DecrementBorrowedCoins(ctx sdk.Context, coins sdk.Coins) error {
|
|||||||
return sdkerrors.Wrapf(types.ErrBorrowedCoinsNotFound, "cannot repay coins if no coins are currently borrowed")
|
return sdkerrors.Wrapf(types.ErrBorrowedCoinsNotFound, "cannot repay coins if no coins are currently borrowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedBorrowedCoins, isAnyNegative := borrowedCoins.SafeSub(coins)
|
updatedBorrowedCoins := sdk.NewCoins()
|
||||||
if isAnyNegative {
|
for _, coin := range coins {
|
||||||
return types.ErrNegativeBorrowedCoins
|
// If amount is greater than total borrowed amount due to rounding, set total borrowed amount to 0
|
||||||
|
// by skipping the coin such that it's not included in the updatedBorrowedCoins object
|
||||||
|
if coin.Amount.GTE(borrowedCoins.AmountOf(coin.Denom)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
updatedBorrowCoin := sdk.NewCoin(coin.Denom, borrowedCoins.AmountOf(coin.Denom).Sub(coin.Amount))
|
||||||
|
updatedBorrowedCoins = updatedBorrowedCoins.Add(updatedBorrowCoin)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.SetBorrowedCoins(ctx, updatedBorrowedCoins)
|
k.SetBorrowedCoins(ctx, updatedBorrowedCoins)
|
||||||
|
@ -145,9 +145,15 @@ func (k Keeper) DecrementSuppliedCoins(ctx sdk.Context, coins sdk.Coins) error {
|
|||||||
return sdkerrors.Wrapf(types.ErrSuppliedCoinsNotFound, "cannot withdraw if no coins are deposited")
|
return sdkerrors.Wrapf(types.ErrSuppliedCoinsNotFound, "cannot withdraw if no coins are deposited")
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedSuppliedCoins, isAnyNegative := suppliedCoins.SafeSub(coins)
|
updatedSuppliedCoins := sdk.NewCoins()
|
||||||
if isAnyNegative {
|
for _, coin := range coins {
|
||||||
return types.ErrNegativeSuppliedCoins
|
// If amount is greater than total supplied amount due to rounding, set total supplied amount to 0
|
||||||
|
// by skipping the coin such that it's not included in the updatedSuppliedCoins object
|
||||||
|
if coin.Amount.GTE(suppliedCoins.AmountOf(coin.Denom)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
updatedSupplyCoin := sdk.NewCoin(coin.Denom, suppliedCoins.AmountOf(coin.Denom).Sub(coin.Amount))
|
||||||
|
updatedSuppliedCoins = updatedSuppliedCoins.Add(updatedSupplyCoin)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.SetSuppliedCoins(ctx, updatedSuppliedCoins)
|
k.SetSuppliedCoins(ctx, updatedSuppliedCoins)
|
||||||
|
@ -180,9 +180,15 @@ func (k Keeper) StartAuctions(ctx sdk.Context, borrower sdk.AccAddress, borrows,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return liquidatedCoins, err
|
return liquidatedCoins, err
|
||||||
}
|
}
|
||||||
// Decrement supplied coins and increment borrowed coins optimistically
|
// Decrement supplied coins and decrement borrowed coins optimistically
|
||||||
k.DecrementSuppliedCoins(ctx, sdk.Coins{lot})
|
err = k.DecrementSuppliedCoins(ctx, sdk.Coins{lot})
|
||||||
k.IncrementBorrowedCoins(ctx, sdk.Coins{bid})
|
if err != nil {
|
||||||
|
return liquidatedCoins, err
|
||||||
|
}
|
||||||
|
err = k.DecrementBorrowedCoins(ctx, sdk.Coins{bid})
|
||||||
|
if err != nil {
|
||||||
|
return liquidatedCoins, err
|
||||||
|
}
|
||||||
|
|
||||||
// Add lot to liquidated coins
|
// Add lot to liquidated coins
|
||||||
liquidatedCoins = liquidatedCoins.Add(lot)
|
liquidatedCoins = liquidatedCoins.Add(lot)
|
||||||
@ -225,9 +231,15 @@ func (k Keeper) StartAuctions(ctx sdk.Context, borrower sdk.AccAddress, borrows,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return liquidatedCoins, err
|
return liquidatedCoins, err
|
||||||
}
|
}
|
||||||
// Decrement supplied coins and increment borrowed coins optimistically
|
// Decrement supplied coins and decrement borrowed coins optimistically
|
||||||
k.DecrementSuppliedCoins(ctx, sdk.Coins{lot})
|
err = k.DecrementSuppliedCoins(ctx, sdk.Coins{lot})
|
||||||
k.IncrementBorrowedCoins(ctx, sdk.Coins{bid})
|
if err != nil {
|
||||||
|
return liquidatedCoins, err
|
||||||
|
}
|
||||||
|
err = k.DecrementBorrowedCoins(ctx, sdk.Coins{bid})
|
||||||
|
if err != nil {
|
||||||
|
return liquidatedCoins, err
|
||||||
|
}
|
||||||
|
|
||||||
// Add lot to liquidated coins
|
// Add lot to liquidated coins
|
||||||
liquidatedCoins = liquidatedCoins.Add(lot)
|
liquidatedCoins = liquidatedCoins.Add(lot)
|
||||||
|
@ -18,20 +18,20 @@ import (
|
|||||||
|
|
||||||
func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||||
type args struct {
|
type args struct {
|
||||||
borrower sdk.AccAddress
|
borrower sdk.AccAddress
|
||||||
keeper sdk.AccAddress
|
keeper sdk.AccAddress
|
||||||
keeperRewardPercent sdk.Dec
|
keeperRewardPercent sdk.Dec
|
||||||
initialModuleCoins sdk.Coins
|
initialModuleCoins sdk.Coins
|
||||||
initialBorrowerCoins sdk.Coins
|
initialBorrowerCoins sdk.Coins
|
||||||
initialKeeperCoins sdk.Coins
|
initialKeeperCoins sdk.Coins
|
||||||
depositCoins []sdk.Coin
|
depositCoins []sdk.Coin
|
||||||
borrowCoins sdk.Coins
|
borrowCoins sdk.Coins
|
||||||
liquidateAfter int64
|
liquidateAfter int64
|
||||||
expectedLiquidatedCoins sdk.Coins
|
expectedTotalSuppliedCoins sdk.Coins
|
||||||
expectedBidCoins sdk.Coins
|
expectedTotalBorrowedCoins sdk.Coins
|
||||||
expectedKeeperCoins sdk.Coins // coins keeper address should have after successfully liquidating position
|
expectedKeeperCoins sdk.Coins // coins keeper address should have after successfully liquidating position
|
||||||
expectedBorrowerCoins sdk.Coins // additional coins (if any) the borrower address should have after successfully liquidating position
|
expectedBorrowerCoins sdk.Coins // additional coins (if any) the borrower address should have after successfully liquidating position
|
||||||
expectedAuctions auctypes.Auctions // the auctions we should expect to find have been started
|
expectedAuctions auctypes.Auctions // the auctions we should expect to find have been started
|
||||||
}
|
}
|
||||||
|
|
||||||
type errArgs struct {
|
type errArgs struct {
|
||||||
@ -63,19 +63,19 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
{
|
{
|
||||||
"valid: keeper liquidates borrow",
|
"valid: keeper liquidates borrow",
|
||||||
args{
|
args{
|
||||||
borrower: borrower,
|
borrower: borrower,
|
||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||||
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF))),
|
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF))),
|
||||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(8*KAVA_CF))),
|
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(8*KAVA_CF))),
|
||||||
liquidateAfter: oneMonthInSeconds,
|
liquidateAfter: oneMonthInSeconds,
|
||||||
expectedLiquidatedCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 9500390)),
|
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 504138)),
|
||||||
expectedBidCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 8004766)),
|
expectedTotalBorrowedCoins: nil,
|
||||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100500020))),
|
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100500020))),
|
||||||
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(98000001))), // initial - deposit + borrow + liquidation leftovers
|
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(98000001))), // initial - deposit + borrow + liquidation leftovers
|
||||||
expectedAuctions: auctypes.Auctions{
|
expectedAuctions: auctypes.Auctions{
|
||||||
auctypes.CollateralAuction{
|
auctypes.CollateralAuction{
|
||||||
BaseAuction: auctypes.BaseAuction{
|
BaseAuction: auctypes.BaseAuction{
|
||||||
@ -102,19 +102,19 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
{
|
{
|
||||||
"valid: single deposit, multiple borrows",
|
"valid: single deposit, multiple borrows",
|
||||||
args{
|
args{
|
||||||
borrower: borrower,
|
borrower: borrower,
|
||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||||
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(1000*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1000*BTCB_CF))),
|
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(1000*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1000*BTCB_CF))),
|
||||||
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(50*KAVA_CF))), // $100 * 0.8 = $80 borrowable
|
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(50*KAVA_CF))), // $100 * 0.8 = $80 borrowable
|
||||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(20*KAVA_CF)), sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(2*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(0.2*BTCB_CF))), // $20+$20+$20 = $80 borrowed
|
borrowCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(20*KAVA_CF)), sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(2*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(0.2*BTCB_CF))), // $20+$20+$20 = $80 borrowed
|
||||||
liquidateAfter: oneMonthInSeconds,
|
liquidateAfter: oneMonthInSeconds,
|
||||||
expectedLiquidatedCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 47500032)),
|
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 2500711)),
|
||||||
expectedBidCoins: sdk.NewCoins(sdk.NewInt64Coin("bnb", 200003287), sdk.NewInt64Coin("btc", 20000032), sdk.NewInt64Coin("ukava", 10000782), sdk.NewInt64Coin("usdc", 20003284)),
|
expectedTotalBorrowedCoins: nil,
|
||||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(102500001))),
|
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(102500001))),
|
||||||
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(20*KAVA_CF)), sdk.NewCoin("ukava", sdk.NewInt(60000002)), sdk.NewCoin("bnb", sdk.NewInt(2*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(0.2*BTCB_CF))), // initial - deposit + borrow + liquidation leftovers
|
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(20*KAVA_CF)), sdk.NewCoin("ukava", sdk.NewInt(60000002)), sdk.NewCoin("bnb", sdk.NewInt(2*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(0.2*BTCB_CF))), // initial - deposit + borrow + liquidation leftovers
|
||||||
expectedAuctions: auctypes.Auctions{
|
expectedAuctions: auctypes.Auctions{
|
||||||
auctypes.CollateralAuction{
|
auctypes.CollateralAuction{
|
||||||
BaseAuction: auctypes.BaseAuction{
|
BaseAuction: auctypes.BaseAuction{
|
||||||
@ -186,19 +186,19 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
{
|
{
|
||||||
"valid: multiple deposits, single borrow",
|
"valid: multiple deposits, single borrow",
|
||||||
args{
|
args{
|
||||||
borrower: borrower,
|
borrower: borrower,
|
||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||||
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1000*KAVA_CF))),
|
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1000*KAVA_CF))),
|
||||||
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(100*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(100*BTCB_CF))),
|
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(100*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(100*BTCB_CF))),
|
||||||
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(50*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1*BTCB_CF))), // $100 + $100 + $100 = $300 * 0.8 = $240 borrowable // $100 * 0.8 = $80 borrowable
|
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(50*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1*BTCB_CF))), // $100 + $100 + $100 = $300 * 0.8 = $240 borrowable // $100 * 0.8 = $80 borrowable
|
||||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(120*KAVA_CF))), // $240 borrowed
|
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(120*KAVA_CF))), // $240 borrowed
|
||||||
liquidateAfter: oneMonthInSeconds,
|
liquidateAfter: oneMonthInSeconds,
|
||||||
expectedLiquidatedCoins: sdk.NewCoins(sdk.NewInt64Coin("bnb", 950000000), sdk.NewInt64Coin("btc", 95000000), sdk.NewInt64Coin("ukava", 47504818)),
|
expectedTotalSuppliedCoins: nil,
|
||||||
expectedBidCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 120112133)),
|
expectedTotalBorrowedCoins: nil,
|
||||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(102500253)), sdk.NewCoin("bnb", sdk.NewInt(0.5*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(0.05*BTCB_CF))), // 5% of each seized coin + initial balances
|
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(102500253)), sdk.NewCoin("bnb", sdk.NewInt(0.5*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(0.05*BTCB_CF))), // 5% of each seized coin + initial balances
|
||||||
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(170.000001*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(90*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(99*BTCB_CF))),
|
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(170.000001*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(90*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(99*BTCB_CF))),
|
||||||
expectedAuctions: auctypes.Auctions{
|
expectedAuctions: auctypes.Auctions{
|
||||||
auctypes.CollateralAuction{
|
auctypes.CollateralAuction{
|
||||||
BaseAuction: auctypes.BaseAuction{
|
BaseAuction: auctypes.BaseAuction{
|
||||||
@ -256,19 +256,19 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
"valid: mutliple stablecoin deposits, multiple variable coin borrows",
|
"valid: mutliple stablecoin deposits, multiple variable coin borrows",
|
||||||
// Auctions: total lot value = $285 ($300 of deposits - $15 keeper reward), total max bid value = $270
|
// Auctions: total lot value = $285 ($300 of deposits - $15 keeper reward), total max bid value = $270
|
||||||
args{
|
args{
|
||||||
borrower: borrower,
|
borrower: borrower,
|
||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||||
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(1000*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1000*BTCB_CF))),
|
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(1000*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1000*BTCB_CF))),
|
||||||
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(100*KAVA_CF))),
|
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(100*KAVA_CF))),
|
||||||
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
depositCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(100*KAVA_CF))), // $100 + $100 + $100 = $300 * 0.9 = $270 borrowable
|
depositCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(100*KAVA_CF))), // $100 + $100 + $100 = $300 * 0.9 = $270 borrowable
|
||||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(35*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1*BTCB_CF))), // $270 borrowed
|
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(35*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1*BTCB_CF))), // $270 borrowed
|
||||||
liquidateAfter: oneMonthInSeconds,
|
liquidateAfter: oneMonthInSeconds,
|
||||||
expectedLiquidatedCoins: sdk.NewCoins(sdk.NewInt64Coin("usdc", 95000000), sdk.NewInt64Coin("usdt", 95000000), sdk.NewInt64Coin("usdx", 94999999)),
|
expectedTotalSuppliedCoins: nil,
|
||||||
expectedBidCoins: sdk.NewCoins(sdk.NewInt64Coin("bnb", 1000082154), sdk.NewInt64Coin("btc", 100000821), sdk.NewInt64Coin("ukava", 35010052)),
|
expectedTotalBorrowedCoins: nil,
|
||||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(5*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(5*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(5*KAVA_CF))), // 5% of each seized coin + initial balances
|
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(5*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(5*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(5*KAVA_CF))), // 5% of each seized coin + initial balances
|
||||||
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(135*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1*BTCB_CF)), sdk.NewCoin("usdx", sdk.NewInt(0.000001*KAVA_CF))),
|
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(135*KAVA_CF)), sdk.NewCoin("bnb", sdk.NewInt(10*BNB_CF)), sdk.NewCoin("btc", sdk.NewInt(1*BTCB_CF)), sdk.NewCoin("usdx", sdk.NewInt(0.000001*KAVA_CF))),
|
||||||
expectedAuctions: auctypes.Auctions{
|
expectedAuctions: auctypes.Auctions{
|
||||||
auctypes.CollateralAuction{
|
auctypes.CollateralAuction{
|
||||||
BaseAuction: auctypes.BaseAuction{
|
BaseAuction: auctypes.BaseAuction{
|
||||||
@ -355,19 +355,19 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
{
|
{
|
||||||
"valid: multiple stablecoin deposits, multiple stablecoin borrows",
|
"valid: multiple stablecoin deposits, multiple stablecoin borrows",
|
||||||
args{
|
args{
|
||||||
borrower: borrower,
|
borrower: borrower,
|
||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||||
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("dai", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF))),
|
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("dai", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF))),
|
||||||
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("dai", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF))),
|
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("dai", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF))),
|
||||||
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("dai", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF))),
|
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("dai", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1000*KAVA_CF))),
|
||||||
depositCoins: sdk.NewCoins(sdk.NewCoin("dai", sdk.NewInt(350*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(200*KAVA_CF))),
|
depositCoins: sdk.NewCoins(sdk.NewCoin("dai", sdk.NewInt(350*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(200*KAVA_CF))),
|
||||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("usdt", sdk.NewInt(250*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(245*KAVA_CF))),
|
borrowCoins: sdk.NewCoins(sdk.NewCoin("usdt", sdk.NewInt(250*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(245*KAVA_CF))),
|
||||||
liquidateAfter: oneMonthInSeconds,
|
liquidateAfter: oneMonthInSeconds,
|
||||||
expectedLiquidatedCoins: sdk.NewCoins(sdk.NewInt64Coin("dai", 332500000), sdk.NewInt64Coin("usdc", 189999999)),
|
expectedTotalSuppliedCoins: nil,
|
||||||
expectedBidCoins: sdk.NewCoins(sdk.NewInt64Coin("usdx", 245487894), sdk.NewInt64Coin("usdt", 250507897)),
|
expectedTotalBorrowedCoins: nil,
|
||||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("dai", sdk.NewInt(1017.50*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1010*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF))),
|
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("dai", sdk.NewInt(1017.50*KAVA_CF)), sdk.NewCoin("usdt", sdk.NewInt(1000*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(1010*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(1000*KAVA_CF))),
|
||||||
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("dai", sdk.NewInt(650*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(800000001)), sdk.NewCoin("usdt", sdk.NewInt(1250*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(1245*KAVA_CF))),
|
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("dai", sdk.NewInt(650*KAVA_CF)), sdk.NewCoin("usdc", sdk.NewInt(800000001)), sdk.NewCoin("usdt", sdk.NewInt(1250*KAVA_CF)), sdk.NewCoin("usdx", sdk.NewInt(1245*KAVA_CF))),
|
||||||
expectedAuctions: auctypes.Auctions{
|
expectedAuctions: auctypes.Auctions{
|
||||||
auctypes.CollateralAuction{
|
auctypes.CollateralAuction{
|
||||||
BaseAuction: auctypes.BaseAuction{
|
BaseAuction: auctypes.BaseAuction{
|
||||||
@ -424,20 +424,20 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
{
|
{
|
||||||
"invalid: borrow not liquidatable",
|
"invalid: borrow not liquidatable",
|
||||||
args{
|
args{
|
||||||
borrower: borrower,
|
borrower: borrower,
|
||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||||
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialModuleCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
initialKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100*KAVA_CF))),
|
||||||
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(20*KAVA_CF))), // Deposit 20 KAVA
|
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(20*KAVA_CF))), // Deposit 20 KAVA
|
||||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(5*KAVA_CF))), // Borrow 5 KAVA
|
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(5*KAVA_CF))), // Borrow 5 KAVA
|
||||||
liquidateAfter: oneMonthInSeconds,
|
liquidateAfter: oneMonthInSeconds,
|
||||||
expectedLiquidatedCoins: sdk.Coins{},
|
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(20001624))),
|
||||||
expectedBidCoins: sdk.Coins{},
|
expectedTotalBorrowedCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(5001709))),
|
||||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100.5*KAVA_CF))),
|
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100.5*KAVA_CF))),
|
||||||
expectedBorrowerCoins: sdk.NewCoins(),
|
expectedBorrowerCoins: sdk.NewCoins(),
|
||||||
expectedAuctions: auctypes.Auctions{},
|
expectedAuctions: auctypes.Auctions{},
|
||||||
},
|
},
|
||||||
errArgs{
|
errArgs{
|
||||||
expectPass: false,
|
expectPass: false,
|
||||||
@ -650,10 +650,9 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
|
|
||||||
// Check that supplied and borrowed coins have been updated post-liquidation
|
// Check that supplied and borrowed coins have been updated post-liquidation
|
||||||
suppliedCoinsPost, _ := suite.keeper.GetSuppliedCoins(liqCtx)
|
suppliedCoinsPost, _ := suite.keeper.GetSuppliedCoins(liqCtx)
|
||||||
suite.Require().Equal(suppliedCoinsPre.Sub(tc.args.expectedLiquidatedCoins), suppliedCoinsPost)
|
suite.Require().Equal(tc.args.expectedTotalSuppliedCoins, suppliedCoinsPost)
|
||||||
borrowedCoinsPost, _ := suite.keeper.GetBorrowedCoins(liqCtx)
|
borrowedCoinsPost, _ := suite.keeper.GetBorrowedCoins(liqCtx)
|
||||||
|
suite.Require().Equal(tc.args.expectedTotalBorrowedCoins, borrowedCoinsPost)
|
||||||
suite.Require().Equal(borrowedCoinsPre.Add(tc.args.expectedBidCoins...), borrowedCoinsPost)
|
|
||||||
} 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))
|
||||||
@ -668,6 +667,10 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
|||||||
// Check that no auctions have been created
|
// Check that no auctions have been created
|
||||||
auctions := suite.auctionKeeper.GetAllAuctions(liqCtx)
|
auctions := suite.auctionKeeper.GetAllAuctions(liqCtx)
|
||||||
suite.Require().True(len(auctions) == 0)
|
suite.Require().True(len(auctions) == 0)
|
||||||
|
|
||||||
|
// Check that supplied and borrowed coins have not been updated post-liquidation
|
||||||
|
suite.Require().Equal(tc.args.expectedTotalSuppliedCoins, suppliedCoinsPre)
|
||||||
|
suite.Require().Equal(tc.args.expectedTotalBorrowedCoins, borrowedCoinsPre)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,10 @@ func (k Keeper) Repay(ctx sdk.Context, sender, owner sdk.AccAddress, coins sdk.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update total borrowed amount
|
// Update total borrowed amount
|
||||||
k.DecrementBorrowedCoins(ctx, payment)
|
err = k.DecrementBorrowedCoins(ctx, payment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Call incentive hook
|
// Call incentive hook
|
||||||
if !borrow.Amount.Empty() {
|
if !borrow.Amount.Empty() {
|
||||||
|
@ -64,8 +64,12 @@ func (k Keeper) Withdraw(ctx sdk.Context, depositor sdk.AccAddress, coins sdk.Co
|
|||||||
} else {
|
} else {
|
||||||
k.SetDeposit(ctx, deposit)
|
k.SetDeposit(ctx, deposit)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update total supplied amount
|
// Update total supplied amount
|
||||||
k.DecrementSuppliedCoins(ctx, amount)
|
err = k.DecrementSuppliedCoins(ctx, amount)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Call incentive hook
|
// Call incentive hook
|
||||||
k.AfterDepositModified(ctx, deposit)
|
k.AfterDepositModified(ctx, deposit)
|
||||||
|
Loading…
Reference in New Issue
Block a user