Skip to content

Commit

Permalink
effective leverage (#884)
Browse files Browse the repository at this point in the history
* effectiveLeverage and migration fixes

* fixing variable name

* fixes after merge with main
  • Loading branch information
avkr003 authored Oct 26, 2024
1 parent c4d2695 commit 215f6de
Show file tree
Hide file tree
Showing 23 changed files with 443 additions and 342 deletions.
2 changes: 1 addition & 1 deletion proto/elys/leveragelp/pool.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ message Pool {
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string max_leveragelp_percent = 5 [
string max_leveragelp_ratio = 5 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
Expand Down
2 changes: 2 additions & 0 deletions proto/elys/perpetual/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ message QueryOpenEstimationResponse {
string borrow_interest_rate = 13 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string funding_rate = 14 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string price_impact = 15 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin custody = 16 [(gogoproto.nullable) = false] ;
cosmos.base.v1beta1.Coin liabilities = 17 [(gogoproto.nullable) = false] ;
}

message QueryGetAllToPayRequest {}
Expand Down
2 changes: 1 addition & 1 deletion x/accountedpool/keeper/hooks_leveragelp.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func (k Keeper) OnLeverageLpPoolEnable(ctx sdk.Context, ammPool ammtypes.Pool) e
// Check if already exists
exists := k.PoolExists(ctx, poolId)
if exists {
return nil //TODO types.ErrPoolAlreadyExist correct this, failing in workflow
return types.ErrPoolAlreadyExist
}

// Initiate pool
Expand Down
4 changes: 2 additions & 2 deletions x/amm/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
// NewParams creates a new Params instance
func NewParams(poolCreationFee math.Int, slippageTrackDuration uint64, enable bool) Params {
return Params{
PoolCreationFee: poolCreationFee,
SlippageTrackDuration: slippageTrackDuration,
PoolCreationFee: poolCreationFee,
SlippageTrackDuration: slippageTrackDuration,
EnableBaseCurrencyPairedPoolOnly: enable,
}
}
Expand Down
6 changes: 3 additions & 3 deletions x/leveragelp/keeper/msg_server_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (k Keeper) Open(ctx sdk.Context, msg *types.MsgOpen) (*types.MsgOpenRespons
Quo(params.TotalValue.ToLegacyDec())
}

var pool_leveragelp sdk.Dec
var poolLeveragelpRatio sdk.Dec
pool, found := k.GetPool(ctx, msg.AmmPoolId)
if !found {
return nil, errorsmod.Wrap(types.ErrPoolDoesNotExist, fmt.Sprintf("poolId: %d", msg.AmmPoolId))
Expand All @@ -44,9 +44,9 @@ func (k Keeper) Open(ctx sdk.Context, msg *types.MsgOpen) (*types.MsgOpenRespons
if !found {
return nil, errorsmod.Wrap(types.ErrPoolDoesNotExist, fmt.Sprintf("poolId: %d", msg.AmmPoolId))
}
pool_leveragelp = pool.LeveragedLpAmount.ToLegacyDec().Quo(amm_pool.TotalShares.Amount.ToLegacyDec()).Mul(sdk.NewDec(100))
poolLeveragelpRatio = pool.LeveragedLpAmount.ToLegacyDec().Quo(amm_pool.TotalShares.Amount.ToLegacyDec())

if pool_leveragelp.GTE(pool.MaxLeveragelpPercent) || borrowRatio.GTE(params.MaxLeverageRatio) {
if poolLeveragelpRatio.GTE(pool.MaxLeveragelpRatio) || borrowRatio.GTE(params.MaxLeverageRatio) {
return nil, errorsmod.Wrap(types.ErrMaxLeverageLpExists, "no new position can be open")
}

Expand Down
12 changes: 0 additions & 12 deletions x/leveragelp/migrations/v13_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,9 @@ package migrations

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

func (m Migrator) V13Migration(ctx sdk.Context) error {
legacyPools := m.keeper.GetAllLegacyPools(ctx)

for _, legacyPool := range legacyPools {
newPool := types.Pool{
AmmPoolId: legacyPool.AmmPoolId,
Health: legacyPool.Health,
LeveragedLpAmount: legacyPool.LeveragedLpAmount,
LeverageMax: legacyPool.LeverageMax,
}
m.keeper.SetPool(ctx, newPool)
}

return nil
}
15 changes: 0 additions & 15 deletions x/leveragelp/migrations/v14_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,6 @@ import (
)

func (m Migrator) V14Migration(ctx sdk.Context) error {
pools := m.keeper.GetAllPools(ctx)

for _, pool := range pools {

ammPool, err := m.keeper.GetAmmPool(ctx, pool.AmmPoolId)
if err != nil {
return err
}
if m.keeper.GetHooks() != nil {
err = m.keeper.GetHooks().AfterEnablingPool(ctx, ammPool)
if err != nil {
return err
}
}
}

return nil
}
11 changes: 6 additions & 5 deletions x/leveragelp/migrations/v15_migration.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package migrations

import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/leveragelp/types"
)
Expand All @@ -10,11 +11,11 @@ func (m Migrator) V15Migration(ctx sdk.Context) error {

for _, legacyPool := range legacyPools {
newPool := types.Pool{
AmmPoolId: legacyPool.AmmPoolId,
Health: legacyPool.Health,
LeveragedLpAmount: legacyPool.LeveragedLpAmount,
LeverageMax: legacyPool.LeverageMax,
MaxLeveragelpPercent: sdk.NewDec(60),
AmmPoolId: legacyPool.AmmPoolId,
Health: legacyPool.Health,
LeveragedLpAmount: legacyPool.LeveragedLpAmount,
LeverageMax: legacyPool.LeverageMax,
MaxLeveragelpRatio: math.LegacyMustNewDecFromStr("0.6"),
}
m.keeper.SetPool(ctx, newPool)
}
Expand Down
10 changes: 5 additions & 5 deletions x/leveragelp/types/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (

func NewPool(poolId uint64, maxLeverage math.LegacyDec) Pool {
return Pool{
AmmPoolId: poolId,
Health: sdk.NewDec(100),
LeveragedLpAmount: sdk.ZeroInt(),
LeverageMax: sdk.NewDec(10),
MaxLeveragelpPercent: sdk.NewDec(60),
AmmPoolId: poolId,
Health: sdk.NewDec(100),
LeveragedLpAmount: sdk.ZeroInt(),
LeverageMax: sdk.NewDec(10),
MaxLeveragelpRatio: sdk.MustNewDecFromStr("0.6"),
}
}

Expand Down
40 changes: 20 additions & 20 deletions x/leveragelp/types/pool.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions x/perpetual/keeper/mtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (k Keeper) fillMTPData(ctx sdk.Context, mtp types.MTP, baseCurrency string)
fundingFeesInBaseCurrency = fundingFeesInBaseCurrency.ToLegacyDec().Mul(tradingAssetPrice).TruncateInt()
}

effectiveLeverage, err := k.UpdatedLeverage(ctx, mtp)
effectiveLeverage, err := k.GetEffectiveLeverage(ctx, mtp)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -348,8 +348,8 @@ func (k Keeper) GetEstimatedPnL(ctx sdk.Context, mtp types.MTP, baseCurrency str
// estimated_pnl = (custody_amount - collateral_amount) * market_price - totalLiabilities

// For long position, convert both custody and collateral to base currency
custodyAfterCollateralInBaseCurrecy := (custodyAmtAfterFunding.Sub(collateralAmt)).ToLegacyDec().Mul(tradingAssetPrice).TruncateInt()
estimatedPnL = custodyAfterCollateralInBaseCurrecy.Sub(totalLiabilities)
custodyAfterCollateralInBaseCurrency := (custodyAmtAfterFunding.Sub(collateralAmt)).ToLegacyDec().Mul(tradingAssetPrice).TruncateInt()
estimatedPnL = custodyAfterCollateralInBaseCurrency.Sub(totalLiabilities)
} else {
// estimated_pnl = custody_amount * market_price - totalLiabilities - collateral_amount

Expand Down
31 changes: 31 additions & 0 deletions x/perpetual/keeper/mtp_leverage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package keeper

import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/perpetual/types"
)

// GetEffectiveLeverage = custody / (custody - liabilities), has to be dimensionless
func (k Keeper) GetEffectiveLeverage(ctx sdk.Context, mtp types.MTP) (math.LegacyDec, error) {

// using swaps will have fees but this is just user facing value for a query
tradingAssetPrice, err := k.GetAssetPrice(ctx, mtp.TradingAsset)
if err != nil {
return math.LegacyDec{}, err
}

if mtp.Position == types.Position_LONG {
// custody is trading asset, liabilities are in usdc
custodyInLiabilitiesAsset := mtp.Custody.ToLegacyDec().Mul(tradingAssetPrice)
denominator := custodyInLiabilitiesAsset.Sub(mtp.Liabilities.ToLegacyDec())
effectiveLeverage := custodyInLiabilitiesAsset.Quo(denominator)
return effectiveLeverage, nil
} else {
// custody is usdc, liabilities are in trading asset
liabilitiesInCustodyAsset := mtp.Liabilities.ToLegacyDec().Mul(tradingAssetPrice)
denominator := mtp.Custody.ToLegacyDec().Sub(liabilitiesInCustodyAsset)
effectiveLeverage := mtp.Custody.ToLegacyDec().Quo(denominator)
return effectiveLeverage, nil
}
}
73 changes: 73 additions & 0 deletions x/perpetual/keeper/mtp_leverage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package keeper_test

import (
"cosmossdk.io/math"
ptypes "github.com/elys-network/elys/x/parameter/types"
"github.com/elys-network/elys/x/perpetual/types"
)

func (suite *PerpetualKeeperTestSuite) TestGetEffectiveLeverage() {
var mtp types.MTP
mtp.TradingAsset = ptypes.ATOM
testCases := []struct {
name string
expectErrMsg string
result math.LegacyDec
prerequisiteFunction func()
}{
{
"price not set",
"asset price uatom not found",
math.LegacyDec{},
func() {
},
},
{
"LONG",
"",
math.LegacyMustNewDecFromStr("1.176470588235294118"),
func() {
suite.SetupCoinPrices()
mtp.Position = types.Position_LONG
mtp.Custody = math.NewInt(100)
mtp.Liabilities = math.NewInt(75)
},
},
{
"SHORT",
"",
math.LegacyMustNewDecFromStr("2.666666666666666667"),
func() {
suite.SetupCoinPrices()
mtp.Position = types.Position_SHORT
mtp.Custody = math.NewInt(600)
mtp.Liabilities = math.NewInt(75)
},
},
{
"SHORT, bot should liquidate before leverage goes negative",
"",
math.LegacyMustNewDecFromStr("-0.363636363636363636"),
func() {
suite.SetupCoinPrices()
mtp.Position = types.Position_SHORT
mtp.Custody = math.NewInt(100)
mtp.Liabilities = math.NewInt(75)
},
},
}

for _, tc := range testCases {
suite.Run(tc.name, func() {
tc.prerequisiteFunction()
effectiveLeverage, err := suite.app.PerpetualKeeper.GetEffectiveLeverage(suite.ctx, mtp)
suite.Require().Equal(tc.result, effectiveLeverage)
if tc.expectErrMsg != "" {
suite.Require().Error(err)
suite.Require().Contains(err.Error(), tc.expectErrMsg)
} else {
suite.Require().NoError(err)
}
})
}
}
Loading

0 comments on commit 215f6de

Please sign in to comment.