Skip to content

Commit

Permalink
Merge branch 'main' into transfer_middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmic-vagabond authored Sep 21, 2023
2 parents 3f1d75a + 511b0eb commit 1f15354
Show file tree
Hide file tree
Showing 8 changed files with 964 additions and 55 deletions.
50 changes: 50 additions & 0 deletions x/margin/keeper/begin_blocker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package keeper

import (
"fmt"

"github.com/cosmos/cosmos-sdk/types/errors"

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

func (k Keeper) BeginBlocker(ctx sdk.Context) {
//check if epoch has passed then execute
epochLength := k.GetEpochLength(ctx)
epochPosition := k.GetEpochPosition(ctx, epochLength)

if epochPosition == 0 { // if epoch has passed
currentHeight := ctx.BlockHeight()
_ = currentHeight
pools := k.GetAllPools(ctx)
for _, pool := range pools {
// TODO: fields missing
// pool.BlockInterestExternal = sdk.ZeroUint()
// pool.BlockInterestNative = sdk.ZeroUint()
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.InterestRateComputation(ctx, pool, ammPool)
if err != nil {
ctx.Logger().Error(err.Error())
continue // ?
}
pool.InterestRate = rate
// TODO: field missing
// pool.LastHeightInterestRateComputed = 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)
}
}
k.SetPool(ctx, pool)
}
}

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

import (
"fmt"

"github.com/cosmos/cosmos-sdk/types/errors"

sdk "github.com/cosmos/cosmos-sdk/types"

ammtypes "github.com/elys-network/elys/x/amm/types"
"github.com/elys-network/elys/x/margin/types"
)

