Skip to content

Commit

Permalink
Merge branch 'main' into feat/apr
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmic-vagabond authored Nov 20, 2023
2 parents 5cb7aad + 2d3cb15 commit 34b6163
Show file tree
Hide file tree
Showing 68 changed files with 1,238 additions and 1,576 deletions.
4 changes: 4 additions & 0 deletions proto/elys/margin/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ message Params {
bool whitelisting_enabled = 18;
string invariant_check_epoch = 19;
string broker_address = 20;
string take_profit_borrow_interest_rate_min = 21 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
4 changes: 4 additions & 0 deletions proto/elys/margin/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ message MTP {
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string take_profit_borrow_rate = 18 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}

message WhiteList {
Expand Down
42 changes: 5 additions & 37 deletions x/accountedpool/keeper/accounted_pool_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,6 @@ import (
margintypes "github.com/elys-network/elys/x/margin/types"
)

// Get Amm Pool Balance
func (k Keeper) GetAmmPoolBalance(ammPool ammtypes.Pool, denom string) sdk.Int {
for _, asset := range ammPool.PoolAssets {
if asset.Token.Denom == denom {
return asset.Token.Amount
}
}

return sdk.ZeroInt()
}

func (k Keeper) GetMarginPoolBalancesByPosition(marginPool margintypes.Pool, denom string, position margintypes.Position) (sdk.Int, sdk.Int, sdk.Int) {
poolAssets := marginPool.GetPoolAssets(position)

for _, asset := range *poolAssets {
if asset.AssetDenom == denom {
return asset.AssetBalance, asset.Liabilities, asset.Custody
}
}

return sdk.ZeroInt(), sdk.ZeroInt(), sdk.ZeroInt()
}

// Get Margin Pool Balance
func (k Keeper) GetMarginPoolBalances(marginPool margintypes.Pool, denom string) (sdk.Int, sdk.Int, sdk.Int) {
assetBalanceLong, liabilitiesLong, custodyLong := k.GetMarginPoolBalancesByPosition(marginPool, denom, margintypes.Position_LONG)
assetBalanceShort, liabilitiesShort, custodyShort := k.GetMarginPoolBalancesByPosition(marginPool, denom, margintypes.Position_SHORT)

assetBalance := assetBalanceLong.Add(assetBalanceShort)
liabilities := liabilitiesLong.Add(liabilitiesShort)
custody := custodyLong.Add(custodyShort)

return assetBalance, liabilities, custody
}

func (k Keeper) UpdateAccountedPool(ctx sdk.Context, ammPool ammtypes.Pool, marginPool margintypes.Pool) error {
poolId := ammPool.PoolId
// Check if already exists
Expand All @@ -61,8 +26,11 @@ func (k Keeper) UpdateAccountedPool(ctx sdk.Context, ammPool ammtypes.Pool, marg
// amm pool balance + margin pool balance + margin pool liabilties - margin pool custody
// But not deducting custody amount here as the balance was already deducted through TakeCustody function.
for i, asset := range accountedPool.PoolAssets {
aBalance := k.GetAmmPoolBalance(ammPool, asset.Token.Denom)
mBalance, mLiabiltiies, _ := k.GetMarginPoolBalances(marginPool, asset.Token.Denom)
aBalance, err := margintypes.GetAmmPoolBalance(ammPool, asset.Token.Denom)
if err != nil {
return err
}
mBalance, mLiabiltiies, _ := margintypes.GetMarginPoolBalances(marginPool, asset.Token.Denom)
accountedAmt := aBalance.Add(mBalance).Add(mLiabiltiies)
accountedPool.PoolAssets[i].Token = sdk.NewCoin(asset.Token.Denom, accountedAmt)
}
Expand Down
7 changes: 5 additions & 2 deletions x/leveragelp/keeper/position_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ func (k Keeper) OpenConsolidate(ctx sdk.Context, position *types.Position, msg *
return nil, err
}

collateralAmountDec := sdk.NewDecFromBigInt(msg.CollateralAmount.BigInt())
collateralAmountDec := sdk.NewDecFromInt(msg.CollateralAmount)
originCollateral := sdk.NewDecFromInt(position.Collateral.Amount)
position.Collateral = position.Collateral.Add(sdk.NewCoin(msg.CollateralAsset, msg.CollateralAmount))
maxLeverage := k.GetMaxLeverageParam(ctx)
leverage := sdk.MinDec(msg.Leverage, maxLeverage)
position.Leverage = leverage
position.StopLossPrice = msg.StopLossPrice
position.StopLossPrice = collateralAmountDec.Mul(msg.StopLossPrice).
Add(originCollateral.Mul(position.StopLossPrice)).
Quo(originCollateral.Add(collateralAmountDec))

position, err = k.ProcessOpenLong(ctx, position, leverage, collateralAmountDec, poolId, msg)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions x/leveragelp/keeper/position_open_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func (suite KeeperTestSuite) TestOpenLong() {
CollateralAmount: sdk.NewInt(1000),
AmmPoolId: 1,
Leverage: sdk.NewDec(5),
StopLossPrice: sdk.ZeroDec(),
})
suite.Require().NoError(err)
suite.Require().Equal(position.Address, addr.String())
Expand All @@ -108,6 +109,7 @@ func (suite KeeperTestSuite) TestOpenLong() {
CollateralAmount: sdk.NewInt(1000),
AmmPoolId: 1,
Leverage: sdk.NewDec(5),
StopLossPrice: sdk.ZeroDec(),
})
suite.Require().NoError(err)
position2, err := k.GetPosition(suite.ctx, position.Address, position.Id)
Expand Down
1 change: 1 addition & 0 deletions x/margin/client/cli/query_mtp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func networkWithMTPObjects(t *testing.T, n int) (*network.Network, []*types.MTP)
ConsolidateLeverage: sdk.ZeroDec(),
SumCollateral: sdk.ZeroInt(),
TakeProfitPrice: sdk.MustNewDecFromStr(types.TakeProfitPriceDefault),
TakeProfitBorrowRate: sdk.OneDec(),
}

mtps = append(mtps, &mtp)
Expand Down
59 changes: 31 additions & 28 deletions x/margin/keeper/begin_blocker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,42 @@ func (k Keeper) BeginBlocker(ctx sdk.Context) {
epochLength := k.GetEpochLength(ctx)
epochPosition := k.GetEpochPosition(ctx, epochLength)

if epochPosition == 0 { // if epoch has passed
entry, found := k.apKeeper.GetEntry(ctx, ptypes.BaseCurrency)
if !found {
ctx.Logger().Error(sdkerrors.Wrapf(assetprofiletypes.ErrAssetProfileNotFound, "asset %s not found", ptypes.BaseCurrency).Error())
}
baseCurrency := entry.Denom
// if epoch has not passed
if epochPosition != 0 {
return
}

// if epoch has passed
entry, found := k.apKeeper.GetEntry(ctx, ptypes.BaseCurrency)
if !found {
ctx.Logger().Error(sdkerrors.Wrapf(assetprofiletypes.ErrAssetProfileNotFound, "asset %s not found", ptypes.BaseCurrency).Error())
}
baseCurrency := entry.Denom

currentHeight := ctx.BlockHeight()
pools := k.GetAllPools(ctx)
for _, pool := range pools {
ammPool, err := k.GetAmmPool(ctx, pool.AmmPoolId, "")
currentHeight := ctx.BlockHeight()
pools := k.GetAllPools(ctx)
for _, pool := range pools {
ammPool, err := k.GetAmmPool(ctx, pool.AmmPoolId, "")
if err != nil {
ctx.Logger().Error(errors.Wrap(err, fmt.Sprintf("error getting amm pool: %d", pool.AmmPoolId)).Error())
continue // ?
}
if k.IsPoolEnabled(ctx, pool.AmmPoolId) {
rate, err := k.BorrowInterestRateComputation(ctx, pool, ammPool)
if err != nil {
ctx.Logger().Error(errors.Wrap(err, fmt.Sprintf("error getting amm pool: %d", pool.AmmPoolId)).Error())
ctx.Logger().Error(err.Error())
continue // ?
}
if k.IsPoolEnabled(ctx, pool.AmmPoolId) {
rate, err := k.BorrowInterestRateComputation(ctx, pool, ammPool)
if err != nil {
ctx.Logger().Error(err.Error())
continue // ?
}
pool.BorrowInterestRate = rate
pool.LastHeightBorrowInterestRateComputed = currentHeight
_ = k.UpdatePoolHealth(ctx, &pool)
// TODO: function missing
// k.TrackSQBeginBlock(ctx, pool)
mtps, _, _ := k.GetMTPsForPool(ctx, pool.AmmPoolId, nil)
for _, mtp := range mtps {
BeginBlockerProcessMTP(ctx, k, mtp, pool, ammPool, baseCurrency)
}
pool.BorrowInterestRate = rate
pool.LastHeightBorrowInterestRateComputed = currentHeight
_ = k.UpdatePoolHealth(ctx, &pool)
// TODO: function missing
// k.TrackSQBeginBlock(ctx, pool)
mtps, _, _ := k.GetMTPsForPool(ctx, pool.AmmPoolId, nil)
for _, mtp := range mtps {
BeginBlockerProcessMTP(ctx, k, mtp, pool, ammPool, baseCurrency)
}
k.SetPool(ctx, pool)
}
k.SetPool(ctx, pool)
}

}
37 changes: 36 additions & 1 deletion x/margin/keeper/begin_blocker_process_mtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ func BeginBlockerProcessMTP(ctx sdk.Context, k Keeper, mtp *types.MTP, pool type
}
}
}()
var err error
// update mtp take profit liabilities
// calculate mtp take profit liablities, delta x_tp_l = delta y_tp_c * current price (take profit liabilities = take profit custody * current price)
mtp.TakeProfitLiabilities, err = k.CalcMTPTakeProfitLiability(ctx, mtp, baseCurrency)
if err != nil {
ctx.Logger().Error(errors.Wrap(err, fmt.Sprintf("error calculating mtp take profit liabilities: %s", mtp.String())).Error())
return
}
// calculate and update take profit borrow rate
mtp.TakeProfitBorrowRate, err = k.CalcMTPTakeProfitBorrowRate(ctx, mtp)
if err != nil {
ctx.Logger().Error(errors.Wrap(err, fmt.Sprintf("error calculating mtp take profit borrow rate: %s", mtp.String())).Error())
return
}
h, err := k.UpdateMTPHealth(ctx, *mtp, ammPool, baseCurrency)
if err != nil {
ctx.Logger().Error(errors.Wrap(err, fmt.Sprintf("error updating mtp health: %s", mtp.String())).Error())
Expand Down Expand Up @@ -48,6 +62,27 @@ func BeginBlockerProcessMTP(ctx sdk.Context, k Keeper, mtp *types.MTP, pool type

_ = k.SetMTP(ctx, mtp)

for _, custody := range mtp.Custodies {
assetPrice, err := k.EstimateSwapGivenOut(ctx, sdk.NewCoin(custody.Denom, sdk.NewInt(1)), baseCurrency, ammPool)
if err != nil {
ctx.Logger().Error(errors.Wrap(err, fmt.Sprintf("error estimating swap given out: %s", custody.Denom)).Error())
return
}
if mtp.TakeProfitPrice.GT(sdk.NewDecFromInt(assetPrice)) {
break
}
ctx.Logger().Error(fmt.Sprintf("error executing force close on position %s because take profit price %s is less than asset price %s", mtp.String(), mtp.TakeProfitPrice.String(), sdk.NewDecFromInt(assetPrice).String()))
return
}

// check MTP health against threshold
safetyFactor := k.GetSafetyFactor(ctx)

if mtp.MtpHealth.GT(safetyFactor) {
ctx.Logger().Error(errors.Wrap(types.ErrMTPHealthy, "error executing force close because mtp is healthy").Error())
return
}

var repayAmount sdk.Int
switch mtp.Position {
case types.Position_LONG:
Expand All @@ -61,7 +96,7 @@ func BeginBlockerProcessMTP(ctx sdk.Context, k Keeper, mtp *types.MTP, pool type
if err == nil {
// Emit event if position was closed
k.EmitForceClose(ctx, mtp, repayAmount, "")
} else if err != types.ErrMTPHealthy {
} else {
ctx.Logger().Error(errors.Wrap(err, "error executing force close").Error())
}

Expand Down
15 changes: 0 additions & 15 deletions x/margin/keeper/calc_mtp_consolidate_leverage.go

This file was deleted.

5 changes: 4 additions & 1 deletion x/margin/keeper/calc_mtp_interest_liabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func (k Keeper) CalcMTPBorrowInterestLiabilities(ctx sdk.Context, mtp *types.MTP

rate.SetFloat64(borrowInterestRate.MustFloat64())

collateralIndex, _ := k.GetMTPAssetIndex(mtp, collateralAsset, "")
collateralIndex, _ := types.GetMTPAssetIndex(mtp, collateralAsset, "")
unpaidCollaterals := sdk.ZeroInt()
// Calculate collateral borrow interests in base currency
if mtp.Collaterals[collateralIndex].Denom == baseCurrency {
Expand Down Expand Up @@ -47,5 +47,8 @@ func (k Keeper) CalcMTPBorrowInterestLiabilities(ctx sdk.Context, mtp *types.MTP
borrowInterestNewInt = sdk.NewInt(1)
}

// apply take profit borrow rate to borrow interest
borrowInterestNewInt = sdk.NewDecFromInt(borrowInterestNewInt).Mul(mtp.TakeProfitBorrowRate).TruncateInt()

return borrowInterestNewInt
}
36 changes: 36 additions & 0 deletions x/margin/keeper/calc_mtp_take_profit_borrow_rate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/margin/types"
)

func (k Keeper) CalcMTPTakeProfitBorrowRate(ctx sdk.Context, mtp *types.MTP) (sdk.Dec, error) {
// Check if there are any takeProfitCustodies to avoid division by zero
if len(mtp.TakeProfitCustodies) == 0 {
return sdk.ZeroDec(), nil
}

var totalTakeProfitBorrowRate sdk.Dec = sdk.ZeroDec()
for takeProfitCustodyIndex, takeProfitCustody := range mtp.TakeProfitCustodies {
// Calculate the borrow rate for this takeProfitCustody
takeProfitBorrowRateInt := takeProfitCustody.Amount.Quo(mtp.Custodies[takeProfitCustodyIndex].Amount)

// Convert takeProfitBorrowRateInt from sdk.Int to sdk.Dec
takeProfitBorrowRateDec := sdk.NewDecFromInt(takeProfitBorrowRateInt)

// Add this take profit borrow rate to the total
totalTakeProfitBorrowRate = totalTakeProfitBorrowRate.Add(takeProfitBorrowRateDec)
}

// Calculate the average take profit borrow rate
averageTakeProfitBorrowRate := totalTakeProfitBorrowRate.Quo(sdk.NewDec(int64(len(mtp.TakeProfitCustodies))))

// Get Margin Params
params := k.GetParams(ctx)

// Use TakeProfitBorrowInterestRateMin param as minimum take profit borrow rate
averageTakeProfitBorrowRate = sdk.MaxDec(averageTakeProfitBorrowRate, params.TakeProfitBorrowInterestRateMin)

return averageTakeProfitBorrowRate, nil
}
27 changes: 27 additions & 0 deletions x/margin/keeper/calc_mtp_take_profit_liabilities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/margin/types"
)

func (k Keeper) CalcMTPTakeProfitLiability(ctx sdk.Context, mtp *types.MTP, baseCurrency string) (sdk.Int, error) {
takeProfitLiabilities := sdk.ZeroInt()
for _, takeProfitCustody := range mtp.TakeProfitCustodies {
takeProfitCustodyAsset := takeProfitCustody.Denom
// Retrieve AmmPool
ammPool, err := k.GetAmmPool(ctx, mtp.AmmPoolId, takeProfitCustodyAsset)
if err != nil {
return sdk.ZeroInt(), err
}

// convert custody amount to base currency
C, err := k.EstimateSwapGivenOut(ctx, takeProfitCustody, baseCurrency, ammPool)
if err != nil {
return sdk.ZeroInt(), err
}
takeProfitLiabilities = takeProfitLiabilities.Add(C)
}

return takeProfitLiabilities, nil
}
23 changes: 0 additions & 23 deletions x/margin/keeper/check_long_assets.go

This file was deleted.

Loading

0 comments on commit 34b6163

Please sign in to comment.