From 53e8087a795df2924f13d1755ac65ef3ff4d461d Mon Sep 17 00:00:00 2001 From: Witold Date: Wed, 5 Jun 2024 10:56:27 +0200 Subject: [PATCH 1/6] refactor: scale funding payment --- core/products/perpetual.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/products/perpetual.go b/core/products/perpetual.go index de7e2701130..a9814ba64cc 100644 --- a/core/products/perpetual.go +++ b/core/products/perpetual.go @@ -900,15 +900,22 @@ func (p *Perpetual) calculateFundingPayment(t int64) *fundingData { // the funding payment is the difference between the two, the sign representing the direction of cash flow fundingPayment := num.DecimalFromUint(internalTWAP).Sub(num.DecimalFromUint(externalTWAP)) + delta := t - p.startedAt // apply interest-rates if necessary if !p.p.InterestRate.IsZero() { - delta := t - p.startedAt if p.log.GetLevel() == logging.DebugLevel { p.log.Debug("applying interest-rate with clamping", logging.String("funding-payment", fundingPayment.String()), logging.Int64("delta", delta)) } fundingPayment = fundingPayment.Add(p.calculateInterestTerm(externalTWAP, internalTWAP, delta)) } + // scale funding payment by fraction of funding period spent outside of auction + timeSpentInAuction := p.auctions.timeSpent(p.startedAt, t) + if timeSpentInAuction > 0 && delta > 0 { + scaling := (delta - timeSpentInAuction) / delta + fundingPayment = fundingPayment.Mul(num.DecimalFromInt64(scaling)) + } + // apply funding scaling factor if p.p.FundingRateScalingFactor != nil { fundingPayment = fundingPayment.Mul(*p.p.FundingRateScalingFactor) From fa63ef482edff559fb0dc00ab074ac4356a0c7d3 Mon Sep 17 00:00:00 2001 From: Witold Date: Mon, 8 Jul 2024 12:05:40 +0200 Subject: [PATCH 2/6] refactor: fix integration tests --- .../features/settlement/0019-MCAL_018.feature | 18 +++ .../0019-MCAL_fundingMargin5.feature | 42 +++-- .../settlement/0053-PERP-024_Closeout.feature | 147 ------------------ .../0053-PERP-024_LossSocialisation.feature | 11 +- ...-028_twap_calculation_with_auction.feature | 27 ++-- .../features/settlement/0053-PERP-039.feature | 15 +- .../features/settlement/0053-PERP-040.feature | 15 +- core/products/perpetual.go | 4 +- 8 files changed, 87 insertions(+), 192 deletions(-) delete mode 100644 core/integration/features/settlement/0053-PERP-024_Closeout.feature diff --git a/core/integration/features/settlement/0019-MCAL_018.feature b/core/integration/features/settlement/0019-MCAL_018.feature index 9ce59dec02d..c0ab60f0185 100644 --- a/core/integration/features/settlement/0019-MCAL_018.feature +++ b/core/integration/features/settlement/0019-MCAL_018.feature @@ -88,9 +88,14 @@ Feature: check when settlement data precision is different/equal to the settleme | party3 | USD | ETH/DEC19 | 132000 | 99866000 | | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | + When time is updated to "2021-02-11T16:35:24Z" + Then system unix time is "1613061324" + When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | + When time is updated to "2021-08-12T11:04:07Z" + Then system unix time is "1628766247" When the network moves ahead "5" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE1": @@ -171,10 +176,16 @@ Feature: check when settlement data precision is different/equal to the settleme | party3 | USD | ETH/DEC19 | 132000 | 99866000 | | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | + When time is updated to "2021-02-11T16:35:24Z" + Then system unix time is "1613061324" + When the oracles broadcast data with block time signed with "0xCAFECAFE3": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | + When time is updated to "2021-08-12T11:04:07Z" + Then system unix time is "1628766247" + When the network moves ahead "5" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE3": | name | value | time offset | @@ -182,6 +193,7 @@ Feature: check when settlement data precision is different/equal to the settleme | perp.funding.cue | 1628766252 | 0s | #1628766252 is half year after the first oracel time + Then debug funding period events And the following transfers should happen: | from | to | from account | to account | market id | amount | asset | | aux2 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 74700 | USD | @@ -253,9 +265,15 @@ Feature: check when settlement data precision is different/equal to the settleme | party3 | USD | ETH/DEC19 | 132000 | 99866000 | | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | + When time is updated to "2021-02-11T16:35:24Z" + Then system unix time is "1613061324" + When the oracles broadcast data with block time signed with "0xCAFECAFE2": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | + + When time is updated to "2021-08-12T11:04:07Z" + Then system unix time is "1628766247" When the network moves ahead "5" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE2": diff --git a/core/integration/features/settlement/0019-MCAL_fundingMargin5.feature b/core/integration/features/settlement/0019-MCAL_fundingMargin5.feature index 45552770ce2..c4ec346c007 100644 --- a/core/integration/features/settlement/0019-MCAL_fundingMargin5.feature +++ b/core/integration/features/settlement/0019-MCAL_fundingMargin5.feature @@ -79,16 +79,22 @@ Feature: check when settlement data precision is different/equal to the settleme | party1 | ETH/DEC19 | sell | 1 | 2000 | 0 | TYPE_LIMIT | TIF_GTC | | party3 | ETH/DEC19 | buy | 1 | 2000 | 1 | TYPE_LIMIT | TIF_GTC | + When time is updated to "2021-02-11T16:35:24Z" + Then system unix time is "1613061324" + When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | And the network moves ahead "5" blocks + When time is updated to "2021-08-12T11:04:12Z" + Then system unix time is "1628766252" + Then the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 300000000 | 0s | | perp.funding.cue | 1628766252 | 0s | -# #1628766252 is half year after the first oracel time + #1628766252 is half year after the first oracle time And the following transfers should happen: | from | to | from account | to account | market id | amount | asset | @@ -104,27 +110,35 @@ Feature: check when settlement data precision is different/equal to the settleme | id | data source config | linear slippage factor | quadratic slippage factor | | ETH/DEC19 | perp-oracle-2 | 0.25 | 0 | + When time is updated to "2021-08-12T11:04:30Z" + Then system unix time is "1628766270" + And the oracles broadcast data with block time signed with "0xCAFECAFE2": | name | value | time offset | | perp.funding.cue | 1628766270 | 0s | + | perp.ETH.value | 350000000 | 0s | - When the network moves ahead "5" blocks + When time is updated to "2024-10-12T20:51:10Z" + Then system unix time is "1728766270" Then the oracles broadcast data with block time signed with "0xCAFECAFE2": | name | value | time offset | - | perp.ETH.value | 350000000 | 0s | | perp.funding.cue | 1728766270 | 0s | + And the following funding period events should be emitted: + | start | end | internal twap | external twap | funding payment | + | 1628766270 | 1728766270 | 200000 | 350000000 | -174800000 | + # funding loss, win, margin excess transfers: And the following transfers should happen: - | from | to | from account | to account | market id | amount | asset | - | aux | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 1080000 | USD | - | aux | market | ACCOUNT_TYPE_GENERAL | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 297994700 | USD | - | party1 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 1680000 | USD | - | party1 | market | ACCOUNT_TYPE_GENERAL | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 997469400 | USD | - | market | party2 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 432741366 | USD | - | market | party3 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 432741368 | USD | - | market | aux2 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 432741366 | USD | - | aux2 | aux2 | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_GENERAL | ETH/DEC19 | 432666666 | USD | - | party2 | party2 | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_GENERAL | ETH/DEC19 | 432666666 | USD | - | party3 | party3 | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_GENERAL | ETH/DEC19 | 432666668 | USD | + | from | to | from account | to account | market id | amount | asset | type | + | aux | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 1080000 | USD | TRANSFER_TYPE_PERPETUALS_FUNDING_LOSS | + | aux | market | ACCOUNT_TYPE_GENERAL | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 297994700 | USD | TRANSFER_TYPE_PERPETUALS_FUNDING_LOSS | + | party1 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 1680000 | USD | TRANSFER_TYPE_PERPETUALS_FUNDING_LOSS | + | party1 | market | ACCOUNT_TYPE_GENERAL | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 997469400 | USD | TRANSFER_TYPE_PERPETUALS_FUNDING_LOSS | + | market | party2 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 432741366 | USD | TRANSFER_TYPE_PERPETUALS_FUNDING_WIN | + | market | party3 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 432741368 | USD | TRANSFER_TYPE_PERPETUALS_FUNDING_WIN | + | market | aux2 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 432741366 | USD | TRANSFER_TYPE_PERPETUALS_FUNDING_WIN | + | aux2 | aux2 | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_GENERAL | ETH/DEC19 | 432711486 | USD | TRANSFER_TYPE_MARGIN_HIGH | + | party2 | party2 | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_GENERAL | ETH/DEC19 | 432711486 | USD | TRANSFER_TYPE_MARGIN_HIGH | + | party3 | party3 | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_GENERAL | ETH/DEC19 | 432711488 | USD | TRANSFER_TYPE_MARGIN_HIGH | diff --git a/core/integration/features/settlement/0053-PERP-024_Closeout.feature b/core/integration/features/settlement/0053-PERP-024_Closeout.feature deleted file mode 100644 index b4436126352..00000000000 --- a/core/integration/features/settlement/0053-PERP-024_Closeout.feature +++ /dev/null @@ -1,147 +0,0 @@ -Feature: Test funding payment triggering closeout for Perps market - - Background: - - And the perpetual oracles from "0xCAFECAFE1": - | name | asset | settlement property | settlement type | schedule property | schedule type | margin funding factor | interest rate | clamp lower bound | clamp upper bound | quote name | settlement decimals | - | perp-oracle | USD | perp.ETH.value | TYPE_INTEGER | perp.funding.cue | TYPE_TIMESTAMP | 0.5 | 0.05 | 0.1 | 0.9 | ETH | 18 | - And the liquidity sla params named "SLA": - | price range | commitment min time fraction | performance hysteresis epochs | sla competition factor | - | 1.0 | 0.5 | 1 | 1.0 | - - And the markets: - | id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | position decimal places | market type | sla params | - | ETH/DEC19 | ETH | USD | default-simple-risk-model-3 | default-margin-calculator | 1 | default-none | default-none | perp-oracle | 1 | 0 | -3 | perp | default-futures | - - And the initial insurance pool balance is "100" for all the markets - And the following network parameters are set: - | name | value | - | market.auction.minimumDuration | 1 | - | limits.markets.maxPeggedOrders | 2 | - - @Perpetual @Liquidation - Scenario: (0053-PERP-024) Funding payment triggering closeout but no loss soccialization - Given the following network parameters are set: - | name | value | - | network.markPriceUpdateMaximumFrequency | 5s | - And the parties deposit on asset's general account the following amount: - | party | asset | amount | - | party1 | USD | 10000000 | - | party2 | USD | 10000000 | - | party3 | USD | 10000000 | - | aux | USD | 100000000 | - | aux2 | USD | 2391000 | - | lpprov | USD | 100000000 | - - When the parties submit the following liquidity provision: - | id | party | market id | commitment amount | fee | lp type | - | lp1 | lpprov | ETH/DEC19 | 10000000 | 0.001 | submission | - | lp1 | lpprov | ETH/DEC19 | 10000000 | 0.001 | submission | - And the parties place the following pegged iceberg orders: - | party | market id | peak size | minimum visible size | side | pegged reference | volume | offset | - | lpprov | ETH/DEC19 | 2 | 1 | buy | BID | 50 | 1 | - | lpprov | ETH/DEC19 | 2 | 1 | sell | ASK | 50 | 1 | - - # place auxiliary orders so we always have best bid and best offer as to not trigger the liquidity auction - When the parties place the following orders: - | party | market id | side | volume | price | resulting trades | type | tif | - | aux | ETH/DEC19 | buy | 1 | 49 | 0 | TYPE_LIMIT | TIF_GTC | - | aux | ETH/DEC19 | sell | 1 | 5001 | 0 | TYPE_LIMIT | TIF_GTC | - | aux2 | ETH/DEC19 | buy | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | - | aux | ETH/DEC19 | sell | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | - - And the market data for the market "ETH/DEC19" should be: - | target stake | supplied stake | - | 1100000 | 10000000 | - Then the opening auction period ends for market "ETH/DEC19" - And the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "ETH/DEC19" - And the settlement account should have a balance of "0" for the market "ETH/DEC19" - - # back sure we end the block so we're in a new one after opening auction - When the network moves ahead "1" blocks - - When the parties place the following orders: - | party | market id | side | volume | price | resulting trades | type | tif | - | party1 | ETH/DEC19 | sell | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | - | party2 | ETH/DEC19 | buy | 1 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | - - And the settlement account should have a balance of "0" for the market "ETH/DEC19" - When the parties place the following orders: - | party | market id | side | volume | price | resulting trades | type | tif | - | party1 | ETH/DEC19 | sell | 1 | 2000 | 0 | TYPE_LIMIT | TIF_GTC | - - When the parties place the following orders: - | party | market id | side | volume | price | resulting trades | type | tif | - | party3 | ETH/DEC19 | buy | 1 | 2000 | 1 | TYPE_LIMIT | TIF_GTC | - - And the market data for the market "ETH/DEC19" should be: - | mark price | trading mode | target stake | supplied stake | open interest | - | 1000 | TRADING_MODE_CONTINUOUS | 3300000 | 10000000 | 3 | - # send in external data to the perpetual market, it should not change anything and a MTM should not happen - When the network moves ahead "1" blocks - And the mark price should be "1000" for the market "ETH/DEC19" - - When the oracles broadcast data with block time signed with "0xCAFECAFE1": - | name | value | time offset | - | perp.ETH.value | 1600000000000000000000 | 0s | - | perp.funding.cue | 1612998252 | 0s | - When the network moves ahead "4" blocks - - And the following transfers should happen: - | from | to | from account | to account | market id | amount | asset | - | party1 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 1000000 | USD | - | aux | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 1000000 | USD | - | market | aux2 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 1000000 | USD | - | market | party2 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 1000000 | USD | - # And the cumulated balance for all accounts should be worth "330010000" - And the settlement account should have a balance of "0" for the market "ETH/DEC19" - - When the network moves ahead "1" blocks - - When the parties place the following orders: - | party | market id | side | volume | price | resulting trades | type | tif | - | aux | ETH/DEC19 | sell | 1 | 2001 | 0 | TYPE_LIMIT | TIF_GTC | - | aux2 | ETH/DEC19 | buy | 1 | 2001 | 1 | TYPE_LIMIT | TIF_GTC | - - And the mark price should be "2000" for the market "ETH/DEC19" - Then the parties should have the following profit and loss: - | party | volume | unrealised pnl | realised pnl | - | aux | -1 | -1000000 | 96000 | - | aux2 | 1 | 1000000 | -96000 | - | party1 | -2 | -1000000 | 0 | - | party2 | 1 | 1000000 | 0 | - | party3 | 1 | 0 | 0 | - | lpprov | 0 | 0 | 0 | - ## allow close-outs to happen - When the network moves ahead "1" blocks - #1 year has 8760 hours,so 0.002 year would be: 8760*0.002*3600 = 63072second, so next funding time (with delta_t = 0.002) would be 1612998252+63072=1613061324 - And the oracles broadcast data with block time signed with "0xCAFECAFE1": - | name | value | time offset | - | perp.funding.cue | 1613061324 | 0s | - - #funding payment = f_twap - s_twap + clamp_lower_bound*s_twap =2000-1600+(0.1*1600)=560 - Then the following transfers should happen: - | from | to | from account | to account | market id | amount | asset | - | aux2 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 1120000 | USD | - | party2 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 560000 | USD | - | party3 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 560000 | USD | - | market | aux | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 1120000 | USD | - | market | party1 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 1120000 | USD | - - And the parties should have the following account balances: - | party | asset | market id | margin | general | - | aux2 | USD | ETH/DEC19 | 0 | 0 | - - And the parties should have the following profit and loss: - | party | volume | unrealised pnl | realised pnl | - | aux | -1 | -1000000 | 1216000 | - | aux2 | 0 | 0 | -2388999 | - | party1 | -2 | -1000000 | 1120000 | - | party2 | 1 | 1000000 | -560000 | - | party3 | 1 | 0 | -560000 | - | lpprov | 0 | 0 | 0 | - - And the insurance pool balance should be "2173099" for the market "ETH/DEC19" - - - diff --git a/core/integration/features/settlement/0053-PERP-024_LossSocialisation.feature b/core/integration/features/settlement/0053-PERP-024_LossSocialisation.feature index 5b399a42843..57a9eaa273d 100644 --- a/core/integration/features/settlement/0053-PERP-024_LossSocialisation.feature +++ b/core/integration/features/settlement/0053-PERP-024_LossSocialisation.feature @@ -19,7 +19,7 @@ Feature: Test funding payment triggering closeout for Perps market | limits.markets.maxPeggedOrders | 2 | @Perpetual @Liquidation - Scenario: (0053-PERP-024) Funding payment triggering loss soccialization + Scenario: (0053-PERP-024) Funding payment triggering loss socialization Given the following network parameters are set: | name | value | | network.markPriceUpdateMaximumFrequency | 5s | @@ -80,10 +80,17 @@ Feature: Test funding payment triggering closeout for Perps market When the network moves ahead "1" blocks And the mark price should be "1000" for the market "ETH/DEC19" + When time is updated to "2021-02-10T23:04:12Z" + Then system unix time is "1612998252" + When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 3000000000000000000000 | 0s | | perp.funding.cue | 1612998252 | 0s | + + When time is updated to "2021-08-12T11:04:12Z" + Then system unix time is "1628766252" + When the network moves ahead "4" blocks #MTM for mark price 1000 to 1200 @@ -96,8 +103,6 @@ Feature: Test funding payment triggering closeout for Perps market And the settlement account should have a balance of "0" for the market "ETH/DEC19" - When the network moves ahead "1" blocks - When the parties place the following orders: | party | market id | side | volume | price | resulting trades | type | tif | | aux | ETH/DEC19 | sell | 1 | 2001 | 0 | TYPE_LIMIT | TIF_GTC | diff --git a/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature b/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature index 329b6fbff71..d1fdaa27611 100644 --- a/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature +++ b/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature @@ -121,47 +121,47 @@ Feature: Test internal and external twap calculation | name | value | time offset | | perp.ETH.value | 30000000000000000000 | 0s | - ### 6 mins in, still in monitoring auction + ### 6 mins in, still in monitoring auction (fraction outside auction is 5/6, hence the funding payment ends up being 5/6*1000=~833) Given the network moves ahead "60" blocks Then the trading mode should be "TRADING_MODE_MONITORING_AUCTION" for the market "ETH/DEC19" Then the product data for the market "ETH/DEC19" should be: | internal twap | external twap | funding payment | - | 10800 | 9800 | 1000 | + | 10800 | 9800 | 833 | Given the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 11000000000000000000 | 0s | - # 7 mins in, the auction period will end + # 7 mins in, the auction period will end (fraction outside auction is 5/7, hence the funding payment ends up being 5/7*1000=~714) Given the network moves ahead "60" blocks Then the trading mode should be "TRADING_MODE_MONITORING_AUCTION" for the market "ETH/DEC19" Then the product data for the market "ETH/DEC19" should be: | internal twap | external twap | funding payment | - | 10800 | 9800 | 1000 | + | 10800 | 9800 | 714 | Then the network moves ahead "1" blocks - - # 8 mins in, still in continuous traidng +`` + # 8 mins in, still in continuous trading (fraction outside auction is ~6/8, hence the funding payment ends up being 6/8*500=~374) Given the network moves ahead "60" blocks Then the product data for the market "ETH/DEC19" should be: | internal twap | external twap | funding payment | - | 10500 | 10000 | 500 | + | 10500 | 10000 | 374 | Given the parties place the following orders: | party | market id | side | volume | price | resulting trades | type | tif | | party1 | ETH/DEC19 | buy | 1 | 8 | 0 | TYPE_LIMIT | TIF_GTC | | party2 | ETH/DEC19 | sell | 1 | 8 | 1 | TYPE_LIMIT | TIF_GTC | - And the oracles broadcast data with block time signed with "0xCAFECAFE1": + And the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 8000000000000000000 | 0s | - # 9 mins in, still in continuous traidng + # 9 mins in, still in continuous trading (fraction outside auction is ~7/9, hence the funding payment ends up being 7/9*500=~332) Given the network moves ahead "60" blocks Then the product data for the market "ETH/DEC19" should be: | internal twap | external twap | funding payment | - | 10142 | 9714 | 428 | + | 10142 | 9714 | 332 | Given the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 14000000000000000000 | 0s | - # 10 mins in, still in continuous traidng + # 10 mins in, still in continuous trading (fraction outside auction is ~8/10, hence the funding payment ends up being 8/10*375=~299) Given the network moves ahead "60" blocks Then the markets are updated: | id | price monitoring | linear slippage factor | quadratic slippage factor | @@ -172,7 +172,4 @@ Feature: Test internal and external twap calculation | party2 | ETH/DEC19 | sell | 1 | 30 | 1 | TYPE_LIMIT | TIF_GTC | Then the product data for the market "ETH/DEC19" should be: | internal twap | external twap | funding payment | - | 9875 | 10250 | -375 | - - - + | 9875 | 10250 | -299 | diff --git a/core/integration/features/settlement/0053-PERP-039.feature b/core/integration/features/settlement/0053-PERP-039.feature index c9644fb757f..4eab6eb5617 100644 --- a/core/integration/features/settlement/0053-PERP-039.feature +++ b/core/integration/features/settlement/0053-PERP-039.feature @@ -60,6 +60,10 @@ Feature: If a market insurance pool does not have enough funds to cover a fundin # back sure we end the block so we're in a new one after opening auction When the network moves ahead "1" blocks + Then the oracles broadcast data with block time signed with "0xCAFECAFE1": + | name | value | time offset | + | perp.ETH.value | 1000000000000000000000 | 0s | + When the parties place the following orders: | party | market id | side | volume | price | resulting trades | type | tif | @@ -80,9 +84,12 @@ Feature: If a market insurance pool does not have enough funds to cover a fundin When the network moves ahead "1" blocks And the mark price should be "1000" for the market "ETH/DEC19" + When time is updated to "2021-02-10T23:04:12Z" + Then system unix time is "1612998252" + When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | - | perp.ETH.value | 1000000000000000000000 | 0s | + | perp.ETH.value | 6200000000000000000000 | 0s | | perp.funding.cue | 1612998252 | 0s | When the network moves ahead "4" blocks @@ -98,15 +105,15 @@ Feature: If a market insurance pool does not have enough funds to cover a fundin And the settlement account should have a balance of "0" for the market "ETH/DEC19" And the insurance pool balance should be "200" for the market "ETH/DEC19" When the network moves ahead "1" blocks - And the mark price should be "1200" for the market "ETH/DEC19" + When time is updated to "2021-08-12T11:04:12Z" + Then system unix time is "1628766252" + When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | - | perp.ETH.value | 6200000000000000000000 | 0s | | perp.funding.cue | 1628766252 | 0s | - And the following funding period events should be emitted: | start | end | internal twap | external twap | funding payment | | 1612998252 | 1628766252 | 1200 | 6200 | -5000 | diff --git a/core/integration/features/settlement/0053-PERP-040.feature b/core/integration/features/settlement/0053-PERP-040.feature index 2b5a80faeb8..2de8f49b62e 100644 --- a/core/integration/features/settlement/0053-PERP-040.feature +++ b/core/integration/features/settlement/0053-PERP-040.feature @@ -61,18 +61,18 @@ Feature: Assert that the scaling factor is applied before the funding cap is app # send in external data to the perpetual market, it should not change anything and a MTM should not happen When the network moves ahead "1" blocks + Then system unix time is "1575072004" When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 3000000000000000000000 | 0s | - | perp.funding.cue | 1612998252 | 0s | + | perp.funding.cue | 1575072004 | 0s | When the network moves ahead "6" blocks - + When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 3000000000000000000000 | 0s | - | perp.funding.cue | 1628766252 | 0s | - + | perp.funding.cue | 1575072012 | 0s | # funding payments = s_twap * delta_t * interest_rate * fund rate scaling * dp = (3000-1200)*1*10.0*1000 = 18,000,000 # funding rate will be funding payment / s_twap = 18,000,000/(3,000*dp) = 6 # So having a lower/upper bound of -6/+6 will not change the result @@ -143,17 +143,18 @@ Feature: Assert that the scaling factor is applied before the funding cap is app # send in external data to the perpetual market, it should not change anything and a MTM should not happen When the network moves ahead "1" blocks - + Then system unix time is "1575072004" + When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 3000000000000000000000 | 0s | - | perp.funding.cue | 1612998252 | 0s | + | perp.funding.cue | 1575072004 | 0s | When the network moves ahead "6" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.ETH.value | 3000000000000000000000 | 0s | - | perp.funding.cue | 1628766252 | 0s | + | perp.funding.cue | 1575072012 | 0s | # funding payments = s_twap * delta_t * interest_rate * fund rate scaling * dp = (3000-1200)*1*10.0*1000 = 18,000,000 # funding rate will be funding payment / s_twap = 18,000,000/(3,000*dp) = 6 diff --git a/core/products/perpetual.go b/core/products/perpetual.go index a9814ba64cc..a1c9d388f11 100644 --- a/core/products/perpetual.go +++ b/core/products/perpetual.go @@ -912,8 +912,8 @@ func (p *Perpetual) calculateFundingPayment(t int64) *fundingData { // scale funding payment by fraction of funding period spent outside of auction timeSpentInAuction := p.auctions.timeSpent(p.startedAt, t) if timeSpentInAuction > 0 && delta > 0 { - scaling := (delta - timeSpentInAuction) / delta - fundingPayment = fundingPayment.Mul(num.DecimalFromInt64(scaling)) + scaling := num.DecimalFromInt64(delta - timeSpentInAuction).Div(num.DecimalFromInt64(delta)) + fundingPayment = fundingPayment.Mul(scaling) } // apply funding scaling factor From 75ce3f500cf228b8fbcdcdfd1f5f17d03d452923 Mon Sep 17 00:00:00 2001 From: Elias Van Ootegem Date: Mon, 15 Jul 2024 11:19:36 +0100 Subject: [PATCH 3/6] chore: update changelog Signed-off-by: Elias Van Ootegem --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88ba8d41877..c293cbd7d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - [11400](https://github.com/vegaprotocol/vega/issues/11400) - Add support for long block auction. - [11026](https://github.com/vegaprotocol/vega/issues/11026) - Add API flag to get paid liquidity fees for a `vAMM` using the parent key. - [11027](https://github.com/vegaprotocol/vega/issues/11027) - Add API filters to get fees and rewards by market, across epochs. +- [10360](https://github.com/vegaprotocol/vega/issues/10360) - Scale funding payment by fraction of period spent outside of auction. ### 🐛 Fixes From 0ac3bcd476c75f4c933e149c53508f5fd261d14f Mon Sep 17 00:00:00 2001 From: Witold Date: Fri, 12 Jul 2024 12:14:36 +0200 Subject: [PATCH 4/6] refactor: fix tests --- ...-028_twap_calculation_with_auction.feature | 2 +- core/products/perpetual.go | 2 +- core/products/perpetual_auctions_test.go | 40 ++++++++++++++----- core/products/perpetual_snapshot_test.go | 7 ++-- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature b/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature index d1fdaa27611..7c046703b68 100644 --- a/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature +++ b/core/integration/features/settlement/0053-PERP-028_twap_calculation_with_auction.feature @@ -138,7 +138,7 @@ Feature: Test internal and external twap calculation | internal twap | external twap | funding payment | | 10800 | 9800 | 714 | Then the network moves ahead "1" blocks -`` + # 8 mins in, still in continuous trading (fraction outside auction is ~6/8, hence the funding payment ends up being 6/8*500=~374) Given the network moves ahead "60" blocks Then the product data for the market "ETH/DEC19" should be: diff --git a/core/products/perpetual.go b/core/products/perpetual.go index a1c9d388f11..8429ce263c9 100644 --- a/core/products/perpetual.go +++ b/core/products/perpetual.go @@ -912,7 +912,7 @@ func (p *Perpetual) calculateFundingPayment(t int64) *fundingData { // scale funding payment by fraction of funding period spent outside of auction timeSpentInAuction := p.auctions.timeSpent(p.startedAt, t) if timeSpentInAuction > 0 && delta > 0 { - scaling := num.DecimalFromInt64(delta - timeSpentInAuction).Div(num.DecimalFromInt64(delta)) + scaling := num.DecimalOne().Sub(num.DecimalFromInt64(timeSpentInAuction).Div(num.DecimalFromInt64(delta))) fundingPayment = fundingPayment.Mul(scaling) } diff --git a/core/products/perpetual_auctions_test.go b/core/products/perpetual_auctions_test.go index 19c190b06c6..929c16d6397 100644 --- a/core/products/perpetual_auctions_test.go +++ b/core/products/perpetual_auctions_test.go @@ -74,17 +74,23 @@ func testDataPointInAuctionIgnored(t *testing.T) { // submit the first point then enter an auction submitPointWithDifference(t, perp, points[0], expectedTWAP) - whenAuctionStateChanges(t, perp, points[0].t+int64(time.Second), true) + auctionStart := points[0].t + int64(time.Second) + whenAuctionStateChanges(t, perp, auctionStart, true) // submit a crazy point difference, then a normal point submitPointWithDifference(t, perp, points[1], -9999999) submitPointWithDifference(t, perp, points[2], expectedTWAP) // now we leave auction and the crazy point difference will not affect the TWAP because it was in an auction period - whenAuctionStateChanges(t, perp, points[2].t+int64(time.Second), false) + auctionEnd := points[2].t + int64(time.Second) + whenAuctionStateChanges(t, perp, auctionEnd, false) + + currentPeriodLength := float64(points[len(points)-1].t - points[0].t) + timeInAuction := float64(auctionEnd - auctionStart) + periodFractionOutsideAuction := 1 - timeInAuction/currentPeriodLength fundingPayment := whenTheFundingPeriodEnds(t, perp, points[len(points)-1].t) - assert.Equal(t, int64(expectedTWAP), fundingPayment.Int64()) + assert.Equal(t, int64(periodFractionOutsideAuction*float64(expectedTWAP)), fundingPayment.Int64()) } func testDataPointsInAuctionOutOfOrder(t *testing.T) { @@ -107,18 +113,24 @@ func testDataPointsInAuctionOutOfOrder(t *testing.T) { whenAuctionStateChanges(t, perp, a1, true) whenAuctionStateChanges(t, perp, a2, false) + currentPeriodLength := float64(points[len(points)-1].t - points[0].t) + timeInAuction := float64(points[1].t - points[0].t + points[3].t - points[2].t) + periodFractionOutsideAuction := num.DecimalOne().Sub(num.DecimalFromFloat(timeInAuction).Div(num.DecimalFromFloat(currentPeriodLength))) // funding payment will be the constant diff in the first point - assert.Equal(t, "100", getFundingPayment(t, perp, nd)) + expected, _ := num.IntFromDecimal(periodFractionOutsideAuction.Mul(num.DecimalFromInt64(100))) + assert.Equal(t, num.IntToString(expected), getFundingPayment(t, perp, nd)) // now submit a point that is mid the auction period submitPointWithDifference(t, perp, points[2], 200) - assert.Equal(t, "150", getFundingPayment(t, perp, nd)) + + expected, _ = num.IntFromDecimal(periodFractionOutsideAuction.Mul(num.DecimalFromInt64(150))) + assert.Equal(t, num.IntToString(expected), getFundingPayment(t, perp, nd)) // now submit a point also in before the previous point, also in an auction period // and its contribution should be ignored. crazy := &testDataPoint{t: between(a1, points[1].t), price: num.NewUint(1000)} submitPointWithDifference(t, perp, crazy, 9999999) - assert.Equal(t, "150", getFundingPayment(t, perp, nd)) + assert.Equal(t, "49", getFundingPayment(t, perp, nd)) } func testAuctionFundingPeriodReset(t *testing.T) { @@ -136,7 +148,8 @@ func testAuctionFundingPeriodReset(t *testing.T) { whenAuctionStateChanges(t, perp, points[0].t+int64(time.Second), true) fundingPayment := whenTheFundingPeriodEnds(t, perp, points[0].t+int64(2*time.Second)) - assert.Equal(t, int64(expectedTWAP), fundingPayment.Int64()) + periodFractionOutsideAuction := 0.5 + assert.Equal(t, int64(periodFractionOutsideAuction*float64(expectedTWAP)), fundingPayment.Int64()) // should still be on an auction to ending another funding period should give 0 submitPointWithDifference(t, perp, points[1], -999999) @@ -148,7 +161,7 @@ func testAuctionFundingPeriodReset(t *testing.T) { whenAuctionStateChanges(t, perp, between(points[2].t, points[3].t), false) fundingPayment = whenTheFundingPeriodEnds(t, perp, points[3].t) - assert.Equal(t, int64(100), fundingPayment.Int64()) + assert.Equal(t, int64(periodFractionOutsideAuction*100), fundingPayment.Int64()) // now we're not in an auction, ending the period again will preserve that fundingPayment = whenTheFundingPeriodEnds(t, perp, points[3].t+int64(time.Hour)) @@ -171,7 +184,8 @@ func testFundingDataAtInAuctionPeriodStart(t *testing.T) { end := points[0].t + int64(2*time.Second) fundingPayment := whenTheFundingPeriodEnds(t, perp, end) - assert.Equal(t, int64(expectedTWAP), fundingPayment.Int64()) + periodFractionOutsideAuction := 0.5 + assert.Equal(t, int64(periodFractionOutsideAuction*float64(expectedTWAP)), fundingPayment.Int64()) // but if we query the funding payment right now it'll be zero because this 0 length, just started // funding period is all in auction @@ -203,9 +217,15 @@ func testPastFundingPaymentInAuction(t *testing.T) { perp.broker.EXPECT().Send(gomock.Any()).Times(1) require.NoError(t, perp.perpetual.SubmitDataPoint(context.Background(), points[2].price, points[2].t)) + endPrev := end end = points[2].t - int64(500*time.Millisecond) fundingPayment = whenTheFundingPeriodEnds(t, perp, end) - assert.Equal(t, int64(expectedTWAP), fundingPayment.Int64()) + + currentPeriodLength := float64(end - endPrev) + timeInAuction := float64(end - points[1].t) + periodFractionOutsideAuction := 1 - timeInAuction/currentPeriodLength + + assert.Equal(t, int64(periodFractionOutsideAuction*float64(expectedTWAP)), fundingPayment.Int64()) } func testPastFundingPayment(t *testing.T) { diff --git a/core/products/perpetual_snapshot_test.go b/core/products/perpetual_snapshot_test.go index 0e819d86f2e..77cca74a4b8 100644 --- a/core/products/perpetual_snapshot_test.go +++ b/core/products/perpetual_snapshot_test.go @@ -64,9 +64,10 @@ func TestPerpetualSnapshot(t *testing.T) { whenAuctionStateChanges(t, perps, points[2].t+int64(time.Second), false) fundingPayment := getFundingPayment(t, perps, points[3].t) - assert.Equal(t, "1234", fundingPayment) + // 2/3 of funding period spent in auction so expecting funding payment of 1/3*1234=~411 + assert.Equal(t, "411", fundingPayment) fundingPayment = getFundingPayment(t, perps, points[3].t) - assert.Equal(t, "1234", fundingPayment) + assert.Equal(t, "411", fundingPayment) // now get the serialised state, and try to load it state1 := perps.perpetual.Serialize() @@ -88,7 +89,7 @@ func TestPerpetualSnapshot(t *testing.T) { // check funding payment comes out the same fundingPayment = getFundingPayment(t, perps2, points[3].t) - assert.Equal(t, "1234", fundingPayment) + assert.Equal(t, "411", fundingPayment) // check the the time-trigger has been set properly cfg := scheduleSrc.Data.GetInternalTimeTriggerSpecConfiguration() From 1e81e3bc27c049812c6f9958d0ab555896e10dc9 Mon Sep 17 00:00:00 2001 From: Elias Van Ootegem Date: Mon, 15 Jul 2024 10:54:46 +0100 Subject: [PATCH 5/6] chore: remove redundant and misleading steps setting system time Signed-off-by: Elias Van Ootegem --- .../features/settlement/0019-MCAL_018.feature | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/core/integration/features/settlement/0019-MCAL_018.feature b/core/integration/features/settlement/0019-MCAL_018.feature index c0ab60f0185..cf0f90e61ed 100644 --- a/core/integration/features/settlement/0019-MCAL_018.feature +++ b/core/integration/features/settlement/0019-MCAL_018.feature @@ -2,7 +2,7 @@ Feature: check when settlement data precision is different/equal to the settleme Background: - And the following assets are registered: + Given the following assets are registered: | id | decimal places | | USD | 2 | @@ -24,17 +24,15 @@ Feature: check when settlement data precision is different/equal to the settleme | market.auction.minimumDuration | 1 | | limits.markets.maxPeggedOrders | 2 | - @Perpetual + @Perpetual @PBlock Scenario: 001 oracle data decimal > asset decimal 0070-MKTD-018, 0019-MCAL-091 - And the markets: + Given the markets: | id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | position decimal places | market type | sla params | | ETH/DEC19 | ETH | USD | default-simple-risk-model-3 | default-margin-calculator | 1 | default-none | default-none | perp-oracle-1 | 0.25 | 0 | -1 | perp | default-futures | And the following network parameters are set: - | name | value | - | market.auction.minimumDuration | 1 | - | limits.markets.maxPeggedOrders | 2 | - Given the following network parameters are set: | name | value | + | market.auction.minimumDuration | 1 | + | limits.markets.maxPeggedOrders | 2 | | network.markPriceUpdateMaximumFrequency | 5s | And the parties deposit on asset's general account the following amount: | party | asset | amount | @@ -89,13 +87,11 @@ Feature: check when settlement data precision is different/equal to the settleme | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | When time is updated to "2021-02-11T16:35:24Z" - Then system unix time is "1613061324" When the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | When time is updated to "2021-08-12T11:04:07Z" - Then system unix time is "1628766247" When the network moves ahead "5" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE1": @@ -114,7 +110,7 @@ Feature: check when settlement data precision is different/equal to the settleme @Perpetual Scenario: 002 oracle data decimal < asset decimal 0070-MKTD-019 - And the markets: + Given the markets: | id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | position decimal places | decimal places | market type | sla params | | ETH/DEC19 | ETH | USD | default-simple-risk-model-3 | default-margin-calculator | 1 | default-none | default-none | perp-oracle-3 | 0.25 | 0 | 1 | 2 | perp | default-futures | And the following network parameters are set: @@ -177,14 +173,12 @@ Feature: check when settlement data precision is different/equal to the settleme | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | When time is updated to "2021-02-11T16:35:24Z" - Then system unix time is "1613061324" When the oracles broadcast data with block time signed with "0xCAFECAFE3": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | When time is updated to "2021-08-12T11:04:07Z" - Then system unix time is "1628766247" When the network moves ahead "5" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE3": @@ -266,14 +260,12 @@ Feature: check when settlement data precision is different/equal to the settleme | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | When time is updated to "2021-02-11T16:35:24Z" - Then system unix time is "1613061324" When the oracles broadcast data with block time signed with "0xCAFECAFE2": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | When time is updated to "2021-08-12T11:04:07Z" - Then system unix time is "1628766247" When the network moves ahead "5" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE2": From d1a53e146ec96a4bde7c02d586478909f482a5dc Mon Sep 17 00:00:00 2001 From: Elias Van Ootegem Date: Mon, 15 Jul 2024 11:17:51 +0100 Subject: [PATCH 6/6] chore: avoid setting times during current scenario, use blocks instead Signed-off-by: Elias Van Ootegem --- .../features/settlement/0019-MCAL_018.feature | 76 ++++++++++++------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/core/integration/features/settlement/0019-MCAL_018.feature b/core/integration/features/settlement/0019-MCAL_018.feature index cf0f90e61ed..1dcd31ec0fa 100644 --- a/core/integration/features/settlement/0019-MCAL_018.feature +++ b/core/integration/features/settlement/0019-MCAL_018.feature @@ -24,9 +24,11 @@ Feature: check when settlement data precision is different/equal to the settleme | market.auction.minimumDuration | 1 | | limits.markets.maxPeggedOrders | 2 | - @Perpetual @PBlock + @Perpetual Scenario: 001 oracle data decimal > asset decimal 0070-MKTD-018, 0019-MCAL-091 - Given the markets: + # start at this timestamp + Given time is updated to "2021-02-11T16:35:21Z" + And the markets: | id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | position decimal places | market type | sla params | | ETH/DEC19 | ETH | USD | default-simple-risk-model-3 | default-margin-calculator | 1 | default-none | default-none | perp-oracle-1 | 0.25 | 0 | -1 | perp | default-futures | And the following network parameters are set: @@ -60,11 +62,13 @@ Feature: check when settlement data precision is different/equal to the settleme | aux2 | ETH/DEC19 | buy | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | | aux | ETH/DEC19 | sell | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | - Then the opening auction period ends for market "ETH/DEC19" + # Time moves forwards 2s + Then the network moves ahead "2" blocks And the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "ETH/DEC19" + # Another +1s making it 2021-02-11T16:35:24 When the network moves ahead "1" blocks - When the parties place the following orders: + And the parties place the following orders: | party | market id | side | volume | price | resulting trades | type | tif | | party1 | ETH/DEC19 | sell | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | | party2 | ETH/DEC19 | buy | 1 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | @@ -86,12 +90,18 @@ Feature: check when settlement data precision is different/equal to the settleme | party3 | USD | ETH/DEC19 | 132000 | 99866000 | | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | - When time is updated to "2021-02-11T16:35:24Z" - When the oracles broadcast data with block time signed with "0xCAFECAFE1": + And the oracles broadcast data with block time signed with "0xCAFECAFE1": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | - When time is updated to "2021-08-12T11:04:07Z" + # 4320h is 6 * 30 * 24 (180days, or 6 months) with a block duration of 10 days (so 18 ticks) + # making it 2021-08-10T16:35:24 + Then the network moves ahead "4320h" with block duration of "240h" + # now move ahead the remaining time to get to 2021-08-11T11:04:07 + # We're moving by 66,583s (18 * 3600 + 29 * 60 + 43), divisible by 11 (6053) + # So set block duration to 6053 for 11 ticks + And the network moves ahead "18h29m43s" with block duration of "6053s" + #When time is updated to "2021-08-12T11:04:07Z" When the network moves ahead "5" blocks When the oracles broadcast data with block time signed with "0xCAFECAFE1": @@ -110,7 +120,8 @@ Feature: check when settlement data precision is different/equal to the settleme @Perpetual Scenario: 002 oracle data decimal < asset decimal 0070-MKTD-019 - Given the markets: + Given time is updated to "2021-02-11T16:35:21Z" + And the markets: | id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | position decimal places | decimal places | market type | sla params | | ETH/DEC19 | ETH | USD | default-simple-risk-model-3 | default-margin-calculator | 1 | default-none | default-none | perp-oracle-3 | 0.25 | 0 | 1 | 2 | perp | default-futures | And the following network parameters are set: @@ -146,11 +157,12 @@ Feature: check when settlement data precision is different/equal to the settleme | aux2 | ETH/DEC19 | buy | 100 | 100000 | 0 | TYPE_LIMIT | TIF_GTC | | aux | ETH/DEC19 | sell | 100 | 100000 | 0 | TYPE_LIMIT | TIF_GTC | - Then the opening auction period ends for market "ETH/DEC19" + Then the network moves ahead "2" blocks And the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "ETH/DEC19" + # Time at start of the scenario is now +3s When the network moves ahead "1" blocks - When the parties place the following orders: + And the parties place the following orders: | party | market id | side | volume | price | resulting trades | type | tif | | party1 | ETH/DEC19 | sell | 100 | 100000 | 0 | TYPE_LIMIT | TIF_GTC | | party2 | ETH/DEC19 | buy | 100 | 100000 | 1 | TYPE_LIMIT | TIF_GTC | @@ -172,22 +184,29 @@ Feature: check when settlement data precision is different/equal to the settleme | party3 | USD | ETH/DEC19 | 132000 | 99866000 | | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | - When time is updated to "2021-02-11T16:35:24Z" When the oracles broadcast data with block time signed with "0xCAFECAFE3": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | - When time is updated to "2021-08-12T11:04:07Z" + # 4320h is 6 * 30 * 24 (180days, or 6 months) with a block duration of 10 days (so 18 ticks) + # making it 2021-08-10T16:35:24 + Then the network moves ahead "4320h" with block duration of "240h" + # now move ahead the remaining time to get to 2021-08-11T11:04:07 + # We're moving by 66,583s (18 * 3600 + 29 * 60 + 43), divisible by 11 (6053) + # So set block duration to 6053 for 11 ticks + And the network moves ahead "18h29m43s" with block duration of "6053s" - When the network moves ahead "5" blocks - When the oracles broadcast data with block time signed with "0xCAFECAFE3": + # When time is updated to "2021-08-12T11:04:07Z" + + And the network moves ahead "5" blocks + Then the oracles broadcast data with block time signed with "0xCAFECAFE3": | name | value | time offset | | perp.ETH.value | 30000 | 0s | | perp.funding.cue | 1628766252 | 0s | #1628766252 is half year after the first oracel time - Then debug funding period events + #Then debug funding period events And the following transfers should happen: | from | to | from account | to account | market id | amount | asset | | aux2 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 74700 | USD | @@ -196,7 +215,9 @@ Feature: check when settlement data precision is different/equal to the settleme | market | aux | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 74700 | USD | | market | party1 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 149400 | USD | + @PBlock Scenario: 003 oracle data decimal = asset decimal, while market decimal is 1, 0070-MKTD-020 + Given time is updated to "2021-02-11T16:35:21Z" And the markets: | id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | decimal places | position decimal places | market type | sla params | | ETH/DEC19 | ETH | USD | default-simple-risk-model-3 | default-margin-calculator | 1 | default-none | default-none | perp-oracle-2 | 0.25 | 0 | 1 | -1 | perp | default-futures | @@ -204,7 +225,7 @@ Feature: check when settlement data precision is different/equal to the settleme | name | value | | market.auction.minimumDuration | 1 | | limits.markets.maxPeggedOrders | 2 | - Given the following network parameters are set: + And the following network parameters are set: | name | value | | network.markPriceUpdateMaximumFrequency | 5s | And the parties deposit on asset's general account the following amount: @@ -233,7 +254,7 @@ Feature: check when settlement data precision is different/equal to the settleme | aux2 | ETH/DEC19 | buy | 1 | 10000 | 0 | TYPE_LIMIT | TIF_GTC | | aux | ETH/DEC19 | sell | 1 | 10000 | 0 | TYPE_LIMIT | TIF_GTC | - Then the opening auction period ends for market "ETH/DEC19" + Then the network moves ahead "2" blocks And the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "ETH/DEC19" When the network moves ahead "1" blocks @@ -259,29 +280,30 @@ Feature: check when settlement data precision is different/equal to the settleme | party3 | USD | ETH/DEC19 | 132000 | 99866000 | | lp1 | USD | ETH/DEC19 | 6600000 | 492200000 | - When time is updated to "2021-02-11T16:35:24Z" When the oracles broadcast data with block time signed with "0xCAFECAFE2": | name | value | time offset | | perp.funding.cue | 1613061324 | 0s | - When time is updated to "2021-08-12T11:04:07Z" - - When the network moves ahead "5" blocks - When the oracles broadcast data with block time signed with "0xCAFECAFE2": + # 4320h is 6 * 30 * 24 (180days, or 6 months) with a block duration of 10 days (so 18 ticks) + # making it 2021-08-10T16:35:24 + Then the network moves ahead "4320h" with block duration of "240h" + # now move ahead the remaining time to get to 2021-08-11T11:04:07 + # We're moving by 66,583s (18 * 3600 + 29 * 60 + 43), divisible by 11 (6053) + # So set block duration to 6053 for 11 ticks + And the network moves ahead "18h29m43s" with block duration of "6053s" + + And the network moves ahead "5" blocks + And the oracles broadcast data with block time signed with "0xCAFECAFE2": | name | value | time offset | | perp.ETH.value | 300000 | 0s | | perp.funding.cue | 1628766252 | 0s | #1628766252 is half year after the first oracel time - And the following transfers should happen: + Then the following transfers should happen: | from | to | from account | to account | market id | amount | asset | | aux2 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 74700 | USD | | party2 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 74700 | USD | | party3 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 74700 | USD | | market | aux | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 74700 | USD | | market | party1 | ACCOUNT_TYPE_SETTLEMENT | ACCOUNT_TYPE_MARGIN | ETH/DEC19 | 149400 | USD | - - - -