Skip to content

Commit

Permalink
feat: add pap state to market data
Browse files Browse the repository at this point in the history
  • Loading branch information
ze97286 committed Sep 30, 2024
1 parent 6418019 commit 690c1ef
Show file tree
Hide file tree
Showing 41 changed files with 2,904 additions and 1,837 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [11642](https://github.com/vegaprotocol/vega/issues/11642) - `AMMs` with empty price levels are now allowed.
- [11685](https://github.com/vegaprotocol/vega/issues/11685) - Automated purchase support added.
- [11711](https://github.com/vegaprotocol/vega/issues/11711) - Manage closed team membership by updating the allow list.
- [11722](https://github.com/vegaprotocol/vega/issues/11722) - Expose active protocol automated purchase identifier in market data API.

### 🐛 Fixes

Expand Down
2 changes: 1 addition & 1 deletion commands/transfer_funds.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func checkTransfer(cmd *commandspb.Transfer) (e Errors) {
} else {
switch k := cmd.Kind.(type) {
case *commandspb.Transfer_OneOff:
if cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GLOBAL_REWARD && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GENERAL && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_UNSPECIFIED && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY {
if cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GLOBAL_REWARD && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_GENERAL && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_UNSPECIFIED && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY && cmd.ToAccountType != vega.AccountType_ACCOUNT_TYPE_BUY_BACK_FEES {
errs.AddForProperty("transfer.to_account_type", errors.New("account type is not valid for one off transfer"))
}
if k.OneOff.GetDeliverOn() < 0 {
Expand Down
17 changes: 17 additions & 0 deletions core/execution/spot/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,18 @@ func (m *Market) GetMarketData() types.MarketData {
mode = m.mkt.TradingMode
}

var papState *vega.ProtocolAutomatedPurchaseData
if m.pap != nil {
var activeOrder *string
if len(m.pap.activeOrder) > 0 {
activeOrder = &m.pap.activeOrder
}
papState = &vega.ProtocolAutomatedPurchaseData{
Id: m.pap.ID,
OrderId: activeOrder,
}
}

return types.MarketData{
Market: m.GetID(),
BestBidPrice: m.priceToMarketPrecision(bestBidPrice),
Expand Down Expand Up @@ -471,6 +483,7 @@ func (m *Market) GetMarketData() types.MarketData {
MarketValueProxy: m.lastMarketValueProxy.BigInt().String(),
LiquidityProviderFeeShare: m.equityShares.LpsToLiquidityProviderFeeShare(m.liquidity.GetAverageLiquidityScores()),
LiquidityProviderSLA: m.liquidityEngine.LiquidityProviderSLAStats(m.timeService.GetTimeNow()),
PAPState: papState,
}
}

Expand Down Expand Up @@ -690,6 +703,8 @@ func (m *Market) OnTick(ctx context.Context, t time.Time) bool {
return true
}

m.checkPAP(ctx)

// first we expire orders
if !m.closed && m.canTrade() {
expired := m.removeExpiredOrders(ctx, t.UnixNano())
Expand Down Expand Up @@ -3544,3 +3559,5 @@ func (m *Market) getACcountTypesForPAP() (types.AccountType, types.AccountType,
}
return m.pap.getACcountTypesForPAP()
}

func (m *Market) BeginBlock(ctx context.Context) {}
4 changes: 2 additions & 2 deletions core/execution/spot/protocol_automated_purchase.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ func (m *Market) stopPAP(ctx context.Context) {
m.pap.nextAuctionAmount = nil
}

// BeginBlock checks if a pap has expired, if so and it.
func (m *Market) BeginBlock(ctx context.Context) {
// checkPAP checks if a pap has expired, if so and it.
func (m *Market) checkPAP(ctx context.Context) {
// no pap - nothing to do
if m.pap == nil {
return
Expand Down
106 changes: 106 additions & 0 deletions core/integration/features/pap/0097-PAPU-021.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
Feature: Given the program currently has no funds earmarked for an auction, if a program's expiry timestamp is reached, the program will be cancelled and no further auctions will take place. (0097-PAPU-021).

Background:
Given the log normal risk model named "log-normal-risk-model":
| risk aversion | tau | mu | r | sigma |
| 0.000001 | 0.1 | 0 | 0 | 1.0 |
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 |
| validators.epoch.length | 60m |
And the liquidity monitoring parameters:
| name | triggering ratio | time window | scaling factor |
| lqm-params | 1.0 | 20s | 1 |
And the fees configuration named "fees-config-1":
| maker fee | infrastructure fee |
| 0.0004 | 0.001 |
And the price monitoring named "price-monitoring":
| horizon | probability | auction extension |
| 3600 | 0.99 | 30 |
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 following network parameters are set:
| name | value |
| limits.markets.maxPeggedOrders | 2 |
And the following assets are registered:
| id | decimal places |
| ETH | 0 |

And the spot markets:
| id | name | base asset | quote asset | liquidity monitoring | risk model | auction duration | fees | price monitoring | sla params |
| BTC/ETH | BTC/ETH | BTC | ETH | lqm-params | log-normal-risk-model | 2 | fees-config-1 | price-monitoring | SLA-22 |

Given the parties deposit on asset's general account the following amount:
| party | asset | amount |
| party1 | ETH | 1000000000 |
| party2 | ETH | 1000000000 |
| party3 | ETH | 1000000000 |
| party1 | BTC | 1000000000 |
| party3 | BTC | 1000000000 |
| lpprov | ETH | 1000000000 |
| lpprov | BTC | 1000000000 |

When the parties submit the following liquidity provision:
| id | party | market id | commitment amount | fee | lp type |
| lp1 | lpprov | BTC/ETH | 937000 | 0.1 | submission |
| lp1 | lpprov | BTC/ETH | 937000 | 0.1 | submission |
And the parties place the following pegged iceberg orders:
| party | market id | peak size | minimum visible size | side | pegged reference | volume | offset |
| lpprov | BTC/ETH | 2 | 1 | buy | MID | 50 | 100 |
| lpprov | BTC/ETH | 2 | 1 | sell | MID | 50 | 100 |

# place orders and generate trades - slippage 100
And the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| party2 | BTC/ETH | buy | 1 | 950000 | 0 | TYPE_LIMIT | TIF_GTC | t2-b-1 |
| party1 | BTC/ETH | buy | 1 | 1000000 | 0 | TYPE_LIMIT | TIF_GFA | t1-b-1 |
| party3 | BTC/ETH | sell | 1 | 1000000 | 0 | TYPE_LIMIT | TIF_GTC | t2-s-1 |

When the opening auction period ends for market "BTC/ETH"

And the following trades should be executed:
| buyer | price | size | seller |
| party1 | 1000000 | 1 | party3 |
And the mark price should be "1000000" for the market "BTC/ETH"

And the composite price oracles from "0xCAFECAFE2":
| name | price property | price type | price decimals |
| price_oracle | prices.ETH.value | TYPE_INTEGER | 0 |

And the time triggers oracle spec is:
| name | initial | every |
| auction_schedule | 172713601 | 30 |
| auction_vol_snap_schedule | 172713600 | 30 |

And the average block duration is "1"

And the parties deposit on asset's general account the following amount:
| party | asset | amount |
| f0b40ebdc5b92cf2cf82ff5d0c3f94085d23d5ec2d37d0b929e177c6d4d37e4c | BTC | 50000 |
Given time is updated to "2024-09-24T00:00:00Z"

Scenario: pap is not funded and expires nothing gets earmarked (0097-PAPU-021)
When the protocol automated purchase is defined as:
| id | from | from account type | to account type | market id | price oracle | price oracle staleness tolerance | oracle offset factor | auction schedule oracle | auction volume snapshot schedule oracle | auction duration | minimum auction size | maximum auction size | expiry timestamp |
| 12345 | BTC | ACCOUNT_TYPE_BUY_BACK_FEES | ACCOUNT_TYPE_NETWORK_TREASURY | BTC/ETH | price_oracle | 10s | 1.01 | auction_schedule | auction_vol_snap_schedule | 60s | 100 | 200 | 1727136030 |

And the active pap id should be "12345" for the market "BTC/ETH"

Then the oracles broadcast data with block time signed with "0xCAFECAFE2":
| name | value | time offset |
| prices.ETH.value | 1000000 | -1s |

And the network moves ahead "120" blocks
And the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "BTC/ETH"
And the active pap id should be "none" for the market "BTC/ETH"
And the active pap order id should be "none" for the market "BTC/ETH"



113 changes: 113 additions & 0 deletions core/integration/features/pap/0097-PAPU-022.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
Feature: Given the program currently has earmarked funds for an auction but is not yet in the auction, if a program's expiry timestamp is reached, the program will be cancelled, the earmarked funds released and no further auctions will take place. (0097-PAPU-022).
Background:
Given the log normal risk model named "log-normal-risk-model":
| risk aversion | tau | mu | r | sigma |
| 0.000001 | 0.1 | 0 | 0 | 1.0 |
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 |
| validators.epoch.length | 60m |
And the liquidity monitoring parameters:
| name | triggering ratio | time window | scaling factor |
| lqm-params | 1.0 | 20s | 1 |
And the fees configuration named "fees-config-1":
| maker fee | infrastructure fee |
| 0.0004 | 0.001 |
And the price monitoring named "price-monitoring":
| horizon | probability | auction extension |
| 3600 | 0.99 | 30 |
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 following network parameters are set:
| name | value |
| limits.markets.maxPeggedOrders | 2 |
And the following assets are registered:
| id | decimal places |
| ETH | 0 |

And the spot markets:
| id | name | base asset | quote asset | liquidity monitoring | risk model | auction duration | fees | price monitoring | sla params |
| BTC/ETH | BTC/ETH | BTC | ETH | lqm-params | log-normal-risk-model | 2 | fees-config-1 | price-monitoring | SLA-22 |

Given the parties deposit on asset's general account the following amount:
| party | asset | amount |
| party1 | ETH | 1000000000 |
| party2 | ETH | 1000000000 |
| party3 | ETH | 1000000000 |
| party1 | BTC | 1000000000 |
| party3 | BTC | 1000000000 |
| lpprov | ETH | 1000000000 |
| lpprov | BTC | 1000000000 |

When the parties submit the following liquidity provision:
| id | party | market id | commitment amount | fee | lp type |
| lp1 | lpprov | BTC/ETH | 937000 | 0.1 | submission |
| lp1 | lpprov | BTC/ETH | 937000 | 0.1 | submission |
And the parties place the following pegged iceberg orders:
| party | market id | peak size | minimum visible size | side | pegged reference | volume | offset |
| lpprov | BTC/ETH | 2 | 1 | buy | MID | 50 | 100 |
| lpprov | BTC/ETH | 2 | 1 | sell | MID | 50 | 100 |

# place orders and generate trades - slippage 100
And the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| party2 | BTC/ETH | buy | 1 | 950000 | 0 | TYPE_LIMIT | TIF_GTC | t2-b-1 |
| party1 | BTC/ETH | buy | 1 | 1000000 | 0 | TYPE_LIMIT | TIF_GFA | t1-b-1 |
| party3 | BTC/ETH | sell | 1 | 1000000 | 0 | TYPE_LIMIT | TIF_GTC | t2-s-1 |

When the opening auction period ends for market "BTC/ETH"

And the following trades should be executed:
| buyer | price | size | seller |
| party1 | 1000000 | 1 | party3 |
And the mark price should be "1000000" for the market "BTC/ETH"

And the composite price oracles from "0xCAFECAFE2":
| name | price property | price type | price decimals |
| price_oracle | prices.ETH.value | TYPE_INTEGER | 0 |

And the time triggers oracle spec is:
| name | initial | every |
| auction_schedule | 1727136030 | 30 |
| auction_vol_snap_schedule | 1727136000 | 30 |

And the average block duration is "1"

And the parties deposit on asset's general account the following amount:
| party | asset | amount |
| f0b40ebdc5b92cf2cf82ff5d0c3f94085d23d5ec2d37d0b929e177c6d4d37e4c | BTC | 50000 |
Given time is updated to "2024-09-24T00:00:00Z"
And the parties submit the following one off transfers:
| id | from | from_account_type | to | to_account_type | asset | amount | delivery_time |
| 1 | f0b40ebdc5b92cf2cf82ff5d0c3f94085d23d5ec2d37d0b929e177c6d4d37e4c | ACCOUNT_TYPE_GENERAL | 0000000000000000000000000000000000000000000000000000000000000000 | ACCOUNT_TYPE_BUY_BACK_FEES | BTC | 5000 | 2024-09-23T00:00:00Z |

And the buy back fees balance should be "5000" for the asset "BTC"

Scenario: pap is not funded and expires nothing gets earmarked (0097-PAPU-021)
When the protocol automated purchase is defined as:
| id | from | from account type | to account type | market id | price oracle | price oracle staleness tolerance | oracle offset factor | auction schedule oracle | auction volume snapshot schedule oracle | auction duration | minimum auction size | maximum auction size | expiry timestamp |
| 12345 | BTC | ACCOUNT_TYPE_BUY_BACK_FEES | ACCOUNT_TYPE_NETWORK_TREASURY | BTC/ETH | price_oracle | 10s | 1.01 | auction_schedule | auction_vol_snap_schedule | 60s | 100 | 200 | 1727136020 |

Then the oracles broadcast data with block time signed with "0xCAFECAFE2":
| name | value | time offset |
| prices.ETH.value | 1000000 | -1s |

# volume snapshot is taken
And the network moves ahead "5" blocks
Then the automated purchase program for market "BTC/ETH" should have a snapshot balance of "200"

# the auction trigger is ticked after the expiration
And the network moves ahead "30" blocks
And the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "BTC/ETH"

# the program is cancelled, funds are unearmarked and the balance remained fully in the source account
And the buy back fees balance should be "5000" for the asset "BTC"
And the active pap id should be "none" for the market "BTC/ETH"
And the active pap order id should be "none" for the market "BTC/ETH"
Loading

0 comments on commit 690c1ef

Please sign in to comment.