Skip to content

Commit

Permalink
[Bug]: Leverage, Commitment (#747)
Browse files Browse the repository at this point in the history
* improvements

* remove

* migration script

* gen

* pool

* check

* user

* remove

* edge case

* remove
  • Loading branch information
amityadav0 authored Aug 29, 2024
1 parent 6eba904 commit c059c40
Show file tree
Hide file tree
Showing 12 changed files with 415 additions and 201 deletions.
465 changes: 297 additions & 168 deletions docs/static/openapi.yml

Large diffs are not rendered by default.

12 changes: 5 additions & 7 deletions proto/elys/leveragelp/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import "cosmos/base/v1beta1/coin.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "elys/leveragelp/params.proto";
import "elys/leveragelp/types.proto";

import "elys/leveragelp/pool.proto";

option go_package = "github.com/elys-network/elys/x/leveragelp/types";
Expand Down Expand Up @@ -119,7 +118,7 @@ message PositionsRequest {
}

message PositionsResponse {
repeated QueryPosition positions = 1;
repeated QueryPosition positions = 1;
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

Expand All @@ -129,7 +128,7 @@ message PositionsByPoolRequest {
}

message PositionsByPoolResponse {
repeated QueryPosition positions = 1;
repeated QueryPosition positions = 1;
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

Expand Down Expand Up @@ -187,7 +186,7 @@ message QueryAllPoolResponse {

message PositionResponse {
QueryPosition position = 1;
string locked_lp_token = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string locked_lp_token = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
}

message QueryLiquidationPriceRequest {
Expand Down Expand Up @@ -244,13 +243,12 @@ message QueryCommittedTokensLockedRequest {
}

message QueryCommittedTokensLockedResponse {
string address = 1;
string address = 1;
repeated cosmos.base.v1beta1.Coin locked_committed = 2 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
repeated cosmos.base.v1beta1.Coin total_committed = 3 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
}

message QueryPosition {
Position position = 1;
Position position = 1;
string updated_leverage = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}

7 changes: 5 additions & 2 deletions x/leveragelp/keeper/begin_blocker.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,11 @@ func (k Keeper) LiquidatePositionIfUnhealthy(ctx sdk.Context, position *types.Po

params := k.GetParams(ctx)
isHealthy = position.PositionHealth.GT(params.SafetyFactor)
if isHealthy {
return isHealthy, false, h, err

debt := k.stableKeeper.UpdateInterestAndGetDebt(ctx, position.GetPositionAddress())
liab := debt.GetTotalLiablities()
if isHealthy || liab.IsZero() {
return true, false, h, err
}

repayAmount, err := k.ForceCloseLong(ctx, *position, pool, position.LeveragedLpAmount)
Expand Down
5 changes: 4 additions & 1 deletion x/leveragelp/keeper/msg_server_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ func (k Keeper) Open(ctx sdk.Context, msg *types.MsgOpen) (*types.MsgOpenRespons
}

// Check if it is the same direction position for the same trader.
if position := k.CheckSamePosition(ctx, msg); position != nil {
if position, err := k.CheckSamePosition(ctx, msg); position != nil {
if err != nil {
return nil, err
}
response, err := k.OpenConsolidate(ctx, position, msg)
if err != nil {
return nil, err
Expand Down
67 changes: 65 additions & 2 deletions x/leveragelp/keeper/position.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ func (k Keeper) GetPositionHealth(ctx sdk.Context, position types.Position) (sdk

baseCurrency, found := k.assetProfileKeeper.GetUsdcDenom(ctx)
if !found {
return sdk.Dec{}, errorsmod.Wrapf(assetprofiletypes.ErrAssetProfileNotFound, "asset %s not found", ptypes.BaseCurrency)
return sdk.ZeroDec(), errorsmod.Wrapf(assetprofiletypes.ErrAssetProfileNotFound, "asset %s not found", ptypes.BaseCurrency)
}

leveragedLpAmount := sdk.ZeroInt()
Expand All @@ -270,7 +270,7 @@ func (k Keeper) GetPositionHealth(ctx sdk.Context, position types.Position) (sdk

exitCoinsAfterFee, _, err := k.amm.ExitPoolEst(ctx, position.GetAmmPoolId(), leveragedLpAmount, baseCurrency)
if err != nil {
return sdk.Dec{}, err
return sdk.ZeroDec(), err
}

exitAmountAfterFee := exitCoinsAfterFee.AmountOf(baseCurrency)
Expand Down Expand Up @@ -322,3 +322,66 @@ func (k Keeper) DeleteLegacyPosition(ctx sdk.Context, positionAddress string, id
store.Delete(key)
return nil
}

func (k Keeper) MigrateData(ctx sdk.Context) {
iterator := k.GetPositionIterator(ctx)
defer func(iterator sdk.Iterator) {
err := iterator.Close()
if err != nil {
panic(err)
}
}(iterator)

for ; iterator.Valid(); iterator.Next() {
var position types.Position
bytesValue := iterator.Value()
err := k.cdc.Unmarshal(bytesValue, &position)
if err == nil {
leveragedLpAmount := sdk.ZeroInt()
commitments := k.commKeeper.GetCommitments(ctx, position.GetPositionAddress())

for _, commitment := range commitments.CommittedTokens {
leveragedLpAmount = leveragedLpAmount.Add(commitment.Amount)
}
pool, found := k.GetPool(ctx, position.AmmPoolId)
if found {
pool.LeveragedLpAmount = pool.LeveragedLpAmount.Add(leveragedLpAmount)
pool.Health = k.CalculatePoolHealth(ctx, &pool)
k.SetPool(ctx, pool)
}

// Repay any balance, delete position
debt := k.stableKeeper.UpdateInterestAndGetDebt(ctx, position.GetPositionAddress())
repayAmount := debt.GetTotalLiablities()

// Check if position has enough coins to repay else repay partial
bal := k.bankKeeper.GetBalance(ctx, position.GetPositionAddress(), position.Collateral.Denom)
userAmount := sdk.ZeroInt()
if bal.Amount.LT(repayAmount) {
repayAmount = bal.Amount
} else {
userAmount = bal.Amount.Sub(repayAmount)
}

if repayAmount.IsPositive() {
k.stableKeeper.Repay(ctx, position.GetPositionAddress(), sdk.NewCoin(position.Collateral.Denom, repayAmount))
} else {
userAmount = bal.Amount
}

positionOwner := sdk.MustAccAddressFromBech32(position.Address)
if userAmount.IsPositive() {
k.bankKeeper.SendCoins(ctx, position.GetPositionAddress(), positionOwner, sdk.Coins{sdk.NewCoin(position.Collateral.Denom, userAmount)})
}

if leveragedLpAmount.IsZero() {
// Repay any balance, delete position
k.DestroyPosition(ctx, positionOwner, position.Id)
} else {
// Repay any balance and update position value
position.LeveragedLpAmount = leveragedLpAmount
k.SetPosition(ctx, &position)
}
}
}
}
21 changes: 11 additions & 10 deletions x/leveragelp/keeper/position_close.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ func (k Keeper) ForceCloseLong(ctx sdk.Context, position types.Position, pool ty
userAmount = exitCoinsAfterExitFee[0].Amount.Sub(repayAmount)
}

err = k.stableKeeper.Repay(ctx, position.GetPositionAddress(), sdk.NewCoin(position.Collateral.Denom, repayAmount))
if err != nil {
return sdk.ZeroInt(), err
if repayAmount.IsPositive() {
err = k.stableKeeper.Repay(ctx, position.GetPositionAddress(), sdk.NewCoin(position.Collateral.Denom, repayAmount))
if err != nil {
return sdk.ZeroInt(), err
}
} else {
userAmount = bal.Amount
}

positionOwner := sdk.MustAccAddressFromBech32(position.Address)
Expand All @@ -65,21 +69,18 @@ func (k Keeper) ForceCloseLong(ctx sdk.Context, position types.Position, pool ty
// Update leveragedLpAmount
position.LeveragedLpAmount = position.LeveragedLpAmount.Sub(lpAmount)
if position.LeveragedLpAmount.IsZero() {
err = k.masterchefKeeper.ClaimRewards(ctx, position.GetPositionAddress(), []uint64{position.AmmPoolId}, positionOwner)
if err != nil {
return sdk.ZeroInt(), err
}
// As we have already exited the pool, we need to delete the position
k.masterchefKeeper.ClaimRewards(ctx, position.GetPositionAddress(), []uint64{position.AmmPoolId}, positionOwner)
err = k.DestroyPosition(ctx, positionOwner, position.Id)
if err != nil {
return sdk.ZeroInt(), err
}
} else {
// Update position health
positionHealth, err := k.GetPositionHealth(ctx, position)
if err != nil {
return sdk.ZeroInt(), err
if err == nil {
position.PositionHealth = positionHealth
}
position.PositionHealth = positionHealth

// Update Liabilities
debt = k.stableKeeper.UpdateInterestAndGetDebt(ctx, position.GetPositionAddress())
Expand Down
6 changes: 3 additions & 3 deletions x/leveragelp/keeper/query_position.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package keeper

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
ammtypes "github.com/elys-network/elys/x/amm/types"
"github.com/elys-network/elys/x/leveragelp/types"
Expand All @@ -24,8 +24,8 @@ func (k Keeper) Position(goCtx context.Context, req *types.PositionRequest) (*ty

var positions = []*types.Position{}
positions = append(positions, &position)
updatedLeveragePosition, err := k.GetLeverageLpUpdatedLeverage(ctx, positions)

updatedLeveragePosition, err := k.GetLeverageLpUpdatedLeverage(ctx, positions)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions x/leveragelp/keeper/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ func (k Keeper) CheckUserAuthorization(ctx sdk.Context, msg *types.MsgOpen) erro
return nil
}

func (k Keeper) CheckSamePosition(ctx sdk.Context, msg *types.MsgOpen) *types.Position {
func (k Keeper) CheckSamePosition(ctx sdk.Context, msg *types.MsgOpen) (*types.Position, error) {
positions, _, err := k.GetPositionsForAddress(ctx, sdk.MustAccAddressFromBech32(msg.Creator), &query.PageRequest{})
if err != nil {
return nil
return nil, err
}
for _, position := range positions {
if position.Position.AmmPoolId == msg.AmmPoolId && position.Position.Collateral.Denom == msg.CollateralAsset {
return position.Position
return position.Position, nil
}
}

return nil
return nil, nil
}

func (k Keeper) CheckPoolHealth(ctx sdk.Context, poolId uint64) error {
Expand Down
2 changes: 1 addition & 1 deletion x/leveragelp/keeper/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (suite KeeperTestSuite) TestCheckSameAssets() {
}

// Expect no error
position = k.CheckSamePosition(suite.ctx, msg)
position, _ = k.CheckSamePosition(suite.ctx, msg)
suite.Require().NotNil(position)
}

Expand Down
17 changes: 17 additions & 0 deletions x/leveragelp/migrations/v10_migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package migrations

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

func (m Migrator) V10Migration(ctx sdk.Context) error {
pools := m.keeper.GetAllPools(ctx)
// Reset pools
for _, pool := range pools {
pool.LeveragedLpAmount = sdk.NewInt(0)
m.keeper.SetPool(ctx, pool)
}

m.keeper.MigrateData(ctx)
return nil
}
4 changes: 2 additions & 2 deletions x/leveragelp/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
m := migrations.NewMigrator(am.keeper)
err := cfg.RegisterMigration(types.ModuleName, 8, m.V9Migration)
err := cfg.RegisterMigration(types.ModuleName, 9, m.V10Migration)
if err != nil {
panic(err)
}
Expand All @@ -144,7 +144,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
}

// ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should be set to 1
func (AppModule) ConsensusVersion() uint64 { return 9 }
func (AppModule) ConsensusVersion() uint64 { return 10 }

// BeginBlock contains the logic that is automatically triggered at the beginning of each block
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
Expand Down
2 changes: 1 addition & 1 deletion x/leveragelp/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func NewParams() Params {
SafetyFactor: sdk.NewDecWithPrec(11, 1), // 1.1
WhitelistingEnabled: false,
FallbackEnabled: true,
NumberPerBlock: 1000,
NumberPerBlock: (int64)(1000),
}
}

Expand Down

0 comments on commit c059c40

Please sign in to comment.