validate against money markets in store (#839)

This commit is contained in:
Denali Marsh 2021-02-19 21:23:19 +01:00 committed by GitHub
parent 6045a94b39
commit 6c88c01eb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 64 deletions

View File

@ -131,18 +131,11 @@ func (k Keeper) ValidateBorrow(ctx sdk.Context, borrower sdk.AccAddress, amount
} }
// Get the proposed borrow USD value // Get the proposed borrow USD value
moneyMarketCache := map[string]types.MoneyMarket{}
proprosedBorrowUSDValue := sdk.ZeroDec() proprosedBorrowUSDValue := sdk.ZeroDec()
for _, coin := range amount { for _, coin := range amount {
moneyMarket, ok := moneyMarketCache[coin.Denom] moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom)
// Fetch money market and store in local cache
if !ok {
newMoneyMarket, found := k.GetMoneyMarketParam(ctx, coin.Denom)
if !found { if !found {
return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", coin.Denom) return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom)
}
moneyMarketCache[coin.Denom] = newMoneyMarket
moneyMarket = newMoneyMarket
} }
// Calculate this coin's USD value and add it borrow's total USD value // 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) return sdkerrors.Wrapf(types.ErrDepositsNotFound, "no deposits found for %s", borrower)
} }
totalBorrowableAmount := sdk.ZeroDec() totalBorrowableAmount := sdk.ZeroDec()
for _, depCoin := range deposit.Amount { for _, coin := range deposit.Amount {
moneyMarket, ok := moneyMarketCache[depCoin.Denom] moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom)
// Fetch money market and store in local cache
if !ok {
newMoneyMarket, found := k.GetMoneyMarketParam(ctx, depCoin.Denom)
if !found { if !found {
return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", depCoin.Denom) return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom)
}
moneyMarketCache[depCoin.Denom] = newMoneyMarket
moneyMarket = newMoneyMarket
} }
// Calculate the borrowable amount and add it to the user's total borrowable amount // 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 { if err != nil {
return sdkerrors.Wrapf(types.ErrPriceNotFound, "no price found for market %s", moneyMarket.SpotMarketID) 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) borrowableAmountForDeposit := depositUSDValue.Mul(moneyMarket.BorrowLimit.LoanToValue)
totalBorrowableAmount = totalBorrowableAmount.Add(borrowableAmountForDeposit) totalBorrowableAmount = totalBorrowableAmount.Add(borrowableAmountForDeposit)
} }
@ -203,16 +190,10 @@ func (k Keeper) ValidateBorrow(ctx sdk.Context, borrower sdk.AccAddress, amount
existingBorrowUSDValue := sdk.ZeroDec() existingBorrowUSDValue := sdk.ZeroDec()
existingBorrow, found := k.GetBorrow(ctx, borrower) existingBorrow, found := k.GetBorrow(ctx, borrower)
if found { if found {
for _, borrowedCoin := range existingBorrow.Amount { for _, coin := range existingBorrow.Amount {
moneyMarket, ok := moneyMarketCache[borrowedCoin.Denom] moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom)
// Fetch money market and store in local cache
if !ok {
newMoneyMarket, found := k.GetMoneyMarketParam(ctx, borrowedCoin.Denom)
if !found { if !found {
return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", borrowedCoin.Denom) return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom)
}
moneyMarketCache[borrowedCoin.Denom] = newMoneyMarket
moneyMarket = newMoneyMarket
} }
// Calculate this borrow coin's USD value and add it to the total previous borrowed USD value // 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 { if err != nil {
return sdkerrors.Wrapf(types.ErrPriceNotFound, "no price found for market %s", moneyMarket.SpotMarketID) 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) existingBorrowUSDValue = existingBorrowUSDValue.Add(coinUSDValue)
} }
} }

View File

@ -18,17 +18,6 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramSubspace.SetParamSet(ctx, &params) k.paramSubspace.SetParamSet(ctx, &params)
} }
// 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 // GetMinimumBorrowUSDValue returns the minimum borrow USD value
func (k Keeper) GetMinimumBorrowUSDValue(ctx sdk.Context) sdk.Dec { func (k Keeper) GetMinimumBorrowUSDValue(ctx sdk.Context) sdk.Dec {
params := k.GetParams(ctx) params := k.GetParams(ctx)

View File

@ -85,36 +85,30 @@ func (k Keeper) Repay(ctx sdk.Context, sender, owner sdk.AccAddress, coins sdk.C
// ValidateRepay validates a requested loan repay // ValidateRepay validates a requested loan repay
func (k Keeper) ValidateRepay(ctx sdk.Context, sender, owner sdk.AccAddress, coins sdk.Coins) error { 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{} assetPriceCache := map[string]sdk.Dec{}
// Get the total USD value of user's existing borrows // Get the total USD value of user's existing borrows
existingBorrowUSDValue := sdk.ZeroDec() existingBorrowUSDValue := sdk.ZeroDec()
existingBorrow, found := k.GetBorrow(ctx, owner) existingBorrow, found := k.GetBorrow(ctx, owner)
if found { if found {
for _, borrowedCoin := range existingBorrow.Amount { for _, coin := range existingBorrow.Amount {
moneyMarket, ok := moneyMarketCache[borrowedCoin.Denom] moneyMarket, found := k.GetMoneyMarket(ctx, coin.Denom)
if !ok { // Fetch money market and store in local cache
newMoneyMarket, found := k.GetMoneyMarketParam(ctx, borrowedCoin.Denom)
if !found { if !found {
return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", borrowedCoin.Denom) return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", coin.Denom)
}
moneyMarketCache[borrowedCoin.Denom] = newMoneyMarket
moneyMarket = newMoneyMarket
} }
assetPrice, ok := assetPriceCache[borrowedCoin.Denom] assetPrice, ok := assetPriceCache[coin.Denom]
if !ok { // Fetch current asset price and store in local cache if !ok { // Fetch current asset price and store in local cache
assetPriceInfo, err := k.pricefeedKeeper.GetCurrentPrice(ctx, moneyMarket.SpotMarketID) assetPriceInfo, err := k.pricefeedKeeper.GetCurrentPrice(ctx, moneyMarket.SpotMarketID)
if err != nil { if err != nil {
return sdkerrors.Wrapf(types.ErrPriceNotFound, "no price found for market %s", moneyMarket.SpotMarketID) 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 assetPrice = assetPriceInfo.Price
} }
// Calculate this borrow coin's USD value and add it to the total previous borrowed USD value // 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) 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) return sdkerrors.Wrapf(types.ErrInsufficientBalanceForRepay, "account can only repay up to %s%s", senderCoins.AmountOf(repayCoin.Denom), repayCoin.Denom)
} }
moneyMarket, ok := moneyMarketCache[repayCoin.Denom] moneyMarket, found := k.GetMoneyMarket(ctx, repayCoin.Denom)
if !ok { // Fetch money market and store in local cache
newMoneyMarket, found := k.GetMoneyMarketParam(ctx, repayCoin.Denom)
if !found { if !found {
return sdkerrors.Wrapf(types.ErrMarketNotFound, "no market found for denom %s", repayCoin.Denom) return sdkerrors.Wrapf(types.ErrMarketNotFound, "no money market found for denom %s", repayCoin.Denom)
}
moneyMarketCache[repayCoin.Denom] = newMoneyMarket
moneyMarket = newMoneyMarket
} }
// Calculate this coin's USD value and add it to the repay's total USD value // Calculate this coin's USD value and add it to the repay's total USD value