-
Notifications
You must be signed in to change notification settings - Fork 44
/
handle_funding_fee_collection.go
93 lines (73 loc) · 2.88 KB
/
handle_funding_fee_collection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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/perpetual/types"
)
// HandleFundingFeeCollection handles funding fee collection
func (k Keeper) HandleFundingFeeCollection(ctx sdk.Context, mtp *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
}
// 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
}
// Calculate the take amount in custody asset
takeAmountCustodyAmount := types.CalcTakeAmount(mtp.Custody, mtp.CustodyAsset, fundingRate)
// Build the take amount coin
takeAmountCustody := sdk.NewCoin(mtp.CustodyAsset, takeAmountCustodyAmount)
// Swap the take amount to collateral asset
takeAmountCollateralAmount, err := k.EstimateSwap(ctx, takeAmountCustody, mtp.CollateralAsset, ammPool)
if err != nil {
return err
}
// Get funding fee collection address
fundingFeeCollectionAddress := k.GetFundingFeeCollectionAddress(ctx)
// Transfer take amount in collateral asset to funding fee collection address
_, err = k.TakeFundPayment(ctx, takeAmountCollateralAmount, mtp.CollateralAsset, sdk.OneDec(), fundingFeeCollectionAddress, &ammPool)
if err != nil {
return err
}
// update mtp custody
mtp.Custody = mtp.Custody.Sub(takeAmountCustodyAmount)
// add payment to total funding fee paid in collateral asset
mtp.FundingFeePaidCollateral = mtp.FundingFeePaidCollateral.Add(takeAmountCollateralAmount)
// add payment to total funding fee paid in custody asset
mtp.FundingFeePaidCustody = mtp.FundingFeePaidCustody.Add(takeAmountCustodyAmount)
// emit event
if !takeAmountCollateralAmount.IsZero() {
k.EmitFundingFeePayment(ctx, mtp, takeAmountCustody.Amount, mtp.CollateralAsset, types.EventIncrementalPayFund)
}
// update pool custody balance
err = pool.UpdateCustody(ctx, mtp.CustodyAsset, takeAmountCustody.Amount, false, mtp.Position)
if err != nil {
return err
}
// update accounted balance for custody side
err = pool.UpdateBalance(ctx, mtp.CustodyAsset, takeAmountCustody.Amount, false, mtp.Position)
if err != nil {
return err
}
// update accounted balance for collateral side
err = pool.UpdateBalance(ctx, mtp.CollateralAsset, takeAmountCollateralAmount, 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, baseCurrency)
if err != nil {
return err
}
return nil
}