Skip to content

Commit

Permalink
Merge branch 'develop' into reward_scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
ze97286 authored Sep 5, 2024
2 parents c628e44 + 2985b37 commit b73aec7
Show file tree
Hide file tree
Showing 38 changed files with 5,123 additions and 4,017 deletions.
21 changes: 18 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,29 @@

### 🛠 Improvements

- [11644](https://github.com/vegaprotocol/vega/issues/11644) - `liveOnly` flag has been added to the `AMM` API to show only active `AMMs`.
- [](https://github.com/vegaprotocol/vega/issues/xxx)

### 🐛 Fixes

- [](https://github.com/vegaprotocol/vega/issues/xxx)


## 0.78.2

### 🛠 Improvements

- [11644](https://github.com/vegaprotocol/vega/issues/11644) - `liveOnly` flag has been added to the `AMM` API to show only active `AMMs`.

### 🐛 Fixes

- [11652](https://github.com/vegaprotocol/vega/issues/11652) - Apply fees and discounts on network disposal trades.
- [11645](https://github.com/vegaprotocol/vega/issues/11645) - Support party stats with no markets to retrieve for all markets.
- [11655](https://github.com/vegaprotocol/vega/issues/11655) - Liquidity fees paid does not like type derived party flag.
- [11650](https://github.com/vegaprotocol/vega/issues/11650) - Add include sub accounts flag to `listPositions`.
- [11641](https://github.com/vegaprotocol/vega/issues/11641) - Panic with pegged orders.
- [11646](https://github.com/vegaprotocol/vega/issues/11646) - Add tier numbers to API.


## 0.78.1

### 🐛 Fixes
Expand All @@ -27,8 +43,6 @@
- [11583](https://github.com/vegaprotocol/vega/issues/11583) - Rough bound on price interval when matching with `AMMs` is now looser and calculated in the `AMM` engine.
- [11624](https://github.com/vegaprotocol/vega/issues/11624) - prevent creation of rewards with no payout, but with high computational cost.
- [11619](https://github.com/vegaprotocol/vega/issues/11619) - Fix `EstimatePositions` API for capped futures.
- [11645](https://github.com/vegaprotocol/vega/issues/11645) - Support party stats with no markets to retrieve for all markets.


## 0.78.0

Expand All @@ -54,6 +68,7 @@
- [11612](https://github.com/vegaprotocol/vega/issues/11612) - Reward scaling support.
-[11624](https://github.com/vegaprotocol/vega/issues/11624) - prevent creation of rewards with no payout, but with high computational cost.
- [11624](https://github.com/vegaprotocol/vega/issues/11624) - prevent creation of rewards with no payout, but with high computational cost.
- [11512](https://github.com/vegaprotocol/vega/issues/11512) - Add loss socialisation amounts to funding payment API.

### 🐛 Fixes

Expand Down
11 changes: 6 additions & 5 deletions core/collateral/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,7 @@ func (e *Engine) FinalSettlement(ctx context.Context, marketID string, transfers
logging.String("market-id", settle.MarketID))

brokerEvts = append(brokerEvts,
events.NewLossSocializationEvent(ctx, transfer.Owner, marketID, delta, false, now))
events.NewLossSocializationEvent(ctx, transfer.Owner, marketID, delta, false, now, types.LossTypeUnspecified))
}
}
}
Expand Down Expand Up @@ -1476,16 +1476,16 @@ func (e *Engine) getMTMPartyAccounts(party, marketID, asset string) (gen, margin
// PerpsFundingSettlement will run a funding settlement over given positions.
// This works exactly the same as a MTM settlement, but uses different transfer types.
func (e *Engine) PerpsFundingSettlement(ctx context.Context, marketID string, transfers []events.Transfer, asset string, round *num.Uint, useGeneralAccountForMarginSearch func(string) bool) ([]events.Margin, []*types.LedgerMovement, error) {
return e.mtmOrFundingSettlement(ctx, marketID, transfers, asset, types.TransferTypePerpFundingWin, round, useGeneralAccountForMarginSearch)
return e.mtmOrFundingSettlement(ctx, marketID, transfers, asset, types.TransferTypePerpFundingWin, round, useGeneralAccountForMarginSearch, types.LossTypeFunding)
}

// MarkToMarket will run the mark to market settlement over a given set of positions
// return ledger move stuff here, too (separate return value, because we need to stream those).
func (e *Engine) MarkToMarket(ctx context.Context, marketID string, transfers []events.Transfer, asset string, useGeneralAccountForMarginSearch func(string) bool) ([]events.Margin, []*types.LedgerMovement, error) {
return e.mtmOrFundingSettlement(ctx, marketID, transfers, asset, types.TransferTypeMTMWin, nil, useGeneralAccountForMarginSearch)
return e.mtmOrFundingSettlement(ctx, marketID, transfers, asset, types.TransferTypeMTMWin, nil, useGeneralAccountForMarginSearch, types.LossTypeSettlement)
}

func (e *Engine) mtmOrFundingSettlement(ctx context.Context, marketID string, transfers []events.Transfer, asset string, winType types.TransferType, round *num.Uint, useGeneralAccountForMarginSearch func(string) bool) ([]events.Margin, []*types.LedgerMovement, error) {
func (e *Engine) mtmOrFundingSettlement(ctx context.Context, marketID string, transfers []events.Transfer, asset string, winType types.TransferType, round *num.Uint, useGeneralAccountForMarginSearch func(string) bool, lType types.LossType) ([]events.Margin, []*types.LedgerMovement, error) {
// stop immediately if there aren't any transfers, channels are closed
if len(transfers) == 0 {
return nil, nil, nil
Expand Down Expand Up @@ -1616,7 +1616,7 @@ func (e *Engine) mtmOrFundingSettlement(ctx context.Context, marketID string, tr
logging.String("market-id", settle.MarketID))

brokerEvts = append(brokerEvts,
events.NewLossSocializationEvent(ctx, party, settle.MarketID, delta, false, now))
events.NewLossSocializationEvent(ctx, party, settle.MarketID, delta, false, now, lType))
}
marginEvts = append(marginEvts, marginEvt)
} else {
Expand Down Expand Up @@ -1652,6 +1652,7 @@ func (e *Engine) mtmOrFundingSettlement(ctx context.Context, marketID string, tr
collected: settle.Balance,
requests: make([]request, 0, len(transfers)-winidx),
ts: now,
lType: lType,
}

if distr.LossSocializationEnabled() {
Expand Down
7 changes: 5 additions & 2 deletions core/collateral/simple_distributor.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type simpleDistributor struct {
collected *num.Uint
requests []request
ts int64
lType types.LossType
}

func (s *simpleDistributor) LossSocializationEnabled() bool {
Expand Down Expand Up @@ -73,7 +74,7 @@ func (s *simpleDistributor) Run(ctx context.Context) []events.Event {
v := v
netReq = &v
}
evt = events.NewLossSocializationEvent(ctx, v.request.Owner, s.marketID, loss, true, s.ts)
evt = events.NewLossSocializationEvent(ctx, v.request.Owner, s.marketID, loss, true, s.ts, s.lType)
s.log.Warn("loss socialization missing funds to be distributed",
logging.String("party-id", evt.PartyID()),
logging.BigInt("amount", evt.Amount()),
Expand All @@ -99,7 +100,9 @@ func (s *simpleDistributor) Run(ctx context.Context) []events.Event {
evt.MarketID(),
loss,
!profit, // true if party still lost out, false if mismatch > shortfall
s.ts)
s.ts,
s.lType,
)
}
return evts
}
22 changes: 18 additions & 4 deletions core/events/loss_socialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package events
import (
"context"

"code.vegaprotocol.io/vega/core/types"
"code.vegaprotocol.io/vega/libs/num"
eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1"
)
Expand All @@ -28,9 +29,10 @@ type LossSoc struct {
marketID string
amount *num.Int
ts int64
lType types.LossType
}

func NewLossSocializationEvent(ctx context.Context, partyID, marketID string, amount *num.Uint, neg bool, ts int64) *LossSoc {
func NewLossSocializationEvent(ctx context.Context, partyID, marketID string, amount *num.Uint, neg bool, ts int64, lType types.LossType) *LossSoc {
signedAmount := num.NewIntFromUint(amount)
if neg {
signedAmount.FlipSign()
Expand All @@ -41,9 +43,18 @@ func NewLossSocializationEvent(ctx context.Context, partyID, marketID string, am
marketID: marketID,
amount: signedAmount,
ts: ts,
lType: lType,
}
}

func (l LossSoc) LossType() types.LossType {
return l.lType
}

func (l LossSoc) IsFunding() bool {
return l.lType == types.LossTypeFunding
}

func (l LossSoc) IsParty(id string) bool {
return l.partyID == id
}
Expand Down Expand Up @@ -73,6 +84,7 @@ func (l LossSoc) Proto() eventspb.LossSocialization {
MarketId: l.marketID,
PartyId: l.partyID,
Amount: l.amount.String(),
LossType: l.lType,
}
}

Expand All @@ -88,12 +100,14 @@ func (l LossSoc) StreamMessage() *eventspb.BusEvent {
}

func LossSocializationEventFromStream(ctx context.Context, be *eventspb.BusEvent) *LossSoc {
ls := be.GetLossSocialization()
lse := &LossSoc{
Base: newBaseFromBusEvent(ctx, LossSocializationEvent, be),
partyID: be.GetLossSocialization().PartyId,
marketID: be.GetLossSocialization().MarketId,
partyID: ls.PartyId,
marketID: ls.MarketId,
lType: ls.LossType,
}

lse.amount, _ = num.IntFromString(be.GetLossSocialization().Amount, 10)
lse.amount, _ = num.IntFromString(ls.Amount, 10)
return lse
}
2 changes: 1 addition & 1 deletion core/execution/future/liquidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (m *Market) checkNetwork(ctx context.Context, now time.Time) error {
return nil
}
// transfer fees to the good party -> fees are now taken from the insurance pool
fees, _ := m.fee.GetFeeForPositionResolution(conf.Trades)
fees, _ := m.fee.GetFeeForPositionResolution(conf.Trades, m.referralDiscountRewardService, m.volumeDiscountService, m.volumeRebateService)
tresps, err := m.collateral.TransferFees(ctx, m.GetID(), m.settlementAsset, fees)
if err != nil {
// we probably should reject the order, although if we end up here we have a massive problem.
Expand Down
71 changes: 57 additions & 14 deletions core/fee/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func (e *Engine) CalculateForContinuousMode(

e.feesStats.RegisterMakerFee(maker, taker, fee.MakerFee)

totalTradingFees := num.UintZero().AddSum(fee.MakerFee, fee.InfrastructureFee, fee.LiquidityFee)
totalTradingFees := num.UintZero().AddSum(fee.MakerFee, fee.InfrastructureFee, fee.LiquidityFee, fee.BuyBackFee, fee.TreasuryFee, fee.HighVolumeMakerFee)

switch trade.Aggressor {
case types.SideBuy:
Expand Down Expand Up @@ -451,26 +451,41 @@ func (e *Engine) CalculateForFrequentBatchesAuctionMode(
}, nil
}

func (e *Engine) GetFeeForPositionResolution(trades []*types.Trade) (events.FeesTransfer, *types.Fee) {
func (e *Engine) GetFeeForPositionResolution(trades []*types.Trade,
referral ReferralDiscountRewardService,
volumeDiscount VolumeDiscountService,
volumeRebate VolumeRebateService,
) (events.FeesTransfer, *types.Fee) {
if len(trades) == 0 {
return nil, nil
}
var (
netFee *types.Fee
gt *types.Transfer
gt []*types.Transfer
)
transfers := make([]*types.Transfer, 0, len(trades))
for _, t := range trades {
fees := e.calculateContinuousModeFees(t)

maker := t.Buyer
if t.Buyer == types.NetworkParty {
maker = t.Seller
}
size := num.NewUint(t.Size)
// multiply by size
tradeValueForFee := size.Mul(t.Price, size).ToDecimal().Div(e.positionFactor)
postRewardDiscountFees, _ := e.applyDiscountsAndRewards(types.NetworkParty, maker, tradeValueForFee, fees, referral, volumeDiscount, volumeRebate)
e.feesStats.RegisterMakerFee(maker, types.NetworkParty, postRewardDiscountFees.MakerFee)

goodParty := t.Buyer
t.SellerFee = fees
t.SellerFee = postRewardDiscountFees
if t.Buyer == types.NetworkParty {
goodParty = t.Seller
t.SellerFee = types.NewFee()
t.BuyerFee = fees
t.BuyerFee = postRewardDiscountFees
}
netFee, gt = e.getNetworkFeeWithMakerTransfer(fees, netFee, goodParty)
transfers = append(transfers, gt)
netFee, gt = e.getNetworkFeeWithMakerTransfer(postRewardDiscountFees, netFee, goodParty)
transfers = append(transfers, gt...)
}
netTf, total := e.getNetworkFeeTransfers(netFee)
// calculate the
Expand Down Expand Up @@ -549,29 +564,44 @@ func (e *Engine) buildLiquidityFeesTransfer(
return ft
}

func (e *Engine) getNetworkFeeWithMakerTransfer(fees *types.Fee, current *types.Fee, goodParty string) (*types.Fee, *types.Transfer) {
transfer := &types.Transfer{
func (e *Engine) getNetworkFeeWithMakerTransfer(fees *types.Fee, current *types.Fee, goodParty string) (*types.Fee, []*types.Transfer) {
transfers := []*types.Transfer{}
transfers = append(transfers, &types.Transfer{
Owner: goodParty,
Amount: &types.FinancialAmount{
Asset: e.asset,
Amount: fees.MakerFee,
Amount: fees.MakerFee.Clone(),
},
MinAmount: num.UintZero(),
Type: types.TransferTypeMakerFeeReceive,
})
if !fees.HighVolumeMakerFee.IsZero() {
transfers = append(transfers, &types.Transfer{
Owner: goodParty,
Amount: &types.FinancialAmount{
Asset: e.asset,
Amount: fees.HighVolumeMakerFee,
},
MinAmount: num.UintZero(),
Type: types.TransferTypeHighMakerRebateReceive,
})
}

if current == nil {
return fees.Clone(), transfer
return fees.Clone(), transfers
}
current.MakerFee.AddSum(fees.MakerFee)
current.LiquidityFee.AddSum(fees.LiquidityFee)
current.InfrastructureFee.AddSum(fees.InfrastructureFee)
current.BuyBackFee.AddSum(fees.BuyBackFee)
current.TreasuryFee.AddSum(fees.TreasuryFee)
return current, transfer
current.HighVolumeMakerFee.AddSum(fees.HighVolumeMakerFee)

return current, transfers
}

func (e *Engine) getNetworkFeeTransfers(fees *types.Fee) ([]*types.Transfer, *num.Uint) {
return []*types.Transfer{
transfers := []*types.Transfer{
{
Owner: types.NetworkParty,
Amount: &types.FinancialAmount{
Expand Down Expand Up @@ -617,7 +647,20 @@ func (e *Engine) getNetworkFeeTransfers(fees *types.Fee) ([]*types.Transfer, *nu
MinAmount: num.UintZero(),
Type: types.TransferTypeTreasuryPay,
},
}, num.Sum(fees.MakerFee, fees.InfrastructureFee, fees.LiquidityFee)
}
if !fees.HighVolumeMakerFee.IsZero() {
transfers = append(transfers, &types.Transfer{
Owner: types.NetworkParty,
Amount: &types.FinancialAmount{
Asset: e.asset,
Amount: fees.HighVolumeMakerFee.Clone(),
},
MinAmount: num.UintZero(),
Type: types.TransferTypeHighMakerRebatePay,
})
}

return transfers, num.Sum(fees.MakerFee, fees.InfrastructureFee, fees.LiquidityFee, fees.BuyBackFee, fees.HighVolumeMakerFee)
}

func (e *Engine) applyDiscountsAndRewards(taker string, maker string, tradeValueForFeePurposes num.Decimal, fees *types.Fee, referral ReferralDiscountRewardService, volumeDiscount VolumeDiscountService, volumeRebate VolumeRebateService) (*types.Fee, *types.ReferrerReward) {
Expand Down
19 changes: 12 additions & 7 deletions core/fee/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,8 @@ func testCalcContinuousTradingAndCheckAmountsExtended(t *testing.T) {
TotalFeesPaidAndReceived: []*eventspb.PartyAmount{
{
Party: "party1",
Amount: "875",
QuantumAmount: "875",
Amount: "3375",
QuantumAmount: "3375",
},
{
Party: "party2",
Expand Down Expand Up @@ -744,8 +744,8 @@ func testCalcContinuousTradingAndCheckAmountsWithDiscountExtended(t *testing.T)
TotalFeesPaidAndReceived: []*eventspb.PartyAmount{
{
Party: "party1",
Amount: "443",
QuantumAmount: "443",
Amount: "2943",
QuantumAmount: "2943",
},
{
Party: "party2",
Expand Down Expand Up @@ -1204,7 +1204,7 @@ func testCalcContinuousTradingExtended(t *testing.T) {
feeAmounts := ft.TotalFeesAmountPerParty()
party1Amount, ok := feeAmounts["party1"]
assert.True(t, ok)
assert.Equal(t, num.NewUint(43928), party1Amount)
assert.Equal(t, num.NewUint(45221), party1Amount)

// get the transfer and check we have enough of each types
transfers := ft.Transfers()
Expand Down Expand Up @@ -1670,12 +1670,17 @@ func testCalcBatchAuctionTradingDifferentBatches(t *testing.T) {
func testCloseoutFees(t *testing.T) {
eng := getTestFee(t)
ctrl := gomock.NewController(t)
referralDiscountService := mocks.NewMockReferralDiscountRewardService(ctrl)
referralDiscountService.EXPECT().RewardsFactorsMultiplierAppliedForParty(gomock.Any()).Return(types.EmptyFactors).AnyTimes()
discountRewardService := mocks.NewMockReferralDiscountRewardService(ctrl)
volumeDiscountService := mocks.NewMockVolumeDiscountService(ctrl)
volumeRebateService := mocks.NewMockVolumeRebateService(ctrl)
discountRewardService.EXPECT().ReferralDiscountFactorsForParty(gomock.Any()).Return(types.EmptyFactors).AnyTimes()
discountRewardService.EXPECT().RewardsFactorsMultiplierAppliedForParty(gomock.Any()).Return(types.EmptyFactors).AnyTimes()
volumeDiscountService.EXPECT().VolumeDiscountFactorForParty(gomock.Any()).Return(types.EmptyFactors).AnyTimes()
discountRewardService.EXPECT().GetReferrer(gomock.Any()).Return(types.PartyID(""), errors.New("not a referrer")).AnyTimes()
referralDiscountService.EXPECT().ReferralDiscountFactorsForParty(gomock.Any()).Return(types.EmptyFactors).AnyTimes()
volumeRebateService.EXPECT().VolumeRebateFactorForParty(gomock.Any()).Return(num.DecimalZero()).AnyTimes()
trades := []*types.Trade{
{
Aggressor: types.SideSell,
Expand Down Expand Up @@ -1707,10 +1712,10 @@ func testCloseoutFees(t *testing.T) {
},
}

ft, fee := eng.GetFeeForPositionResolution(trades)
ft, fee := eng.GetFeeForPositionResolution(trades, referralDiscountService, volumeDiscountService, volumeRebateService)
assert.NotNil(t, fee)
allTransfers := ft.Transfers()
// first we have the network -> pay transfers, then 1 transfer per good party
// first we have the network -> pay transfers , then 1 transfer per good party
// two additional transfers for the buy back and treasury fees
assert.Equal(t, len(trades), len(allTransfers)-5)
goodPartyTransfers := allTransfers[5:]
Expand Down
Loading

0 comments on commit b73aec7

Please sign in to comment.