From 6c88c01eb8384a5adeec3a304bc332e3f88de127 Mon Sep 17 00:00:00 2001 From: Denali Marsh Date: Fri, 19 Feb 2021 21:23:19 +0100 Subject: [PATCH] validate against money markets in store (#839) --- x/hard/keeper/borrow.go | 45 ++++++++++++----------------------------- x/hard/keeper/params.go | 11 ---------- x/hard/keeper/repay.go | 31 +++++++++------------------- 3 files changed, 23 insertions(+), 64 deletions(-) diff --git a/x/hard/keeper/borrow.go b/x/hard/keeper/borrow.go index e600494b..aa0f109a 100644 --- a/x/hard/keeper/borrow.go +++ b/x/hard/keeper/borrow.go @@ -131,18 +131,11 @@ func (k Keeper) ValidateBorrow(ctx sdk.Context, borrower sdk.AccAddress, amount } // Get the proposed borrow USD value - moneyMarketCache := map[string]types.MoneyMarket{} proprosedBorrowUSDValue := sdk.ZeroDec() for _, coin := range amount { - moneyMarket, ok := moneyMarketCache[coin.Denom] - // Fetch money market and store in local cache - if !ok { - newMoneyMarket, found := k.GetMoneyMarketParam(ctx, coin.Denom) - if !found { - return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", coin.Denom) - } - moneyMarketCache[coin.Denom] = newMoneyMarket - moneyMarket = newMoneyMarket + moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom) + if !found { + return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom) } // Calculate this coin's USD value and add it borrow's total USD value @@ -177,16 +170,10 @@ func (k Keeper) ValidateBorrow(ctx sdk.Context, borrower sdk.AccAddress, amount return sdkerrors.Wrapf(types.ErrDepositsNotFound, "no deposits found for %s", borrower) } totalBorrowableAmount := sdk.ZeroDec() - for _, depCoin := range deposit.Amount { - moneyMarket, ok := moneyMarketCache[depCoin.Denom] - // Fetch money market and store in local cache - if !ok { - newMoneyMarket, found := k.GetMoneyMarketParam(ctx, depCoin.Denom) - if !found { - return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", depCoin.Denom) - } - moneyMarketCache[depCoin.Denom] = newMoneyMarket - moneyMarket = newMoneyMarket + for _, coin := range deposit.Amount { + moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom) + if !found { + return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom) } // Calculate the borrowable amount and add it to the user's total borrowable amount @@ -194,7 +181,7 @@ func (k Keeper) ValidateBorrow(ctx sdk.Context, borrower sdk.AccAddress, amount if err != nil { return sdkerrors.Wrapf(types.ErrPriceNotFound, "no price found for market %s", moneyMarket.SpotMarketID) } - depositUSDValue := sdk.NewDecFromInt(depCoin.Amount).Quo(sdk.NewDecFromInt(moneyMarket.ConversionFactor)).Mul(assetPriceInfo.Price) + depositUSDValue := sdk.NewDecFromInt(coin.Amount).Quo(sdk.NewDecFromInt(moneyMarket.ConversionFactor)).Mul(assetPriceInfo.Price) borrowableAmountForDeposit := depositUSDValue.Mul(moneyMarket.BorrowLimit.LoanToValue) totalBorrowableAmount = totalBorrowableAmount.Add(borrowableAmountForDeposit) } @@ -203,16 +190,10 @@ func (k Keeper) ValidateBorrow(ctx sdk.Context, borrower sdk.AccAddress, amount existingBorrowUSDValue := sdk.ZeroDec() existingBorrow, found := k.GetBorrow(ctx, borrower) if found { - for _, borrowedCoin := range existingBorrow.Amount { - moneyMarket, ok := moneyMarketCache[borrowedCoin.Denom] - // Fetch money market and store in local cache - if !ok { - newMoneyMarket, found := k.GetMoneyMarketParam(ctx, borrowedCoin.Denom) - if !found { - return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", borrowedCoin.Denom) - } - moneyMarketCache[borrowedCoin.Denom] = newMoneyMarket - moneyMarket = newMoneyMarket + for _, coin := range existingBorrow.Amount { + moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom) + if !found { + return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom) } // Calculate this borrow coin's USD value and add it to the total previous borrowed USD value @@ -220,7 +201,7 @@ func (k Keeper) ValidateBorrow(ctx sdk.Context, borrower sdk.AccAddress, amount if err != nil { return sdkerrors.Wrapf(types.ErrPriceNotFound, "no price found for market %s", moneyMarket.SpotMarketID) } - coinUSDValue := sdk.NewDecFromInt(borrowedCoin.Amount).Quo(sdk.NewDecFromInt(moneyMarket.ConversionFactor)).Mul(assetPriceInfo.Price) + coinUSDValue := sdk.NewDecFromInt(coin.Amount).Quo(sdk.NewDecFromInt(moneyMarket.ConversionFactor)).Mul(assetPriceInfo.Price) existingBorrowUSDValue = existingBorrowUSDValue.Add(coinUSDValue) } } diff --git a/x/hard/keeper/params.go b/x/hard/keeper/params.go index bfdec301..8bcd339c 100644 --- a/x/hard/keeper/params.go +++ b/x/hard/keeper/params.go @@ -18,17 +18,6 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { k.paramSubspace.SetParamSet(ctx, ¶ms) } -// GetMoneyMarketParam returns the corresponding Money Market param for a specific denom -func (k Keeper) GetMoneyMarketParam(ctx sdk.Context, denom string) (types.MoneyMarket, bool) { - params := k.GetParams(ctx) - for _, mm := range params.MoneyMarkets { - if mm.Denom == denom { - return mm, true - } - } - return types.MoneyMarket{}, false -} - // GetMinimumBorrowUSDValue returns the minimum borrow USD value func (k Keeper) GetMinimumBorrowUSDValue(ctx sdk.Context) sdk.Dec { params := k.GetParams(ctx) diff --git a/x/hard/keeper/repay.go b/x/hard/keeper/repay.go index 31ba08da..0d4c0400 100644 --- a/x/hard/keeper/repay.go +++ b/x/hard/keeper/repay.go @@ -85,36 +85,30 @@ func (k Keeper) Repay(ctx sdk.Context, sender, owner sdk.AccAddress, coins sdk.C // ValidateRepay validates a requested loan repay func (k Keeper) ValidateRepay(ctx sdk.Context, sender, owner sdk.AccAddress, coins sdk.Coins) error { - moneyMarketCache := map[string]types.MoneyMarket{} assetPriceCache := map[string]sdk.Dec{} // Get the total USD value of user's existing borrows existingBorrowUSDValue := sdk.ZeroDec() existingBorrow, found := k.GetBorrow(ctx, owner) if found { - for _, borrowedCoin := range existingBorrow.Amount { - moneyMarket, ok := moneyMarketCache[borrowedCoin.Denom] - if !ok { // Fetch money market and store in local cache - newMoneyMarket, found := k.GetMoneyMarketParam(ctx, borrowedCoin.Denom) - if !found { - return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", borrowedCoin.Denom) - } - moneyMarketCache[borrowedCoin.Denom] = newMoneyMarket - moneyMarket = newMoneyMarket + for _, coin := range existingBorrow.Amount { + moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom) + if !found { + return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom) } - assetPrice, ok := assetPriceCache[borrowedCoin.Denom] + assetPrice, ok := assetPriceCache[coin.Denom] if !ok { // Fetch current asset price and store in local cache assetPriceInfo, err := k.pricefeedKeeper.GetCurrentPrice(ctx, moneyMarket.SpotMarketID) if err != nil { return sdkerrors.Wrapf(types.ErrPriceNotFound, "no price found for market %s", moneyMarket.SpotMarketID) } - assetPriceCache[borrowedCoin.Denom] = assetPriceInfo.Price + assetPriceCache[coin.Denom] = assetPriceInfo.Price assetPrice = assetPriceInfo.Price } // Calculate this borrow coin's USD value and add it to the total previous borrowed USD value - coinUSDValue := sdk.NewDecFromInt(borrowedCoin.Amount).Quo(sdk.NewDecFromInt(moneyMarket.ConversionFactor)).Mul(assetPrice) + coinUSDValue := sdk.NewDecFromInt(coin.Amount).Quo(sdk.NewDecFromInt(moneyMarket.ConversionFactor)).Mul(assetPrice) existingBorrowUSDValue = existingBorrowUSDValue.Add(coinUSDValue) } } @@ -128,14 +122,9 @@ func (k Keeper) ValidateRepay(ctx sdk.Context, sender, owner sdk.AccAddress, coi return sdkerrors.Wrapf(types.ErrInsufficientBalanceForRepay, "account can only repay up to %s%s", senderCoins.AmountOf(repayCoin.Denom), repayCoin.Denom) } - moneyMarket, ok := moneyMarketCache[repayCoin.Denom] - if !ok { // Fetch money market and store in local cache - newMoneyMarket, found := k.GetMoneyMarketParam(ctx, repayCoin.Denom) - if !found { - return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", repayCoin.Denom) - } - moneyMarketCache[repayCoin.Denom] = newMoneyMarket - moneyMarket = newMoneyMarket + moneyMarket, found := k.GetMoneyMarket(ctx, repayCoin.Denom) + if !found { + return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", repayCoin.Denom) } // Calculate this coin's USD value and add it to the repay's total USD value