Skip to content

Commit

Permalink
Merge pull request #299 from comdex-official/feature/lend
Browse files Browse the repository at this point in the history
Feature/lend
  • Loading branch information
dheerajkd30 authored Jul 1, 2022
2 parents b916a6a + 337008d commit 16bd429
Show file tree
Hide file tree
Showing 8 changed files with 326 additions and 301 deletions.
7 changes: 4 additions & 3 deletions proto/comdex/lend/v1beta1/lend.proto
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ message BorrowAsset {
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.Coin"
];

uint64 bridged_asset_id = 7 [
(gogoproto.customname) = "BridgedAssetID",
(gogoproto.moretags) = "yaml:\"bridged_asset_id\""
cosmos.base.v1beta1.Coin bridged_asset_amount = 7 [
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"bridged_asset_amount\"",
(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.Coin"
];

google.protobuf.Timestamp borrowing_time = 8 [
Expand Down
36 changes: 24 additions & 12 deletions x/lend/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (q queryServer) QueryLend(c context.Context, req *types.QueryLendRequest) (

item, found := q.GetLend(ctx, req.Id)
if !found {
return nil, status.Errorf(codes.NotFound, "asset does not exist for id %d", req.Id)
return &types.QueryLendResponse{}, nil
}

return &types.QueryLendResponse{
Expand All @@ -94,7 +94,10 @@ func (q queryServer) QueryAllLendByOwner(c context.Context, req *types.QueryAllL
return nil, status.Errorf(codes.NotFound, "Address is not correct")
}

userVaultAssetData, _ := q.UserLends(ctx, req.Owner)
userVaultAssetData, found := q.UserLends(ctx, req.Owner)
if !found {
return &types.QueryAllLendByOwnerResponse{}, nil
}

for _, data := range userVaultAssetData {
lends = append(lends, data)
Expand All @@ -120,7 +123,10 @@ func (q queryServer) QueryAllLendByOwnerAndPool(c context.Context, req *types.Qu
return nil, status.Errorf(codes.NotFound, "Address is not correct")
}

userVaultAssetData, _ := q.LendIdByOwnerAndPool(ctx, req.Owner, req.PoolId)
userVaultAssetData, found := q.LendIdByOwnerAndPool(ctx, req.Owner, req.PoolId)
if !found {
return &types.QueryAllLendByOwnerAndPoolResponse{}, nil
}

for _, data := range userVaultAssetData {
lends = append(lends, data)
Expand All @@ -146,7 +152,10 @@ func (q queryServer) QueryAllBorrowByOwnerAndPool(c context.Context, req *types.
return nil, status.Errorf(codes.NotFound, "Address is not correct")
}

userVaultAssetData, _ := q.BorrowIdByOwnerAndPool(ctx, req.Owner, req.PoolId)
userVaultAssetData, found := q.BorrowIdByOwnerAndPool(ctx, req.Owner, req.PoolId)
if !found {
return &types.QueryAllBorrowByOwnerAndPoolResponse{}, nil
}

for _, data := range userVaultAssetData {
borrows = append(borrows, data)
Expand Down Expand Up @@ -206,7 +215,7 @@ func (q queryServer) QueryPair(c context.Context, req *types.QueryPairRequest) (

item, found := q.GetLendPair(ctx, req.Id)
if !found {
return nil, status.Errorf(codes.NotFound, "asset does not exist for id %d", req.Id)
return &types.QueryPairResponse{}, nil
}

return &types.QueryPairResponse{
Expand Down Expand Up @@ -262,7 +271,7 @@ func (q queryServer) QueryPool(c context.Context, req *types.QueryPoolRequest) (

item, found := q.GetPool(ctx, req.Id)
if !found {
return nil, status.Errorf(codes.NotFound, "asset does not exist for id %d", req.Id)
return &types.QueryPoolResponse{}, nil
}

return &types.QueryPoolResponse{
Expand Down Expand Up @@ -318,7 +327,7 @@ func (q queryServer) QueryAssetToPairMapping(c context.Context, req *types.Query

item, found := q.GetAssetToPair(ctx, req.AssetId, req.PoolId)
if !found {
return nil, status.Errorf(codes.NotFound, "pairs does not exist for assetId and poolId %d", req.AssetId, req.PoolId)
return &types.QueryAssetToPairMappingResponse{}, nil
}

return &types.QueryAssetToPairMappingResponse{
Expand Down Expand Up @@ -374,7 +383,7 @@ func (q queryServer) QueryBorrow(c context.Context, req *types.QueryBorrowReques

item, found := q.GetBorrow(ctx, req.Id)
if !found {
return nil, status.Errorf(codes.NotFound, "asset does not exist for id %d", req.Id)
return &types.QueryBorrowResponse{}, nil
}

return &types.QueryBorrowResponse{
Expand All @@ -396,7 +405,10 @@ func (q queryServer) QueryAllBorrowByOwner(c context.Context, req *types.QueryAl
return nil, status.Errorf(codes.NotFound, "Address is not correct")
}

userVaultAssetData, _ := q.UserBorrows(ctx, req.Owner)
userVaultAssetData, found := q.UserBorrows(ctx, req.Owner)
if !found {
return &types.QueryAllBorrowByOwnerResponse{}, nil
}

for _, data := range userVaultAssetData {
borrows = append(borrows, data)
Expand Down Expand Up @@ -456,7 +468,7 @@ func (q queryServer) QueryAssetRatesStat(c context.Context, req *types.QueryAsse

item, found := q.GetAssetRatesStats(ctx, req.Id)
if !found {
return nil, status.Errorf(codes.NotFound, "asset does not exist for id %d", req.Id)
return &types.QueryAssetRatesStatResponse{}, nil
}

return &types.QueryAssetRatesStatResponse{
Expand All @@ -472,7 +484,7 @@ func (q queryServer) QueryAssetStats(c context.Context, req *types.QueryAssetSta

assetStatsData, found := q.AssetStatsByPoolIdAndAssetId(ctx, req.AssetId, req.PoolId)
if !found {
return nil, status.Errorf(codes.NotFound, "assetStatsData does not exist for assetId %d and poolId %d ", req.AssetId, req.PoolId)
return &types.QueryAssetStatsResponse{}, nil
}

return &types.QueryAssetStatsResponse{
Expand All @@ -488,7 +500,7 @@ func (q queryServer) QueryModuleBalance(c context.Context, req *types.QueryModul

modBal, found := q.GetModuleBalanceByPoolId(ctx, req.PoolId)
if !found {
return nil, status.Errorf(codes.NotFound, "module Balance does not exist for poolId %d ", req.PoolId)
return &types.QueryModuleBalanceResponse{}, nil
}

return &types.QueryModuleBalanceResponse{
Expand Down
3 changes: 2 additions & 1 deletion x/lend/keeper/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func (k Keeper) IterateBorrows(ctx sdk.Context) error {
PairID: borrow.PairID,
AmountIn: borrow.AmountIn,
AmountOut: borrow.AmountOut,
BridgedAssetAmount: borrow.BridgedAssetAmount,
BorrowingTime: borrow.BorrowingTime,
StableBorrowRate: borrow.StableBorrowRate,
UpdatedAmountOut: borrow.UpdatedAmountOut.Add(interestPerBlock),
Expand Down Expand Up @@ -116,7 +117,7 @@ func (k Keeper) RebalanceStableRates(ctx sdk.Context) error {
for _, v := range stableBorrows.StableBorrowIds {
borrowPos, _ := k.GetBorrow(ctx, v)
pair, _ := k.GetLendPair(ctx, borrowPos.PairID)
assetStats, _ := k.UpdateAPR(ctx, pair.AssetOut, pair.AssetOutPoolId)
assetStats, _ := k.UpdateAPR(ctx, pair.AssetOutPoolId, pair.AssetOut)
utilizationRatio, _ := k.GetUtilisationRatioByPoolIdAndAssetId(ctx, pair.AssetOutPoolId, pair.AssetOut)
perc1, _ := sdk.NewDecFromStr("0.2")
perc2, _ := sdk.NewDecFromStr("0.9")
Expand Down
95 changes: 41 additions & 54 deletions x/lend/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,20 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
return types.ErrLendAccessUnauthorised
}

pair, found := k.GetLendPair(ctx, pairId)
if !found {
return types.ErrorPairNotFound
}
//check cr ratio
assetIn, _ := k.GetAsset(ctx, lendPos.AssetId)
assetOut, _ := k.GetAsset(ctx, pair.AssetOut)
assetInRatesStats, _ := k.GetAssetRatesStats(ctx, pair.AssetIn)

cAsset, _ := k.GetAsset(ctx, assetInRatesStats.CAssetId)
if AmountIn.Denom != cAsset.Denom {
return types.ErrBadOfferCoinAmount
}

if k.HasBorrowForAddressByPair(ctx, lenderAddr, pairId) {
return types.ErrorDuplicateBorrow
}
Expand All @@ -426,18 +440,15 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
//if !found {
// return types.ErrorPairNotFound
//}
pair, found := k.GetLendPair(ctx, pairId)
if !found {
return types.ErrorPairNotFound
}

AssetInPool, _ := k.GetPool(ctx, lendPos.PoolId)
AssetOutPool, _ := k.GetPool(ctx, pair.AssetOutPoolId)

//check cr ratio
assetIn, _ := k.GetAsset(ctx, lendPos.AssetId)
assetOut, _ := k.GetAsset(ctx, pair.AssetOut)

assetRatesStats, _ := k.GetAssetRatesStats(ctx, pair.AssetOut)
if IsStableBorrow && !assetRatesStats.EnableStableBorrow {
return sdkerrors.Wrap(types.ErrStableBorrowDisabled, loan.String())
}

err := k.VerifyCollaterlizationRatio(ctx, AmountIn.Amount, assetIn, loan.Amount, assetOut, assetRatesStats.LiquidationThreshold)
if err != nil {
return err
Expand All @@ -455,16 +466,6 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,

AmountOut := loan
// take c/Tokens from the user

assetRatesStat, found := k.GetAssetRatesStats(ctx, lendPos.AssetId)
if !found {
return sdkerrors.Wrap(types.ErrorAssetRatesStatsNotFound, strconv.FormatUint(lendPos.AssetId, 10))
}
cAsset, _ := k.GetAsset(ctx, assetRatesStat.CAssetId)
if AmountIn.Denom != cAsset.Denom {
return sdkerrors.Wrap(types.ErrBadOfferCoinAmount, AmountIn.Denom)
}

if err := k.SendCoinFromAccountToModule(ctx, lenderAddr, AssetInPool.ModuleName, AmountIn); err != nil {
return err
}
Expand Down Expand Up @@ -494,7 +495,7 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
PairID: pairId,
AmountIn: AmountIn,
AmountOut: AmountOut,
BridgedAssetID: 0,
BridgedAssetAmount: sdk.NewCoin("", sdk.NewInt(0)),
IsStableBorrow: IsStableBorrow,
StableBorrowRate: StableBorrowRate,
BorrowingTime: ctx.BlockTime(),
Expand All @@ -506,7 +507,7 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
if !found {
assetStats.TotalBorrowed = sdk.ZeroInt()
}
if borrowPos.StableBorrowRate != sdk.ZeroDec() {
if borrowPos.IsStableBorrow {
AssetStats := types.AssetStats{
PoolId: pair.AssetOutPoolId,
AssetId: pair.AssetOut,
Expand Down Expand Up @@ -562,44 +563,33 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
priceAssetIn, _ := k.GetPriceForAsset(ctx, pair.AssetIn)
amtIn := assetIn.Mul(sdk.NewIntFromUint64(priceAssetIn))

priceFirstBridgedAsset, _ := k.GetPriceForAsset(ctx, AssetInPool.FirstBridgedAssetId)
//priceFirstBridgedAsset, _ := k.GetPriceForAsset(ctx, AssetInPool.FirstBridgedAssetId)
priceSecondBridgedAsset, _ := k.GetPriceForAsset(ctx, AssetInPool.SecondBridgedAssetId)
firstBridgedAsset, _ := k.GetAsset(ctx, AssetInPool.FirstBridgedAssetId)
secondBridgedAsset, _ := k.GetAsset(ctx, AssetInPool.SecondBridgedAssetId)

// qty of first and second bridged asset to be sent over different pool according to the borrow Pool

firstBridgedAssetQty := amtIn.Quo(sdk.NewIntFromUint64(priceFirstBridgedAsset))
firstBridgedAssetQty := amtIn.Quo(sdk.NewIntFromUint64(1000000))
firstBridgedAssetBal := k.ModuleBalance(ctx, AssetInPool.ModuleName, firstBridgedAsset.Denom)
secondBridgedAssetQty := amtIn.Quo(sdk.NewIntFromUint64(priceSecondBridgedAsset))
secondBridgedAssetBal := k.ModuleBalance(ctx, AssetInPool.ModuleName, secondBridgedAsset.Denom)

if firstBridgedAssetQty.LT(firstBridgedAssetBal) {

// take c/Tokens from the user

assetRatesStat, found := k.GetAssetRatesStats(ctx, lendPos.AssetId)
if !found {
return sdkerrors.Wrap(types.ErrorAssetRatesStatsNotFound, strconv.FormatUint(lendPos.AssetId, 10))
}
cAsset, _ := k.GetAsset(ctx, assetRatesStat.CAssetId)
if AmountIn.Denom != cAsset.Denom {
return sdkerrors.Wrap(types.ErrBadOfferCoinAmount, AmountIn.Denom)
}

if err := k.SendCoinFromAccountToModule(ctx, lenderAddr, AssetInPool.ModuleName, AmountIn); err != nil {
return err
}

if err := k.SendCoinFromModuleToModule(ctx, AssetInPool.ModuleName, AssetOutPool.ModuleName, sdk.NewCoins(sdk.NewCoin(firstBridgedAsset.Denom, firstBridgedAssetQty))); err != nil {
bridgedAssetAmount := sdk.NewCoin(firstBridgedAsset.Denom, firstBridgedAssetQty)
if err := k.SendCoinFromModuleToModule(ctx, AssetInPool.ModuleName, AssetOutPool.ModuleName, sdk.NewCoins(bridgedAssetAmount)); err != nil {
return err
}

if err := k.SendCoinFromModuleToAccount(ctx, AssetOutPool.ModuleName, lenderAddr, loan); err != nil {
return err
}

AmountIn := sdk.NewCoin(lendPos.AmountIn.Denom, lendPos.UpdatedAmountIn)
AmountOut := loan

var StableBorrowRate sdk.Dec
Expand All @@ -623,7 +613,7 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
PairID: pairId,
AmountIn: AmountIn,
AmountOut: AmountOut,
BridgedAssetID: AssetInPool.FirstBridgedAssetId,
BridgedAssetAmount: bridgedAssetAmount,
IsStableBorrow: IsStableBorrow,
StableBorrowRate: StableBorrowRate,
BorrowingTime: ctx.BlockTime(),
Expand Down Expand Up @@ -681,28 +671,19 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,

} else if secondBridgedAssetQty.LT(secondBridgedAssetBal) {
// take c/Tokens from the user
assetRatesStat, found := k.GetAssetRatesStats(ctx, lendPos.AssetId)
if !found {
return sdkerrors.Wrap(types.ErrorAssetRatesStatsNotFound, strconv.FormatUint(lendPos.AssetId, 10))
}
cAsset, _ := k.GetAsset(ctx, assetRatesStat.CAssetId)
if AmountIn.Denom != cAsset.Denom {
return sdkerrors.Wrap(types.ErrBadOfferCoinAmount, AmountIn.Denom)
}

if err := k.SendCoinFromAccountToModule(ctx, lenderAddr, AssetInPool.ModuleName, AmountIn); err != nil {
return err
}

if err := k.SendCoinFromModuleToModule(ctx, AssetInPool.ModuleName, AssetOutPool.ModuleName, sdk.NewCoins(sdk.NewCoin(secondBridgedAsset.Denom, secondBridgedAssetQty))); err != nil {
bridgedAssetAmount := sdk.NewCoin(secondBridgedAsset.Denom, secondBridgedAssetQty)
if err := k.SendCoinFromModuleToModule(ctx, AssetInPool.ModuleName, AssetOutPool.ModuleName, sdk.NewCoins(bridgedAssetAmount)); err != nil {
return err
}

if err := k.SendCoinFromModuleToAccount(ctx, AssetOutPool.ModuleName, lenderAddr, loan); err != nil {
return err
}

AmountIn := sdk.NewCoin(lendPos.AmountIn.Denom, lendPos.UpdatedAmountIn)
AmountOut := loan

var StableBorrowRate sdk.Dec
Expand All @@ -726,7 +707,7 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
PairID: pairId,
AmountIn: AmountIn,
AmountOut: AmountOut,
BridgedAssetID: AssetInPool.SecondBridgedAssetId,
BridgedAssetAmount: bridgedAssetAmount,
IsStableBorrow: IsStableBorrow,
StableBorrowRate: StableBorrowRate,
BorrowingTime: ctx.BlockTime(),
Expand All @@ -738,7 +719,7 @@ func (k Keeper) BorrowAsset(ctx sdk.Context, addr string, lendId, pairId uint64,
if !found {
assetStats.TotalBorrowed = sdk.ZeroInt()
}
if borrowPos.StableBorrowRate != sdk.ZeroDec() {
if borrowPos.IsStableBorrow {
AssetStats := types.AssetStats{
PoolId: pair.AssetOutPoolId,
AssetId: pair.AssetOut,
Expand Down Expand Up @@ -816,16 +797,15 @@ func (k Keeper) RepayAsset(ctx sdk.Context, borrowId uint64, borrowerAddr string
return err
}
borrowPos.UpdatedAmountOut = borrowPos.UpdatedAmountOut.Sub(payment.Amount)
borrowPos.Interest_Accumulated = borrowPos.AmountOut.Amount.Sub(payment.Amount)

borrowPos.Interest_Accumulated = borrowPos.Interest_Accumulated.Sub(payment.Amount)
k.SetBorrow(ctx, borrowPos)
} else {
// sending repayment to moduleAcc from borrower
if err := k.bank.SendCoinsFromAccountToModule(ctx, addr, pool.ModuleName, sdk.NewCoins(payment)); err != nil {
return err
}
borrowPos.UpdatedAmountOut = borrowPos.UpdatedAmountOut.Sub(payment.Amount)
borrowPos.AmountOut.Amount = borrowPos.AmountOut.Amount.Sub(payment.Amount).Sub(borrowPos.Interest_Accumulated)
borrowPos.AmountOut.Amount = borrowPos.AmountOut.Amount.Sub(payment.Amount).Add(borrowPos.Interest_Accumulated)
borrowPos.Interest_Accumulated = sdk.ZeroInt()

reserveRates, _ := k.GetReserveRate(ctx, pair.AssetOutPoolId, pair.AssetOut)
Expand Down Expand Up @@ -1014,6 +994,8 @@ func (k Keeper) CloseBorrow(ctx sdk.Context, borrowerAddr string, borrowId uint6
pair, _ := k.GetLendPair(ctx, borrowPos.PairID)
pool, _ := k.GetPool(ctx, pair.AssetOutPoolId)
lendPos, _ := k.GetLend(ctx, borrowPos.LendingID)
assetInPool, _ := k.GetPool(ctx, lendPos.PoolId)

if lendPos.Owner != borrowerAddr {
return types.ErrLendAccessUnauthorised
}
Expand Down Expand Up @@ -1055,9 +1037,14 @@ func (k Keeper) CloseBorrow(ctx sdk.Context, borrowerAddr string, borrowId uint6
if err != nil {
return err
}
//TODO:
// send the bridged asset back to the assetIn pools

if pair.IsInterPool {
if err := k.bank.SendCoinsFromModuleToModule(ctx, pool.ModuleName, assetInPool.ModuleName, sdk.NewCoins(borrowPos.BridgedAssetAmount)); err != nil {
return err
}
}
lendPos.AvailableToBorrow = lendPos.AvailableToBorrow.Add(borrowPos.AmountIn.Amount)
k.SetLend(ctx, lendPos)
k.DeleteBorrow(ctx, borrowId)

return nil
Expand Down
2 changes: 1 addition & 1 deletion x/lend/keeper/lend.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ func (k *Keeper) GetAssetStatsByPoolIdAndAssetId(ctx sdk.Context, assetID, poolI
}

func (k *Keeper) AssetStatsByPoolIdAndAssetId(ctx sdk.Context, assetID, poolId uint64) (AssetStats types.AssetStats, found bool) {
AssetStats, found = k.UpdateAPR(ctx, assetID, poolId)
AssetStats, found = k.UpdateAPR(ctx, poolId, assetID)
if !found {
return AssetStats, false
}
Expand Down
Loading

0 comments on commit 16bd429

Please sign in to comment.