func BeginBlockerProcessMTP(ctx sdk.Context, k Keeper, mtp *types.MTP, pool types.Pool, ammPool ammtypes.Pool) {
defer func() {
if r := recover(); r != nil {
if msg, ok := r.(string); ok {
ctx.Logger().Error(msg)
}
}
}()
h, err := k.UpdateMTPHealth(ctx, *mtp, ammPool)
if err != nil {
ctx.Logger().Error(errors.Wrap(err, fmt.Sprintf("error updating mtp health: %s", mtp.String())).Error())
return
}
mtp.MtpHealth = h
// compute interest
// TODO: missing fields
// interestPayment := k.CalcMTPInterestLiabilities(ctx, *mtp, pool.InterestRate, 0, 0, ammPool, mtp.CollateralAssets[0])
// finalInterestPayment := k.HandleInterestPayment(ctx, mtp.CollateralAssets[0],mtp.CustodyAssets[0], interestPayment, mtp, &pool, ammPool)
// nativeAsset := types.GetSettlementAsset()
// if types.StringCompare(mtp.CollateralAsset, nativeAsset) { // custody is external, payment is custody
// pool.BlockInterestExternal = pool.BlockInterestExternal.Add(finalInterestPayment)
// } else { // custody is native, payment is custody
// pool.BlockInterestNative = pool.BlockInterestNative.Add(finalInterestPayment)
// }

_ = k.SetMTP(ctx, mtp)
// TODO: missing function
// repayAmount, err := k.ForceCloseLong(ctx, *mtp, pool, false, true)

if err == nil {
// TODO: missing function
// Emit event if position was closed
// k.EmitForceClose(ctx, mtp, repayAmount, "")
} else if err != types.ErrMTPUnhealthy {
ctx.Logger().Error(errors.Wrap(err, "error executing force close").Error())
}

}
2 changes: 1 addition & 1 deletion x/margin/keeper/open_long_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (k Keeper) ProcessOpenLong(ctx sdk.Context, mtp *types.MTP, leverage sdk.De
return nil, err
}
if !k.OpenLongChecker.HasSufficientPoolBalance(ctx, ammPool, ptypes.BaseCurrency, borrowingAmount) {
return nil, sdkerrors.Wrap(types.ErrBorrowTooHigh, leveragedAmount.String())
return nil, sdkerrors.Wrap(types.ErrBorrowTooHigh, borrowingAmount.String())
}
} else {
if !k.OpenLongChecker.HasSufficientPoolBalance(ctx, ammPool, msg.CollateralAsset, leveragedAmount) {
Expand Down
152 changes: 99 additions & 53 deletions x/margin/keeper/open_short_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,110 @@ package keeper

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

func (k Keeper) ProcessOpenShort(ctx sdk.Context, mtp *types.MTP, leverage sdk.Dec, eta sdk.Dec, collateralAmountDec sdk.Dec, poolId uint64, msg *types.MsgOpen) (*types.MTP, error) {
// Determine the trading asset.
// tradingAsset := k.OpenShortChecker.GetTradingAsset(msg.CollateralAsset, msg.BorrowAsset)

// // Fetch the pool associated with the given pool ID.
// pool, found := k.OpenShortChecker.GetPool(ctx, poolId)
// if !found {
// return nil, sdkerrors.Wrap(types.ErrPoolDoesNotExist, tradingAsset)
// }

// // Check if the pool is enabled.
// if !k.OpenShortChecker.IsPoolEnabled(ctx, poolId) {
// return nil, sdkerrors.Wrap(types.ErrMTPDisabled, tradingAsset)
// }

// // Fetch the corresponding AMM (Automated Market Maker) pool.
// ammPool, err := k.OpenShortChecker.GetAmmPool(ctx, poolId, tradingAsset)
// if err != nil {
// return nil, err
// }

// // Calculate the leveraged amount based on the collateral provided and the leverage.
// leveragedAmount := sdk.NewInt(collateralAmountDec.Mul(leverage).TruncateInt().Int64())

// // Borrow the asset the user wants to short.
// // err = k.OpenLongChecker.Borrow(ctx, msg.CollateralAsset, msg.BorrowAsset, msg.CollateralAmount, custodyAmount, mtp, &ammPool, &pool, eta)
// // if err != nil {
// // return nil, err
// // }

// // Calculate the custody amount.
// swappedAmount, err := k.OpenShortChecker.EstimateSwap(ctx, leveragedAmount, ptypes.BaseCurrency, ammPool)
// if err != nil {
// return nil, err
// }

// // Ensure the AMM pool has enough balance.
// if !k.OpenShortChecker.HasSufficientPoolBalance(ctx, ammPool, msg.BorrowAsset, swappedAmount) {
// return nil, sdkerrors.Wrap(types.ErrSwapTooHigh, swappedAmount.String())
// }

// // Additional checks and operations:
// // 1. Check minimum liabilities.
// err = k.OpenShortChecker.CheckMinLiabilities(ctx, swappedAmount, eta, pool, ammPool, msg.CollateralAsset)
// if err != nil {
// return nil, err
// }

// // 2. Update the pool and MTP health.
// if err = k.OpenShortChecker.UpdatePoolHealth(ctx, &pool); err != nil {
// return nil, err
// }
// if err = k.OpenShortChecker.UpdateMTPHealth(ctx, *mtp, ammPool); err != nil {
// return nil, err
// }
tradingAsset := k.OpenShortChecker.GetTradingAsset(msg.CollateralAsset, msg.BorrowAsset)

// Fetch the pool associated with the given pool ID.
pool, found := k.OpenShortChecker.GetPool(ctx, poolId)
if !found {
return nil, sdkerrors.Wrap(types.ErrPoolDoesNotExist, tradingAsset)
}

// Check if the pool is enabled.
if !k.OpenShortChecker.IsPoolEnabled(ctx, poolId) {
return nil, sdkerrors.Wrap(types.ErrMTPDisabled, tradingAsset)
}

// Fetch the corresponding AMM (Automated Market Maker) pool.
ammPool, err := k.OpenShortChecker.GetAmmPool(ctx, poolId, tradingAsset)
if err != nil {
return nil, err
}

// Calculate the leveraged amount based on the collateral provided and the leverage.
leveragedAmount := sdk.NewInt(collateralAmountDec.Mul(leverage).TruncateInt().Int64())

if msg.CollateralAsset != ptypes.BaseCurrency {
return nil, sdkerrors.Wrap(types.ErrInvalidBorrowingAsset, "collateral must be base currency")
}

custodyAmtToken := sdk.NewCoin(ptypes.BaseCurrency, leveragedAmount)
borrowingAmount, err := k.OpenShortChecker.EstimateSwapGivenOut(ctx, custodyAmtToken, msg.BorrowAsset, ammPool)
if err != nil {
return nil, err
}

// check the balance
if !k.OpenShortChecker.HasSufficientPoolBalance(ctx, ammPool, ptypes.BaseCurrency, borrowingAmount) {
return nil, sdkerrors.Wrap(types.ErrBorrowTooHigh, borrowingAmount.String())
}

// Check minimum liabilities.
collateralTokenAmt := sdk.NewCoin(msg.CollateralAsset, msg.CollateralAmount)
err = k.OpenShortChecker.CheckMinLiabilities(ctx, collateralTokenAmt, eta, pool, ammPool, msg.BorrowAsset)
if err != nil {
return nil, err
}

// Calculate custody amount.
leveragedAmtTokenIn := sdk.NewCoin(msg.BorrowAsset, borrowingAmount)
custodyAmount, err := k.OpenShortChecker.EstimateSwap(ctx, leveragedAmtTokenIn, ptypes.BaseCurrency, ammPool)
if err != nil {
return nil, err
}

// Ensure the AMM pool has enough balance.
if !k.OpenShortChecker.HasSufficientPoolBalance(ctx, ammPool, ptypes.BaseCurrency, custodyAmount) {
return nil, sdkerrors.Wrap(types.ErrCustodyTooHigh, custodyAmount.String())
}

// if position is short then override the custody asset to the base currency
if mtp.Position == types.Position_SHORT {
mtp.CustodyAssets = []string{ptypes.BaseCurrency}
}

// Borrow the asset the user wants to short.
err = k.OpenShortChecker.Borrow(ctx, msg.CollateralAsset, ptypes.BaseCurrency, msg.CollateralAmount, custodyAmount, mtp, &ammPool, &pool, eta)
if err != nil {
return nil, err
}

// Update the pool health.
if err = k.OpenShortChecker.UpdatePoolHealth(ctx, &pool); err != nil {
return nil, err
}

// Take custody from the pool balance.
if err = k.OpenShortChecker.TakeInCustody(ctx, *mtp, &pool); err != nil {
return nil, err
}

// Update the MTP health.
lr, err := k.OpenShortChecker.UpdateMTPHealth(ctx, *mtp, ammPool)
if err != nil {
return nil, err
}

// Check if the MTP is unhealthy
safetyFactor := k.OpenShortChecker.GetSafetyFactor(ctx)
if lr.LTE(safetyFactor) {
return nil, types.ErrMTPUnhealthy
}

// Update consolidated collateral amount
k.OpenShortChecker.CalcMTPConsolidateCollateral(ctx, mtp)

// Calculate consolidate liabiltiy
k.OpenShortChecker.CalcMTPConsolidateLiability(ctx, mtp)

// Set MTP
k.OpenShortChecker.SetMTP(ctx, mtp)

// Return the updated Margin Trading Position (MTP).
return mtp, nil
Expand Down
Loading

0 comments on commit 1f15354

Please sign in to comment.