code.vegaprotocol.io/vega@v0.79.0/core/integration/features/amm/vamm-wash-trade.feature (about)

     1  Feature: Derived key trades with its primary key.
     2    Background:
     3      Given the average block duration is "1"
     4      And the margin calculator named "margin-calculator-1":
     5        | search factor | initial factor | release factor |
     6        | 1.2           | 1.5            | 1.7            |
     7      And the log normal risk model named "log-normal-risk-model":
     8        | risk aversion | tau                   | mu | r   | sigma |
     9        | 0.001         | 0.0011407711613050422 | 0  | 0.9 | 3.0   |
    10      And the liquidity monitoring parameters:
    11        | name       | triggering ratio | time window | scaling factor |
    12        | lqm-params | 1.00             | 20s         | 1              |
    13        
    14      And the following network parameters are set:
    15        | name                                                | value |
    16        | market.value.windowLength                           | 60s   |
    17        | network.markPriceUpdateMaximumFrequency             | 0s    |
    18        | limits.markets.maxPeggedOrders                      | 6     |
    19        | market.auction.minimumDuration                      | 1     |
    20        | market.fee.factors.infrastructureFee                | 0.001 |
    21        | market.fee.factors.makerFee                         | 0.004 |
    22        | spam.protection.max.stopOrdersPerMarket             | 5     |
    23        | market.liquidity.equityLikeShareFeeFraction         | 1     |
    24        | market.amm.minCommitmentQuantum                     | 1     |
    25        | market.liquidity.bondPenaltyParameter               | 0.2   |
    26        | market.liquidity.stakeToCcyVolume                   | 1     |
    27        | market.liquidity.successorLaunchWindowLength        | 1h    |
    28        | market.liquidity.sla.nonPerformanceBondPenaltySlope | 0.1   |
    29        | market.liquidity.sla.nonPerformanceBondPenaltyMax   | 0.6   |
    30        | validators.epoch.length                             | 10s   |
    31        | market.liquidity.earlyExitPenalty                   | 0.25  |
    32        | market.liquidity.maximumLiquidityFeeFactorLevel     | 0.25  |
    33      #risk factor short:3.5569036
    34      #risk factor long:0.801225765
    35      And the following assets are registered:
    36        | id  | decimal places |
    37        | USD | 0              |
    38      And the fees configuration named "fees-config-1":
    39        | maker fee | infrastructure fee |
    40        | 0.0004    | 0.001              |
    41  
    42      And the liquidity sla params named "SLA-22":
    43        | price range | commitment min time fraction | performance hysteresis epochs | sla competition factor |
    44        | 0.5         | 0.6                          | 1                             | 1.0                    |
    45  
    46      # Create 2 identical markets, one will be used to test moving the mid price in steps of one, the other will do the same in a single trade.
    47      And the markets:
    48        | 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 |
    49        | 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     |
    50  
    51      # Setting up the accounts and vAMM submission now is part of the background, because we'll be running scenarios 0090-VAMM-006 through 0090-VAMM-014 on this setup
    52      Given the parties deposit on asset's general account the following amount:
    53        | party  | asset | amount  |
    54        | lp1    | USD   | 1000000 |
    55        | lp2    | USD   | 1000000 |
    56        | lp3    | USD   | 1000000 |
    57        | lp4    | USD   | 1000000 |
    58        | party1 | USD   | 1000000 |
    59        | party2 | USD   | 1000000 |
    60        | party3 | USD   | 1000000 |
    61        | party4 | USD   | 1000000 |
    62        | party5 | USD   | 1000000 |
    63        | party6 | USD   | 1000000 |
    64        | vamm1  | USD   | 1000000 |
    65        | vamm2  | USD   | 1000000 |
    66  
    67      When the parties submit the following liquidity provision:
    68        | id   | party | market id | commitment amount | fee   | lp type    |
    69        | lp_1 | lp1   | ETH/MAR22 | 600               | 0.02  | submission |
    70        | lp_2 | lp2   | ETH/MAR22 | 400               | 0.015 | submission |
    71      Then the network moves ahead "4" blocks
    72      And the current epoch is "0"
    73  
    74      And the parties place the following orders:
    75        | party  | market id | side | volume | price | resulting trades | type       | tif     | reference |
    76        | lp1    | ETH/MAR22 | buy  | 20     | 40    | 0                | TYPE_LIMIT | TIF_GTC | lp1-b     |
    77        | party1 | ETH/MAR22 | buy  | 1      | 100   | 0                | TYPE_LIMIT | TIF_GTC |           |
    78        | party2 | ETH/MAR22 | sell | 1      | 100   | 0                | TYPE_LIMIT | TIF_GTC |           |
    79        | lp1    | ETH/MAR22 | sell | 10     | 160   | 0                | TYPE_LIMIT | TIF_GTC | lp1-s     |
    80      When the opening auction period ends for market "ETH/MAR22"
    81      Then the following trades should be executed:
    82        | buyer  | price | size | seller |
    83        | party1 | 100   | 1    | party2 |
    84      And the market data for the market "ETH/MAR22" should be:
    85        | mark price | trading mode            | target stake | supplied stake | open interest | ref price | mid price | static mid price |
    86        | 100        | TRADING_MODE_CONTINUOUS | 39           | 1000           | 1             | 100       | 100       | 100              |
    87  
    88      When the parties submit the following AMM:
    89        | party | market id | amount | slippage | base | lower bound | upper bound | lower leverage | upper leverage | proposed fee |
    90        | vamm1 | ETH/MAR22 | 100000 | 0.1      | 100  | 85          | 150         | 4              | 4              | 0.01         |
    91      Then the AMM pool status should be:
    92        | party | market id | amount | status        | base | lower bound | upper bound | lower leverage | upper leverage |
    93        | vamm1 | ETH/MAR22 | 100000 | STATUS_ACTIVE | 100  | 85          | 150         | 4              | 4              |
    94  
    95      And set the following AMM sub account aliases:
    96        | party | market id | alias    |
    97        | vamm1 | ETH/MAR22 | vamm1-id |
    98      And the following transfers should happen:
    99        | from  | from account         | to       | to account           | market id | amount | asset | is amm | type                  |
   100        | vamm1 | ACCOUNT_TYPE_GENERAL | vamm1-id | ACCOUNT_TYPE_GENERAL |           | 100000 | USD   | true   | TRANSFER_TYPE_AMM_LOW |
   101  
   102    @VAMM
   103    Scenario: Simply have the vamm1 submit an order to the book that uncrosses with its own derived key.
   104      When the parties place the following orders:
   105        | party | market id | side | volume | price | resulting trades | type       | tif     | reference |
   106        | vamm1 | ETH/MAR22 | buy  | 1      | 101   | 1                | TYPE_LIMIT | TIF_GTC | vamm1-b   |
   107      And the network moves ahead "1" blocks
   108      # trade with own derived key
   109      Then the following trades should be executed:
   110        | buyer | price | size | seller   | is amm |
   111        | vamm1 | 100   | 1    | vamm1-id | true   |
   112  	And the parties should have the following profit and loss:
   113        | party    | volume | unrealised pnl | realised pnl | is amm |
   114        | party1   | 1      | 0              | 0            |        |
   115        | party2   | -1     | 0              | 0            |        |
   116        | vamm1    | 1      | 0              | 0            |        |
   117        | vamm1-id | -1     | 0              | 0            | true   |
   118  
   119      # Now assume someone managed to submit an order on behalf of the derived key
   120      When the parties place the following hacked orders:
   121        | party    | market id | side | volume | price | resulting trades | type        | tif     | reference | is amm |
   122        | vamm1-id | ETH/MAR22 | buy  | 1      | 0     | 1                | TYPE_MARKET | TIF_FOK | vamm-b    | true   |
   123      Then the following trades should be executed:
   124        | buyer    | price | size | seller | is amm |
   125        | vamm1-id | 160   | 1    | lp1    | true   |
   126  
   127      When the network moves ahead "1" blocks
   128  	Then the parties should have the following profit and loss:
   129        | party    | volume | unrealised pnl | realised pnl | is amm |
   130        | party1   | 1      | 60             | 0            |        |
   131        | party2   | -1     | -60            | 0            |        |
   132        | vamm1    | 1      | 60             | 0            |        |
   133        | vamm1-id | 0      | 0              | -60          | true   |
   134        | lp1      | -1     | 0              | 0            |        |
   135  
   136      # let's re-open the position for the vAMM, and cancel it using the reduce only method
   137      When the parties place the following orders:
   138        | party | market id | side | volume | price | resulting trades | type       | tif     | reference |
   139        | vamm1 | ETH/MAR22 | buy  | 2      | 101   | 1                | TYPE_LIMIT | TIF_GTC | vamm1-b2  |
   140      Then the following trades should be executed:
   141        | buyer | price | size | seller   | is amm |
   142        | vamm1 | 100   | 2    | vamm1-id | true   |
   143  
   144      # Check the positions
   145      When the network moves ahead "1" blocks
   146  	Then the parties should have the following profit and loss:
   147        | party    | volume | unrealised pnl | realised pnl | is amm |
   148        | party1   | 1      | 0              | 0            |        |
   149        | party2   | -1     | 0              | 0            |        |
   150        | vamm1    | 3      | 0              | 0            |        |
   151        | vamm1-id | -2     | 0              | -60          | true   |
   152        | lp1      | -1     | 60             | 0            |        |
   153  
   154      # Now the vamm shouldn't generate any more sell orders
   155      When the parties cancel the following AMM:
   156        | party | market id | method             |
   157        | vamm1 | ETH/MAR22 | METHOD_REDUCE_ONLY |
   158      # ensure no sell trades
   159      Then the parties place the following orders:
   160        | party  | market id | side | volume | price | resulting trades | type       | tif     | reference |
   161        | party1 | ETH/MAR22 | buy  | 1      | 60    | 0                | TYPE_LIMIT | TIF_GTC | p1-b2     |
   162  
   163      When the parties place the following orders:
   164        | party  | market id | side | volume | price | resulting trades | type       | tif     | reference |
   165        | party2 | ETH/MAR22 | sell | 1      | 90    | 1                | TYPE_LIMIT | TIF_GTC | p2-s2     |
   166      Then the following trades should be executed:
   167        | buyer    | price | size | seller | is amm |
   168        | vamm1-id | 100   | 1    | party2 | true   |
   169  
   170      # ensure the vAMM position is indeed reduced
   171      When the network moves ahead "1" blocks
   172  	Then the parties should have the following profit and loss:
   173        | party    | volume | unrealised pnl | realised pnl | is amm |
   174        | party1   | 1      | 0              | 0            |        |
   175        | party2   | -2     | 0              | 0            |        |
   176        | vamm1    | 3      | 0              | 0            |        |
   177        | vamm1-id | -1     | 0              | -60          | true   |
   178        | lp1      | -1     | 60             | 0            |        |
   179  
   180      # Now let's see what happens if someone manages to submit a sell order for a reduce-only AMM key
   181      When the parties place the following hacked orders:
   182        | party    | market id | side | volume | price | resulting trades | type        | tif     | reference | is amm |
   183        | vamm1-id | ETH/MAR22 | buy  | 2      | 0     | 1                | TYPE_MARKET | TIF_FOK | vamm-c    | true   |
   184      # indeed, the order the vAMM should never create is accepted, and gets executed.
   185      Then the following trades should be executed:
   186        | buyer    | price | size | seller | is amm |
   187        | vamm1-id | 160   | 2    | lp1    | true   |
   188      When the network moves ahead "1" blocks
   189  	Then the parties should have the following profit and loss:
   190        | party    | volume | unrealised pnl | realised pnl | is amm |
   191        | party1   | 1      | 60             | 0            |        |
   192        | party2   | -2     | -120           | 0            |        |
   193        | vamm1    | 3      | 180            | 0            |        |
   194        | vamm1-id | 1      | 0              | -120         | true   |
   195        | lp1      | -3     | 0              | 0            |        |
   196  
   197      # Now the vAMM has switched to long, so it should not trade with a sell order.
   198      When the parties place the following orders:
   199        | party  | market id | side | volume | price | resulting trades | type       | tif     | reference |
   200        | party2 | ETH/MAR22 | sell | 1      | 90    | 0                | TYPE_LIMIT | TIF_GTC | p2-s3     |
   201  
   202      # But it'll use the buy order to close its own position
   203      When the parties place the following orders:
   204        | party  | market id | side | volume | price | resulting trades | type       | tif     | reference |
   205        | party1 | ETH/MAR22 | buy  | 2      | 100   | 2                | TYPE_LIMIT | TIF_GTC | p1-b3     |
   206      Then the following trades should be executed:
   207        | buyer  | price | size | seller   | is amm |
   208        | party1 | 90    | 1    | party2   |        |
   209        | party1 | 99    | 1    | vamm1-id | true   |
   210  
   211      When the network moves ahead "1" blocks
   212  	Then the parties should have the following profit and loss:
   213        | party    | volume | unrealised pnl | realised pnl | is amm |
   214        | party1   | 3      | 8              | 0            |        |
   215        | party2   | -3     | -7             | 0            |        |
   216        | vamm1    | 3      | -3             | 0            |        |
   217        | vamm1-id | 0      | 0              | -181         | true   |
   218        | lp1      | -3     | 183            | 0            |        |
   219      # The AMM pool is indeed cancelled.
   220      And the AMM pool status should be:
   221        | party | market id | amount | status           | base | lower bound | upper bound | lower leverage | upper leverage |
   222        | vamm1 | ETH/MAR22 | 100000 | STATUS_CANCELLED | 100  | 85          | 150         | 4              | 4              |
   223  
   224      # Trying to place a vAMM order again results in a margin check failure (the accounts have been drained)
   225      When the parties place the following hacked orders:
   226        | party    | market id | side | volume | price | resulting trades | type        | tif     | reference | is amm | error               |
   227        | vamm1-id | ETH/MAR22 | buy  | 2      | 0     | 0                | TYPE_MARKET | TIF_FOK | vamm-d    | true   | margin check failed |