mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
fix: decrement coins for supply/borrow properly (#862)
* fix: decrement coins for supply/borrow properly * fix: decrement keeper liquidation reward coins from hard total supply (#865) * fix: use proper safe subtraction for withdraw/repay methods * fix: decrement keeper liquidation rewards from total supply * address review comments
This commit is contained in:
parent
162602f390
commit
829aed5256
@ -238,15 +238,19 @@ 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")
|
||||
}
|
||||
|
||||
updatedBorrowedCoins := sdk.NewCoins()
|
||||
for _, coin := range coins {
|
||||
// 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
|
||||
updatedBorrowedCoins, isNegative := borrowedCoins.SafeSub(coins)
|
||||
if isNegative {
|
||||
coinsToSubtract := sdk.NewCoins()
|
||||
for _, coin := range coins {
|
||||
if borrowedCoins.AmountOf(coin.Denom).LT(coin.Amount) {
|
||||
if borrowedCoins.AmountOf(coin.Denom).GT(sdk.ZeroInt()) {
|
||||
coinsToSubtract = coinsToSubtract.Add(sdk.NewCoin(coin.Denom, borrowedCoins.AmountOf(coin.Denom)))
|
||||
}
|
||||
} else {
|
||||
coinsToSubtract = coinsToSubtract.Add(coin)
|
||||
}
|
||||
}
|
||||
updatedBorrowCoin := sdk.NewCoin(coin.Denom, borrowedCoins.AmountOf(coin.Denom).Sub(coin.Amount))
|
||||
updatedBorrowedCoins = updatedBorrowedCoins.Add(updatedBorrowCoin)
|
||||
updatedBorrowedCoins = borrowedCoins.Sub(coinsToSubtract)
|
||||
}
|
||||
|
||||
k.SetBorrowedCoins(ctx, updatedBorrowedCoins)
|
||||
|
@ -145,15 +145,19 @@ func (k Keeper) DecrementSuppliedCoins(ctx sdk.Context, coins sdk.Coins) error {
|
||||
return sdkerrors.Wrapf(types.ErrSuppliedCoinsNotFound, "cannot withdraw if no coins are deposited")
|
||||
}
|
||||
|
||||
updatedSuppliedCoins := sdk.NewCoins()
|
||||
for _, coin := range coins {
|
||||
// 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
|
||||
updatedSuppliedCoins, isNegative := suppliedCoins.SafeSub(coins)
|
||||
if isNegative {
|
||||
coinsToSubtract := sdk.NewCoins()
|
||||
for _, coin := range coins {
|
||||
if suppliedCoins.AmountOf(coin.Denom).LT(coin.Amount) {
|
||||
if suppliedCoins.AmountOf(coin.Denom).GT(sdk.ZeroInt()) {
|
||||
coinsToSubtract = coinsToSubtract.Add(sdk.NewCoin(coin.Denom, suppliedCoins.AmountOf(coin.Denom)))
|
||||
}
|
||||
} else {
|
||||
coinsToSubtract = coinsToSubtract.Add(coin)
|
||||
}
|
||||
}
|
||||
updatedSupplyCoin := sdk.NewCoin(coin.Denom, suppliedCoins.AmountOf(coin.Denom).Sub(coin.Amount))
|
||||
updatedSuppliedCoins = updatedSuppliedCoins.Add(updatedSupplyCoin)
|
||||
updatedSuppliedCoins = suppliedCoins.Sub(coinsToSubtract)
|
||||
}
|
||||
|
||||
k.SetSuppliedCoins(ctx, updatedSuppliedCoins)
|
||||
|
@ -189,3 +189,139 @@ func (suite *KeeperTestSuite) TestDeposit() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestDecrementSuppliedCoins() {
|
||||
type args struct {
|
||||
suppliedInitial sdk.Coins
|
||||
decrementCoins sdk.Coins
|
||||
expectedSuppliedFinal sdk.Coins
|
||||
}
|
||||
type errArgs struct {
|
||||
expectPass bool
|
||||
contains string
|
||||
}
|
||||
type decrementTest struct {
|
||||
name string
|
||||
args args
|
||||
errArgs errArgs
|
||||
}
|
||||
testCases := []decrementTest{
|
||||
{
|
||||
"valid",
|
||||
args{
|
||||
suppliedInitial: cs(c("bnb", 10000000000000), c("busd", 3000000000000), c("xrpb", 2500000000000)),
|
||||
decrementCoins: cs(c("bnb", 5000000000000)),
|
||||
expectedSuppliedFinal: cs(c("bnb", 5000000000000), c("busd", 3000000000000), c("xrpb", 2500000000000)),
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid-negative",
|
||||
args{
|
||||
suppliedInitial: cs(c("bnb", 10000000000000), c("busd", 3000000000000), c("xrpb", 2500000000000)),
|
||||
decrementCoins: cs(c("bnb", 10000000000001)),
|
||||
expectedSuppliedFinal: cs(c("busd", 3000000000000), c("xrpb", 2500000000000)),
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid-multiple negative",
|
||||
args{
|
||||
suppliedInitial: cs(c("bnb", 10000000000000), c("busd", 3000000000000), c("xrpb", 2500000000000)),
|
||||
decrementCoins: cs(c("bnb", 10000000000001), c("busd", 5000000000000)),
|
||||
expectedSuppliedFinal: cs(c("xrpb", 2500000000000)),
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid-absent coin denom",
|
||||
args{
|
||||
suppliedInitial: cs(c("bnb", 10000000000000), c("xrpb", 2500000000000)),
|
||||
decrementCoins: cs(c("busd", 5)),
|
||||
expectedSuppliedFinal: cs(c("bnb", 10000000000000), c("xrpb", 2500000000000)),
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
// Initialize test app and set context
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
loanToValue, _ := sdk.NewDecFromStr("0.6")
|
||||
depositor := sdk.AccAddress(crypto.AddressHash([]byte("test")))
|
||||
authGS := app.NewAuthGenState([]sdk.AccAddress{depositor}, []sdk.Coins{tc.args.suppliedInitial})
|
||||
hardGS := types.NewGenesisState(types.NewParams(
|
||||
types.MoneyMarkets{
|
||||
types.NewMoneyMarket("bnb", types.NewBorrowLimit(false, sdk.NewDec(1000000000000000), loanToValue), "bnb:usd", sdk.NewInt(100000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
||||
types.NewMoneyMarket("busd", types.NewBorrowLimit(false, sdk.NewDec(1000000000000000), loanToValue), "busd:usd", sdk.NewInt(100000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
||||
types.NewMoneyMarket("xrpb", types.NewBorrowLimit(false, sdk.NewDec(1000000000000000), loanToValue), "xrpb:usd", sdk.NewInt(100000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
||||
},
|
||||
sdk.MustNewDecFromStr("10"),
|
||||
), types.DefaultAccumulationTimes, types.DefaultDeposits, types.DefaultBorrows,
|
||||
types.DefaultTotalSupplied, types.DefaultTotalBorrowed, types.DefaultTotalReserves,
|
||||
)
|
||||
// Pricefeed module genesis state
|
||||
pricefeedGS := pricefeed.GenesisState{
|
||||
Params: pricefeed.Params{
|
||||
Markets: []pricefeed.Market{
|
||||
{MarketID: "xrpb:usd", BaseAsset: "kava", QuoteAsset: "usd", Oracles: []sdk.AccAddress{}, Active: true},
|
||||
{MarketID: "busd:usd", BaseAsset: "btcb", QuoteAsset: "usd", Oracles: []sdk.AccAddress{}, Active: true},
|
||||
{MarketID: "bnb:usd", BaseAsset: "bnb", QuoteAsset: "usd", Oracles: []sdk.AccAddress{}, Active: true},
|
||||
},
|
||||
},
|
||||
PostedPrices: []pricefeed.PostedPrice{
|
||||
{
|
||||
MarketID: "busd:usd",
|
||||
OracleAddress: sdk.AccAddress{},
|
||||
Price: sdk.MustNewDecFromStr("1.00"),
|
||||
Expiry: time.Now().Add(1 * time.Hour),
|
||||
},
|
||||
{
|
||||
MarketID: "xrpb:usd",
|
||||
OracleAddress: sdk.AccAddress{},
|
||||
Price: sdk.MustNewDecFromStr("2.00"),
|
||||
Expiry: time.Now().Add(1 * time.Hour),
|
||||
},
|
||||
{
|
||||
MarketID: "bnb:usd",
|
||||
OracleAddress: sdk.AccAddress{},
|
||||
Price: sdk.MustNewDecFromStr("200.00"),
|
||||
Expiry: time.Now().Add(1 * time.Hour),
|
||||
},
|
||||
},
|
||||
}
|
||||
tApp.InitializeFromGenesisStates(authGS,
|
||||
app.GenesisState{pricefeed.ModuleName: pricefeed.ModuleCdc.MustMarshalJSON(pricefeedGS)},
|
||||
app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(hardGS)},
|
||||
)
|
||||
keeper := tApp.GetHardKeeper()
|
||||
suite.app = tApp
|
||||
suite.ctx = ctx
|
||||
suite.keeper = keeper
|
||||
|
||||
// Run BeginBlocker once to transition MoneyMarkets
|
||||
hard.BeginBlocker(suite.ctx, suite.keeper)
|
||||
|
||||
err := suite.keeper.Deposit(suite.ctx, depositor, tc.args.suppliedInitial)
|
||||
suite.Require().NoError(err)
|
||||
err = suite.keeper.DecrementSuppliedCoins(ctx, tc.args.decrementCoins)
|
||||
suite.Require().NoError(err)
|
||||
totalSuppliedActual, found := suite.keeper.GetSuppliedCoins(suite.ctx)
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(totalSuppliedActual, tc.args.expectedSuppliedFinal)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ func (k Keeper) SeizeDeposits(ctx sdk.Context, keeper sdk.AccAddress, deposit ty
|
||||
}
|
||||
}
|
||||
if !keeperRewardCoins.Empty() {
|
||||
k.DecrementSuppliedCoins(ctx, keeperRewardCoins)
|
||||
err := k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleAccountName, keeper, keeperRewardCoins)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
depositCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(10*KAVA_CF))),
|
||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(8*KAVA_CF))),
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 504138)),
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 100004118)),
|
||||
expectedTotalBorrowedCoins: nil,
|
||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100500020))),
|
||||
expectedBorrowerCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(98000001))), // initial - deposit + borrow + liquidation leftovers
|
||||
@ -102,16 +102,21 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
{
|
||||
"valid: single deposit, multiple borrows",
|
||||
args{
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
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))),
|
||||
initialBorrowerCoins: 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
|
||||
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,
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewInt64Coin("ukava", 2500711)),
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
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))),
|
||||
initialBorrowerCoins: 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
|
||||
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,
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("ukava", 1000000710),
|
||||
sdk.NewInt64Coin("usdc", 1000003120),
|
||||
sdk.NewInt64Coin("bnb", 100000003123),
|
||||
sdk.NewInt64Coin("btc", 100000000031),
|
||||
),
|
||||
expectedTotalBorrowedCoins: nil,
|
||||
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
|
||||
@ -186,16 +191,18 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
{
|
||||
"valid: multiple deposits, single borrow",
|
||||
args{
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||
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))),
|
||||
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
|
||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(120*KAVA_CF))), // $240 borrowed
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: nil,
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
keeperRewardPercent: sdk.MustNewDecFromStr("0.05"),
|
||||
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))),
|
||||
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
|
||||
borrowCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(120*KAVA_CF))), // $240 borrowed
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("ukava", 1000101456),
|
||||
),
|
||||
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
|
||||
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))),
|
||||
@ -253,19 +260,24 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid: mutliple stablecoin deposits, multiple variable coin borrows",
|
||||
"valid: multiple stablecoin deposits, multiple variable coin borrows",
|
||||
// Auctions: total lot value = $285 ($300 of deposits - $15 keeper reward), total max bid value = $270
|
||||
args{
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
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))),
|
||||
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))),
|
||||
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
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: nil,
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
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))),
|
||||
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))),
|
||||
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
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("bnb", 100000078047),
|
||||
sdk.NewInt64Coin("btc", 100000000780),
|
||||
sdk.NewInt64Coin("ukava", 1000009550),
|
||||
sdk.NewInt64Coin("usdx", 1),
|
||||
),
|
||||
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
|
||||
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))),
|
||||
@ -355,16 +367,21 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
{
|
||||
"valid: multiple stablecoin deposits, multiple stablecoin borrows",
|
||||
args{
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
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))),
|
||||
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))),
|
||||
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))),
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: nil,
|
||||
borrower: borrower,
|
||||
keeper: keeper,
|
||||
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))),
|
||||
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))),
|
||||
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))),
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("dai", 1000000000),
|
||||
sdk.NewInt64Coin("usdc", 1000000001),
|
||||
sdk.NewInt64Coin("usdt", 1000482503),
|
||||
sdk.NewInt64Coin("usdx", 1000463500),
|
||||
),
|
||||
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))),
|
||||
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))),
|
||||
@ -433,7 +450,7 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
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
|
||||
liquidateAfter: oneMonthInSeconds,
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(20001624))),
|
||||
expectedTotalSuppliedCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(120001624))),
|
||||
expectedTotalBorrowedCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(5001709))),
|
||||
expectedKeeperCoins: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(100.5*KAVA_CF))),
|
||||
expectedBorrowerCoins: sdk.NewCoins(),
|
||||
@ -452,10 +469,13 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
|
||||
// account which will deposit "initial module account coins"
|
||||
depositor := sdk.AccAddress(crypto.AddressHash([]byte("testdepositor")))
|
||||
|
||||
// Auth module genesis state
|
||||
authGS := app.NewAuthGenState(
|
||||
[]sdk.AccAddress{tc.args.borrower, tc.args.keeper},
|
||||
[]sdk.Coins{tc.args.initialBorrowerCoins, tc.args.initialKeeperCoins},
|
||||
[]sdk.AccAddress{tc.args.borrower, tc.args.keeper, depositor},
|
||||
[]sdk.Coins{tc.args.initialBorrowerCoins, tc.args.initialKeeperCoins, tc.args.initialModuleCoins},
|
||||
)
|
||||
|
||||
// Hard module genesis state
|
||||
@ -580,10 +600,6 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
app.GenesisState{pricefeed.ModuleName: pricefeed.ModuleCdc.MustMarshalJSON(pricefeedGS)},
|
||||
app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(hardGS)})
|
||||
|
||||
// Mint coins to Hard module account
|
||||
supplyKeeper := tApp.GetSupplyKeeper()
|
||||
supplyKeeper.MintCoins(ctx, types.ModuleAccountName, tc.args.initialModuleCoins)
|
||||
|
||||
auctionKeeper := tApp.GetAuctionKeeper()
|
||||
|
||||
keeper := tApp.GetHardKeeper()
|
||||
@ -597,6 +613,10 @@ func (suite *KeeperTestSuite) TestKeeperLiquidation() {
|
||||
// Run begin blocker to set up state
|
||||
hard.BeginBlocker(suite.ctx, suite.keeper)
|
||||
|
||||
// Deposit initial module account coins
|
||||
err = suite.keeper.Deposit(suite.ctx, depositor, tc.args.initialModuleCoins)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Deposit coins
|
||||
err = suite.keeper.Deposit(suite.ctx, tc.args.borrower, tc.args.depositCoins)
|
||||
suite.Require().NoError(err)
|
||||
|
Loading…
Reference in New Issue
Block a user