Skip to content

Commit

Permalink
Merge pull request #9673 from vegaprotocol/closeout-bug
Browse files Browse the repository at this point in the history
fix: ensure zero margin on perps
  • Loading branch information
EVODelavega authored Oct 6, 2023
2 parents c815564 + d40a67d commit 91b62fd
Show file tree
Hide file tree
Showing 4 changed files with 369 additions and 53 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@
- [9655](https://github.com/vegaprotocol/vega/issues/9655) - Make liquidity monitoring parameter required in market proposals validation
- [9280](https://github.com/vegaprotocol/vega/issues/9280) - Fix block height off by one issue.
- [9658](https://github.com/vegaprotocol/vega/issues/9658) - Fix `updateVolumeDiscountProgram` GraphQL resolver.
- [9672](https://github.com/vegaprotocol/vega/issues/9672) - Fix margin being non-zero on `PERPS`, add tests to ensure distressed parties are handled correctly

## 0.72.1

Expand Down
292 changes: 291 additions & 1 deletion core/integration/features/settlement/mark_to_market_perpetual.feature
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Feature: Test mark to market settlement with periodicity, takes the first scenar

Background:

And the perpetual oracles from "0xCAFECAFE1":
Given 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 | ETH | perp.ETH.value | TYPE_INTEGER | perp.funding.cue | TYPE_TIMESTAMP | 0 | 0 | 0 | 0 | ETH | 18 |
And the liquidity sla params named "SLA":
Expand Down Expand Up @@ -162,3 +162,293 @@ Feature: Test mark to market settlement with periodicity, takes the first scenar
| party1 | market | ACCOUNT_TYPE_MARGIN | ACCOUNT_TYPE_SETTLEMENT | ETH/DEC19 | 200000 | ETH |
And the cumulated balance for all accounts should be worth "330000000"
And the settlement account should have a balance of "0" for the market "ETH/DEC19"

@Perpetual @PerpMargin
Scenario: A party that never holds a position should end with margin levels at zero
Given the following network parameters are set:
| name | value |
| network.markPriceUpdateMaximumFrequency | 0s |
And the parties deposit on asset's general account the following amount:
| party | asset | amount |
| party1 | ETH | 10000000 |
| party2 | ETH | 10000000 |
| party3 | ETH | 10000000 |
| party4 | ETH | 10000000 |
| aux | ETH | 100000000 |
| aux2 | ETH | 100000000 |
| lpprov | ETH | 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 |
Then the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 120000 | 9880000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |

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 |
Then the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 5041200 | 4958800 |

When the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| party3 | ETH/DEC19 | buy | 1 | 1999 | 0 | TYPE_LIMIT | TIF_GTC | p3-buy-1 |
Then the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party3 | ETH/DEC19 | 110000 | 121000 | 132000 | 154000 |
And the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 5041200 | 4958800 |
| party3 | ETH | ETH/DEC19 | 132000 | 9868000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |


# 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 the oracles broadcast data with block time signed with "0xCAFECAFE1":
| name | value | time offset |
| perp.ETH.value | 2100000000000000000000 | 0s |
| perp.funding.cue | 1511924180 | 0s |

# move to the block before we should MTM and check for no changes
When the network moves ahead "3" blocks
Then the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 1440000 | 8560000 |
| party3 | ETH | ETH/DEC19 | 132000 | 9868000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |
And the cumulated balance for all accounts should be worth "340000000"
And the settlement account should have a balance of "0" for the market "ETH/DEC19"

When the network moves ahead "1" blocks
And 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 |
Then the parties should have the following profit and loss:
| party | volume | unrealised pnl | realised pnl |
| party1 | -1 | 0 | 0 |
| party2 | 1 | 0 | 0 |
| party3 | 0 | 0 | 0 |
# make sure the margin levels for party3 have not changed
And the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party3 | ETH/DEC19 | 110000 | 121000 | 132000 | 154000 |

When the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| party4 | ETH/DEC19 | buy | 1 | 2001 | 1 | TYPE_LIMIT | TIF_GTC | p4-buy-1 |
Then the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party4 | ETH/DEC19 | 110000 | 121000 | 132000 | 154000 |
And the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 1440000 | 8560000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |
| party3 | ETH | ETH/DEC19 | 132000 | 9868000 |
| party4 | ETH | ETH/DEC19 | 132000 | 9865999 |
When the network moves ahead "1" blocks
Then the parties should have the following profit and loss:
| party | volume | unrealised pnl | realised pnl |
| party1 | -2 | -1002000 | 0 |
| party2 | 1 | 1001000 | 0 |
| party3 | 0 | 0 | 0 |
| party4 | 1 | 0 | 0 |
When the parties cancel the following orders:
| party | reference | error |
| party3 | p3-buy-1 | |
Then the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party3 | ETH/DEC19 | 0 | 0 | 0 | 0 |
And the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 7680240 | 1317760 |
| party2 | ETH | ETH/DEC19 | 266532 | 10733468 |
| party3 | ETH | ETH/DEC19 | 0 | 10000000 |
| party4 | ETH | ETH/DEC19 | 266532 | 9731467 |
And the cumulated balance for all accounts should be worth "340000000"
And the settlement account should have a balance of "0" for the market "ETH/DEC19"

@Perpetual @PerpMargin
Scenario: A party that never held a position should simply have its orders closed, but never see their margin get confiscated
Given the following network parameters are set:
| name | value |
| network.markPriceUpdateMaximumFrequency | 0s |
And the parties deposit on asset's general account the following amount:
| party | asset | amount |
| party1 | ETH | 10000000 |
| party2 | ETH | 10000000 |
| party3 | ETH | 1000000 |
| party4 | ETH | 10000000 |
| aux | ETH | 100000000 |
| aux2 | ETH | 100000000 |
| lpprov | ETH | 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 |
Then the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 120000 | 9880000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |

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 |
Then the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 5041200 | 4958800 |

When the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| party3 | ETH/DEC19 | buy | 1 | 1999 | 0 | TYPE_LIMIT | TIF_GTC | p3-buy-1 |
Then the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party3 | ETH/DEC19 | 110000 | 121000 | 132000 | 154000 |
And the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 5041200 | 4958800 |
| party3 | ETH | ETH/DEC19 | 132000 | 868000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |


# 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 the oracles broadcast data with block time signed with "0xCAFECAFE1":
| name | value | time offset |
| perp.ETH.value | 2100000000000000000000 | 0s |
| perp.funding.cue | 1511924180 | 0s |

# move to the block before we should MTM and check for no changes
When the network moves ahead "3" blocks
Then the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 1440000 | 8560000 |
| party3 | ETH | ETH/DEC19 | 132000 | 868000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |
And the cumulated balance for all accounts should be worth "331000000"
And the settlement account should have a balance of "0" for the market "ETH/DEC19"

When the network moves ahead "1" blocks
And 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 |
Then the parties should have the following profit and loss:
| party | volume | unrealised pnl | realised pnl |
| party1 | -1 | 0 | 0 |
| party2 | 1 | 0 | 0 |
| party3 | 0 | 0 | 0 |
# make sure the margin levels for party3 have not changed
And the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party3 | ETH/DEC19 | 110000 | 121000 | 132000 | 154000 |

When the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| party4 | ETH/DEC19 | buy | 1 | 2001 | 1 | TYPE_LIMIT | TIF_GTC | p4-buy-1 |
Then the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party4 | ETH/DEC19 | 110000 | 121000 | 132000 | 154000 |
And the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 1440000 | 8560000 |
| party2 | ETH | ETH/DEC19 | 132000 | 9867000 |
| party3 | ETH | ETH/DEC19 | 132000 | 868000 |
| party4 | ETH | ETH/DEC19 | 132000 | 9865999 |
When the network moves ahead "1" blocks
Then the parties should have the following profit and loss:
| party | volume | unrealised pnl | realised pnl |
| party1 | -2 | -1002000 | 0 |
| party2 | 1 | 1001000 | 0 |
| party3 | 0 | 0 | 0 |
| party4 | 1 | 0 | 0 |
# let's get party3 to run out of margin
When the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif | reference |
| party3 | ETH/DEC19 | buy | 2 | 1999 | 0 | TYPE_LIMIT | TIF_GTC | p3-buy-2 |
Then the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party3 | ETH/DEC19 | 660330 | 726363 | 792396 | 924462 |
And the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 7680240 | 1317760 |
| party2 | ETH | ETH/DEC19 | 266532 | 10733468 |
| party3 | ETH | ETH/DEC19 | 792396 | 207604 |
| party4 | ETH | ETH/DEC19 | 266532 | 9731467 |

When the parties place the following orders:
| party | market id | side | volume | price | resulting trades | type | tif |
| aux | ETH/DEC19 | sell | 1 | 4001 | 0 | TYPE_LIMIT | TIF_GTC |
| aux2 | ETH/DEC19 | buy | 1 | 4001 | 1 | TYPE_LIMIT | TIF_GTC |
And the network moves ahead "1" blocks
Then the parties should have the following margin levels:
| party | market id | maintenance | search | initial | release |
| party3 | ETH/DEC19 | 0 | 0 | 0 | 0 |
And the parties should have the following account balances:
| party | asset | market id | margin | general |
| party1 | ETH | ETH/DEC19 | 3680240 | 1317760 |
| party2 | ETH | ETH/DEC19 | 5270532 | 7729468 |
| party3 | ETH | ETH/DEC19 | 0 | 1000000 |
| party4 | ETH | ETH/DEC19 | 5270532 | 6727467 |
Loading

0 comments on commit 91b62fd

Please sign in to comment.