-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: funding fee payment flow (#261)
* feat: funding fee payment flow * test: fix tests * test: fix * test: fix
- Loading branch information
1 parent
420c7e9
commit 4cf6bef
Showing
25 changed files
with
1,868 additions
and
167 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package keeper | ||
|
||
import ( | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
ammtypes "github.com/elys-network/elys/x/amm/types" | ||
"github.com/elys-network/elys/x/margin/types" | ||
) | ||
|
||
// HandleFundingFeeCollection handles funding fee collection | ||
func (k Keeper) HandleFundingFeeCollection(ctx sdk.Context, mtp *types.MTP, pool *types.Pool, ammPool ammtypes.Pool, collateralAsset string, custodyAsset string) error { | ||
// get funding rate | ||
fundingRate := pool.FundingRate | ||
|
||
// if funding rate is zero, return | ||
if fundingRate.IsZero() { | ||
return nil | ||
} | ||
|
||
// if funding rate is negative and mtp position is long or funding rate is positive and mtp position is short, return | ||
if (fundingRate.IsNegative() && mtp.Position == types.Position_LONG) || (fundingRate.IsPositive() && mtp.Position == types.Position_SHORT) { | ||
return nil | ||
} | ||
|
||
// get indexes | ||
collateralIndex, custodyIndex := types.GetMTPAssetIndex(mtp, collateralAsset, custodyAsset) | ||
|
||
// Calculate the take amount in custody asset | ||
takeAmountCustody := types.CalcTakeAmount(mtp.Custodies[custodyIndex], custodyAsset, fundingRate) | ||
|
||
// Swap the take amount to collateral asset | ||
takeAmountCollateralAmount, err := k.EstimateSwap(ctx, takeAmountCustody, collateralAsset, ammPool) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Create the take amount coin | ||
takeAmountCollateral := sdk.NewCoin(collateralAsset, takeAmountCollateralAmount) | ||
|
||
// Get funding fee collection address | ||
fundingFeeCollectionAddress := k.GetFundingFeeCollectionAddress(ctx) | ||
|
||
// Transfer take amount in collateral asset to funding fee collection address | ||
_, err = k.TakeFundPayment(ctx, takeAmountCollateral.Amount, collateralAsset, sdk.OneDec(), fundingFeeCollectionAddress, &ammPool) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// update mtp custody | ||
mtp.Custodies[custodyIndex] = mtp.Custodies[custodyIndex].Sub(takeAmountCustody) | ||
|
||
// add payment to total funding fee paid in collateral asset | ||
mtp.FundingFeePaidCollaterals[collateralIndex] = mtp.FundingFeePaidCollaterals[collateralIndex].Add(takeAmountCollateral) | ||
|
||
// add payment to total funding fee paid in custody asset | ||
mtp.FundingFeePaidCustodies[custodyIndex] = mtp.FundingFeePaidCustodies[custodyIndex].Add(takeAmountCustody) | ||
|
||
// emit event | ||
if !takeAmountCollateral.IsZero() { | ||
k.EmitFundingFeePayment(ctx, mtp, takeAmountCustody.Amount, collateralAsset, types.EventIncrementalPayFund) | ||
} | ||
|
||
// update pool custody balance | ||
err = pool.UpdateCustody(ctx, custodyAsset, takeAmountCustody.Amount, false, mtp.Position) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// update accounted balance for custody side | ||
err = pool.UpdateBalance(ctx, custodyAsset, takeAmountCustody.Amount, false, mtp.Position) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// update accounted balance for collateral side | ||
err = pool.UpdateBalance(ctx, collateralAsset, takeAmountCollateral.Amount, false, mtp.Position) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// apply changes to mtp object | ||
err = k.SetMTP(ctx, mtp) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// apply changes to pool object | ||
k.SetPool(ctx, *pool) | ||
|
||
// update mtp health | ||
_, err = k.UpdateMTPHealth(ctx, *mtp, ammPool, custodyAsset) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package keeper | ||
|
||
import ( | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
ammtypes "github.com/elys-network/elys/x/amm/types" | ||
"github.com/elys-network/elys/x/margin/types" | ||
) | ||
|
||
// HandleFundingFeeDistribution handles funding fee distribution | ||
func (k Keeper) HandleFundingFeeDistribution(ctx sdk.Context, mtps []*types.MTP, pool *types.Pool, ammPool ammtypes.Pool, baseCurrency string) error { | ||
// get funding rate | ||
fundingRate := pool.FundingRate | ||
|
||
// if funding rate is zero, return | ||
if fundingRate.IsZero() { | ||
return nil | ||
} | ||
|
||
// account liabilities from long position | ||
liabilitiesLong := sdk.ZeroInt() | ||
for _, asset := range pool.PoolAssetsLong { | ||
liabilitiesLong = liabilitiesLong.Add(asset.Liabilities) | ||
} | ||
|
||
// account liabilities from short position | ||
liabilitiesShort := sdk.ZeroInt() | ||
for _, asset := range pool.PoolAssetsShort { | ||
liabilitiesShort = liabilitiesShort.Add(asset.Liabilities) | ||
} | ||
|
||
// get funding fee collection address | ||
fundingFeeCollectionAddress := k.GetFundingFeeCollectionAddress(ctx) | ||
|
||
// get base currency balance | ||
balance := k.bankKeeper.GetBalance(ctx, fundingFeeCollectionAddress, baseCurrency) | ||
|
||
// if balance is zero, return | ||
if balance.IsZero() { | ||
return nil | ||
} | ||
|
||
for _, mtp := range mtps { | ||
// if funding rate is negative and mtp position is short or funding rate is positive and mtp position is long, return | ||
if (fundingRate.IsNegative() && mtp.Position == types.Position_SHORT) || (fundingRate.IsPositive() && mtp.Position == types.Position_LONG) { | ||
return nil | ||
} | ||
|
||
// get mtp address | ||
mtpAddress, err := sdk.AccAddressFromBech32(mtp.Address) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// calc funding fee share | ||
fundingFeeShare := sdk.ZeroDec() | ||
if fundingRate.IsNegative() && mtp.Position == types.Position_LONG { | ||
fundingFeeShare = sdk.NewDecFromInt(mtp.Liabilities).Quo(sdk.NewDecFromInt(liabilitiesLong)) | ||
} | ||
if fundingRate.IsPositive() && mtp.Position == types.Position_SHORT { | ||
fundingFeeShare = sdk.NewDecFromInt(mtp.Liabilities).Quo(sdk.NewDecFromInt(liabilitiesShort)) | ||
} | ||
|
||
// if funding fee share is zero, skip mtp | ||
if fundingFeeShare.IsZero() { | ||
continue | ||
} | ||
|
||
// calculate funding fee amount | ||
fundingFeeAmount := sdk.NewCoin(baseCurrency, sdk.NewDecFromInt(balance.Amount).Mul(fundingFeeShare).TruncateInt()) | ||
|
||
// transfer funding fee amount to mtp address | ||
if err := k.bankKeeper.SendCoins(ctx, fundingFeeCollectionAddress, mtpAddress, sdk.NewCoins(fundingFeeAmount)); err != nil { | ||
return err | ||
} | ||
|
||
// update received funding fee accounting buckets | ||
for custodyIndex, _ := range mtp.Custodies { | ||
for collateralIndex, collateral := range mtp.Collaterals { | ||
// Swap the take amount to collateral asset | ||
fundingFeeCollateralAmount, err := k.EstimateSwap(ctx, fundingFeeAmount, collateral.Denom, ammPool) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Create the take amount coin | ||
fundingFeeCollateral := sdk.NewCoin(collateral.Denom, fundingFeeCollateralAmount) | ||
|
||
// add payment to total funding fee paid in collateral asset | ||
mtp.FundingFeeReceivedCollaterals[collateralIndex] = mtp.FundingFeePaidCollaterals[collateralIndex].Add(fundingFeeCollateral) | ||
|
||
// add payment to total funding fee paid in custody asset | ||
mtp.FundingFeeReceivedCustodies[custodyIndex] = mtp.FundingFeePaidCustodies[custodyIndex].Add(fundingFeeAmount) | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.