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 Aug 23, 2024
2 parents b6c3baa + 7156f91 commit b322570
Show file tree
Hide file tree
Showing 46 changed files with 4,283 additions and 15,518 deletions.
13 changes: 10 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
- [11546](https://github.com/vegaprotocol/vega/issues/11546) - Add validation to market proposals metadata.
- [11562](https://github.com/vegaprotocol/vega/issues/11562) - Update average notional metric with mark price at the end of the epoch and when calculating live score.
- [11570](https://github.com/vegaprotocol/vega/issues/11570) - Include the required set of parties for evaluation for eligible entities reward.
- [11576](https://github.com/vegaprotocol/vega/issues/11576) - Replace additional rebate validation with a cap.
- [11533](https://github.com/vegaprotocol/vega/issues/11533) - Suppose per party fee discounts in fee estimation.
- [11576](https://github.com/vegaprotocol/vega/issues/11576) - Replace additional rebate validation with a cap.
- [11533](https://github.com/vegaprotocol/vega/issues/11533) - Suppose per party fee discounts in fee estimation.
- [11577](https://github.com/vegaprotocol/vega/issues/11577) - Add API for party discounts and rewards.
- [10716](https://github.com/vegaprotocol/vega/issues/10716) - Set Tendermint defaults during init.


### 🐛 Fixes

Expand All @@ -40,7 +43,11 @@
- [11544](https://github.com/vegaprotocol/vega/issues/11544) - Fix empty candles stream.
- [11579](https://github.com/vegaprotocol/vega/issues/11579) - Spot calculate fee on amend, use order price if no amended price is provided.
- [11585](https://github.com/vegaprotocol/vega/issues/11585) - Initialise rebate stats service in API.
- [11592](https://github.com/vegaprotocol/vega/issues/11592) - Fix the order of calls at end of epoch between rebate engine and market tracker.
- [11592](https://github.com/vegaprotocol/vega/issues/11592) - Fix the order of calls at end of epoch between rebate engine and market tracker.
- [11607](https://github.com/vegaprotocol/vega/issues/11607) - Wire rank lottery distribution to team reward payout.
- [959](https://github.com/vegaprotocol/core-test-coverage/issues/959) - Include `ELS` for `AMM` sub keys to the parent key `ELS`.
- [11592](https://github.com/vegaprotocol/vega/issues/11592) - Fix the order of calls at end of epoch between rebate engine and market tracker.


## 0.77.5

Expand Down
13 changes: 13 additions & 0 deletions cmd/vega/commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"time"

"code.vegaprotocol.io/vega/core/config"
Expand Down Expand Up @@ -127,7 +128,19 @@ func (opts *InitCmd) Execute(args []string) error {
if !initCmd.NoTendermint {
tmCfg := tmcfg.DefaultConfig()
tmCfg.SetRoot(os.ExpandEnv(initCmd.TendermintHome))
// add a few defaults
tmCfg.P2P.MaxPacketMsgPayloadSize = 16384
tmCfg.P2P.SendRate = 20000000
tmCfg.P2P.RecvRate = 20000000
tmCfg.Mempool.Size = 10000
tmCfg.Mempool.CacheSize = 20000
tmCfg.Consensus.TimeoutCommit = 0 * time.Second
tmCfg.Consensus.SkipTimeoutCommit = true
tmCfg.Consensus.CreateEmptyBlocksInterval = 1 * time.Second
tmCfg.Storage.DiscardABCIResponses = true
tmcfg.EnsureRoot(tmCfg.RootDir)
// then rewrite the config to apply the changes, EnsureRoot create the config, but with a default config
tmcfg.WriteConfigFile(filepath.Join(tmCfg.RootDir, tmcfg.DefaultConfigDir, tmcfg.DefaultConfigFileName), tmCfg)
if err := initTendermintConfiguration(output, logger, tmCfg); err != nil {
return fmt.Errorf("couldn't initialise tendermint %w", err)
}
Expand Down
14 changes: 13 additions & 1 deletion commands/create_referral_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@

package commands

import commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
import (
"errors"

commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
)

func CheckCreateReferralSet(cmd *commandspb.CreateReferralSet) error {
return checkCreateReferralSet(cmd).ErrorOrNil()
Expand All @@ -28,6 +32,14 @@ func checkCreateReferralSet(cmd *commandspb.CreateReferralSet) Errors {
return errs.FinalAddForProperty("create_referral_set", ErrIsRequired)
}

// Basically this command should be rejected if we are not creating a team
// but also not creating a referral set...
// just check if this command is ineffective...
if cmd.DoNotCreateReferralSet && !cmd.IsTeam {
return errs.FinalAddForProperty("create_referral_set",
errors.New("is ineffective"))
}

if cmd.IsTeam {
if cmd.Team == nil {
return errs.FinalAddForProperty("create_referral_set.team", ErrIsRequired)
Expand Down
1 change: 1 addition & 0 deletions core/execution/common/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ type CommonMarket interface {
GetMarketData() types.MarketData
StartOpeningAuction(context.Context) error
GetEquityShares() *EquityShares
GetEquitySharesForParty(partyID string) num.Decimal
IntoType() types.Market
OnEpochEvent(ctx context.Context, epoch types.Epoch)
OnEpochRestore(ctx context.Context, epoch types.Epoch)
Expand Down
2 changes: 1 addition & 1 deletion core/execution/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -1457,7 +1457,7 @@ func (e *Engine) GetMarket(market string, settled bool) (types.Market, bool) {
// party in the given market. If the market doesn't exist, it returns false.
func (e *Engine) GetEquityLikeShareForMarketAndParty(market, party string) (num.Decimal, bool) {
if mkt, ok := e.allMarkets[market]; ok {
return mkt.GetEquityShares().SharesFromParty(party), true
return mkt.GetEquitySharesForParty(party), true
}
return num.DecimalZero(), false
}
Expand Down
8 changes: 8 additions & 0 deletions core/execution/future/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,14 @@ func (m *Market) GetEquityShares() *common.EquityShares {
return m.equityShares
}

func (m *Market) GetEquitySharesForParty(partyID string) num.Decimal {
primary := m.equityShares.SharesFromParty(partyID)
if sub, err := m.amm.GetAMMParty(partyID); err == nil {
return primary.Add(m.equityShares.SharesFromParty(sub))
}
return primary
}

func (m *Market) ResetParentIDAndInsurancePoolFraction() {
m.mkt.ParentMarketID = ""
m.mkt.InsurancePoolFraction = num.DecimalZero()
Expand Down
9 changes: 9 additions & 0 deletions core/execution/spot/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,15 @@ func (m *Market) GetEquityShares() *common.EquityShares {
return m.equityShares
}

func (m *Market) GetEquitySharesForParty(partyID string) num.Decimal {
primary := m.equityShares.SharesFromParty(partyID)
// AMM for spot has not been implemented yet
// if sub, err := m.amm.GetAMMParty(partyID); err == nil {
// return primary.Add(m.equityShares.SharesFromParty(sub))
// }
return primary
}

func (m *Market) SetNextMTM(tm time.Time) {
m.nextMTM = tm
}
Expand Down
157 changes: 157 additions & 0 deletions core/integration/features/amm/0090-VAMM-092.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
Feature: check VAMM when SLA bond penalty is due

Background:
Given the average block duration is "1"
And the margin calculator named "margin-calculator-1":
| search factor | initial factor | release factor |
| 1.2 | 1.5 | 1.7 |
And the log normal risk model named "log-normal-risk-model":
| risk aversion | tau | mu | r | sigma |
| 0.001 | 0.0011407711613050422 | 0 | 0.9 | 3.0 |
And the liquidity monitoring parameters:
| name | triggering ratio | time window | scaling factor |
| lqm-params | 1.00 | 20s | 1 |

And the following network parameters are set:
| name | value |
| market.value.windowLength | 60s |
| network.markPriceUpdateMaximumFrequency | 0s |
| limits.markets.maxPeggedOrders | 6 |
| market.auction.minimumDuration | 1 |
| market.fee.factors.infrastructureFee | 0.001 |
| market.fee.factors.makerFee | 0.004 |
| spam.protection.max.stopOrdersPerMarket | 5 |
| market.liquidity.equityLikeShareFeeFraction | 1 |
| market.amm.minCommitmentQuantum | 1000 |
| market.liquidity.bondPenaltyParameter | 0.2 |
| market.liquidity.stakeToCcyVolume | 1 |
| market.liquidity.successorLaunchWindowLength | 1h |
| market.liquidity.sla.nonPerformanceBondPenaltySlope | 0.1 |
| market.liquidity.sla.nonPerformanceBondPenaltyMax | 0.6 |
| validators.epoch.length | 10s |
| market.liquidity.earlyExitPenalty | 0.25 |
| market.liquidity.maximumLiquidityFeeFactorLevel | 0.25 |
#risk factor short:3.5569036
#risk factor long:0.801225765
And the following assets are registered:
| id | decimal places |
| USD | 0 |
And the fees configuration named "fees-config-1":
| maker fee | infrastructure fee |
| 0.0004 | 0.001 |

And the liquidity sla params named "SLA-22":
| price range | commitment min time fraction | performance hysteresis epochs | sla competition factor |
| 0.5 | 0.6 | 1 | 1.0 |

And the markets:
| id | quote name | asset | liquidity monitoring | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | sla params |
| ETH/MAR22 | USD | USD | lqm-params | log-normal-risk-model | margin-calculator-1 | 2 | fees-config-1 | default-none | default-eth-for-future | 1e0 | 0 | SLA-22 |

Scenario: set up AMM
Given the parties deposit on asset's general account the following amount:
| party | asset | amount |
| lp1 | USD | 1000000 |
| lp2 | USD | 1000000 |
| lp3 | USD | 1000000 |
| party1 | USD | 1000000 |
| party2 | USD | 1000000 |
| party3 | USD | 1000000 |
| party4 | USD | 1000000 |
| party5 | USD | 1000000 |
| vamm1 | USD | 30000 |

When the parties submit the following liquidity provision:
| id | party | market id | commitment amount | fee | lp type |
| lp_1 | lp1 | ETH/MAR22 | 600 | 0.02 | submission |
| lp_2 | lp2 | ETH/MAR22 | 400 | 0.015 | submission |
Then the network moves ahead "4" blocks
And the current epoch is "0"

And the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| lp1 | ETH/MAR22 | buy | 20 | 40 | 0 | TYPE_LIMIT | TIF_GTC | lp1-b |
| party1 | ETH/MAR22 | buy | 1 | 100 | 0 | TYPE_LIMIT | TIF_GTC | |
| party2 | ETH/MAR22 | sell | 1 | 100 | 0 | TYPE_LIMIT | TIF_GTC | |
| lp1 | ETH/MAR22 | sell | 10 | 160 | 0 | TYPE_LIMIT | TIF_GTC | lp1-s |
When the opening auction period ends for market "ETH/MAR22"
Then the following trades should be executed:
| buyer | price | size | seller |
| party1 | 100 | 1 | party2 |

And the market data for the market "ETH/MAR22" should be:
| mark price | trading mode | target stake | supplied stake | open interest | ref price | mid price | static mid price |
| 100 | TRADING_MODE_CONTINUOUS | 39 | 1000 | 1 | 100 | 100 | 100 |
When the parties submit the following AMM:
| party | market id | amount | slippage | base | lower bound | upper bound | lower leverage | upper leverage | proposed fee |
| vamm1 | ETH/MAR22 | 30000 | 0.1 | 100 | 85 | 150 | 4 | 4 | 0.01 |
Then the AMM pool status should be:
| party | market id | amount | status | base | lower bound | upper bound | lower leverage | upper leverage |
| vamm1 | ETH/MAR22 | 30000 | STATUS_ACTIVE | 100 | 85 | 150 | 4 | 4 |

And set the following AMM sub account aliases:
| party | market id | alias |
| vamm1 | ETH/MAR22 | vamm1-id |
And the following transfers should happen:
| from | from account | to | to account | market id | amount | asset | is amm | type |
| vamm1 | ACCOUNT_TYPE_GENERAL | vamm1-id | ACCOUNT_TYPE_GENERAL | | 30000 | USD | true | TRANSFER_TYPE_AMM_LOW |

Then the parties should have the following account balances:
| party | asset | market id | general |
| 137112507e25d3845a56c47db15d8ced0f28daa8498a0fd52648969c4b296aba | USD | ETH/MAR22 | 30000 |

Then the parties should have the following account balances:
| party | asset | market id | margin | general | bond |
| lp1 | USD | ETH/MAR22 | 960 | 998440 | 600 |
| lp2 | USD | ETH/MAR22 | 0 | 999600 | 400 |
| 137112507e25d3845a56c47db15d8ced0f28daa8498a0fd52648969c4b296aba | USD | ETH/MAR22 | 0 | 30000 | |

Then the network moves ahead "8" blocks

Then the parties should have the following account balances:
| party | asset | market id | margin | general | bond |
| lp1 | USD | ETH/MAR22 | 960 | 998440 | 540 |
| lp2 | USD | ETH/MAR22 | 0 | 999600 | 360 |
| 137112507e25d3845a56c47db15d8ced0f28daa8498a0fd52648969c4b296aba | USD | ETH/MAR22 | 0 | 30000 | |

#0042-LIQF-092:All vAMMs active on a market at the end of an epoch receive SLA bonus rebalancing payments with `0` penalty fraction.
#both lp1 and lp2 got SLA penalty while vamm1 did not
Then the following transfers should happen:
| from | to | from account | to account | market id | amount | asset |
| lp1 | market | ACCOUNT_TYPE_BOND | ACCOUNT_TYPE_INSURANCE | ETH/MAR22 | 60 | USD |
| lp2 | market | ACCOUNT_TYPE_BOND | ACCOUNT_TYPE_INSURANCE | ETH/MAR22 | 40 | USD |

Then the network moves ahead "8" blocks

When the parties cancel the following AMM:
| party | market id | method |
| vamm1 | ETH/MAR22 | METHOD_IMMEDIATE |

Then the parties should have the following account balances:
| party | asset | market id | general |
| vamm1 | USD | ETH/MAR22 | 30000 |

Then the network moves ahead "4" blocks
#0042-LIQF-093:A vAMM active on a market during an epoch, which was cancelled prior to the end of an epoch, receives SLA bonus rebalancing payments with `0` penalty fraction.
#both lp1 and lp2 got SLA penalty while vamm1 did not, and asset has been released from alias back to vamm1
Then the following transfers should happen:
| from | to | from account | to account | market id | amount | asset |
| lp1 | market | ACCOUNT_TYPE_BOND | ACCOUNT_TYPE_INSURANCE | ETH/MAR22 | 54 | USD |
| lp2 | market | ACCOUNT_TYPE_BOND | ACCOUNT_TYPE_INSURANCE | ETH/MAR22 | 36 | USD |

When the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif |
| party4 | ETH/MAR22 | buy | 4 | 120 | 0 | TYPE_LIMIT | TIF_GTC |

#0042-LIQF-094:A vAMMs cancelled in a previous epoch does not receive anything and is not considered during SLA rebalancing at the end of an epoch
Then the network moves ahead "12" blocks

Then the following transfers should happen:
| from | to | from account | to account | market id | amount | asset |
| lp1 | market | ACCOUNT_TYPE_BOND | ACCOUNT_TYPE_INSURANCE | ETH/MAR22 | 48 | USD |
| lp2 | market | ACCOUNT_TYPE_BOND | ACCOUNT_TYPE_INSURANCE | ETH/MAR22 | 32 | USD |

Then the parties should have the following account balances:
| party | asset | market id | general |
| vamm1 | USD | ETH/MAR22 | 30000 |

63 changes: 35 additions & 28 deletions core/processor/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -3024,23 +3024,6 @@ func (app *App) getMaxGas() uint64 {
return app.gastimator.maxGas
}

func (app *App) CreateReferralSet(ctx context.Context, tx abci.Tx, deterministicID string) error {
params := &commandspb.CreateReferralSet{}
if err := tx.Unmarshal(params); err != nil {
return fmt.Errorf("could not deserialize CreateReferralSet command: %w", err)
}

if err := app.referralProgram.CreateReferralSet(ctx, types.PartyID(tx.Party()), types.ReferralSetID(deterministicID)); err != nil {
return err
}

if params.IsTeam {
return app.teamsEngine.CreateTeam(ctx, types.PartyID(tx.Party()), types.TeamID(deterministicID), params.Team)
}

return nil
}

func (app *App) UpdateMarginMode(ctx context.Context, tx abci.Tx) error {
var err error
params := &commandspb.UpdateMarginMode{}
Expand Down Expand Up @@ -3087,6 +3070,25 @@ func (app *App) DeliverCancelAMM(ctx context.Context, tx abci.Tx, deterministicI
return app.exec.CancelAMM(ctx, cancel, deterministicID)
}

func (app *App) CreateReferralSet(ctx context.Context, tx abci.Tx, deterministicID string) error {
params := &commandspb.CreateReferralSet{}
if err := tx.Unmarshal(params); err != nil {
return fmt.Errorf("could not deserialize CreateReferralSet command: %w", err)
}

if !params.DoNotCreateReferralSet {
if err := app.referralProgram.CreateReferralSet(ctx, types.PartyID(tx.Party()), types.ReferralSetID(deterministicID)); err != nil {
return err
}
}

if params.IsTeam {
return app.teamsEngine.CreateTeam(ctx, types.PartyID(tx.Party()), types.TeamID(deterministicID), params.Team)
}

return nil
}

// UpdateReferralSet this is effectively Update team, but also served to create
// a team for an existing referral set...
func (app *App) UpdateReferralSet(ctx context.Context, tx abci.Tx) error {
Expand All @@ -3095,10 +3097,13 @@ func (app *App) UpdateReferralSet(ctx context.Context, tx abci.Tx) error {
return fmt.Errorf("could not deserialize UpdateReferralSet command: %w", err)
}

if err := app.referralProgram.PartyOwnsReferralSet(types.PartyID(tx.Party()), types.ReferralSetID(params.Id)); err != nil {
return fmt.Errorf("cannot update referral set: %w", err)
}
// Is this relevant at all now? With anyone able to create a team, this verification should not matter.
//
// if err := app.referralProgram.PartyOwnsReferralSet(types.PartyID(tx.Party()), types.ReferralSetID(params.Id)); err != nil {
// return fmt.Errorf("cannot update referral set: %w", err)
// }

// ultimately this has just become a createOrUpdateTeam.
if params.IsTeam {
teamID := types.TeamID(params.Id)
if app.teamsEngine.TeamExists(teamID) {
Expand Down Expand Up @@ -3128,14 +3133,16 @@ func (app *App) ApplyReferralCode(ctx context.Context, tx abci.Tx) error {
return fmt.Errorf("could not apply the referral code: %w", err)
}

teamID := types.TeamID(params.Id)
joinTeam := &commandspb.JoinTeam{
Id: params.Id,
}
err = app.teamsEngine.JoinTeam(ctx, partyID, joinTeam)
// This is ok as well, as not all referral sets are teams as well.
if err != nil && err.Error() != teams.ErrNoTeamMatchesID(teamID).Error() {
return fmt.Errorf("couldn't join team: %w", err)
if !params.DoNotJoinTeam {
teamID := types.TeamID(params.Id)
joinTeam := &commandspb.JoinTeam{
Id: params.Id,
}
err = app.teamsEngine.JoinTeam(ctx, partyID, joinTeam)
// This is ok as well, as not all referral sets are teams as well.
if err != nil && err.Error() != teams.ErrNoTeamMatchesID(teamID).Error() {
return fmt.Errorf("couldn't join team: %w", err)
}
}

return nil
Expand Down
Loading

0 comments on commit b322570

Please sign in to comment.