Trader Interactions
Last updated
Last updated
There are 4 possible trader actions on the protocol:
Opening a position
Extending a position (increasing the size of the position)
Reducing a position (decreasing the size of the position)
Closing a position
These 4 sequences of action are the same whether a position is LONG or SHORT.
Anyone with a allowlisted collateral token (e.g. USDC) can open a trading position in one of the perpetual markets with a call to the contract.
Example A.1: Alice opens a LONG position in the ETHUSD trading pair. We assume a market price of 1000 ETHUSD.
Alice deposits 1000 USDC (with the ). 1000 USDC is deposited in Alice's vault (for this trading pair) and will be used as her collateral.
Alice opens a 5x leveraged long position (with ). Her notional amount is 5000 USDC (1000 x 5).
Increment mints 5000 vUSD and swaps this amount for 5 vETH. Increment registers 5000 vUSD debt and 5 vETH assets for the user position. Her position is registered as positionSize = 5 vETH and openNotional = -5000 vUSD.
The trading fee is charged on the notional amount of the trade. At the time of writing the trading fee is assumed to be 0.1% of the openNotional
. The amount is charged to the vault.
The system checks that the magnitude of the swap in the ETHUSD trading pair must not exceed the maximum trade size per block. Otherwise, the transaction is cancelled. This mechanism helps mitigate the risk of flash loans manipulating the system.
Insurance fee is taken from Alice's vault. At the time of writing, this value is 0.1% of the openNotional
.
The system checks that Alice's margin requirement is fulfilled. For a newly opened position, this means checking that the collateral is within the margin ratio requirement. The marginRatio
is required to be at least 8%, and with a collateral of 1000 USDC, Alice's position is valid until openNotional
surpasses an absolute value of -12500 USDC. The margin ratio of the position is derived from the value of the collateral, the value of its fundingPayments, and the profit/loss of the position at the close (i.e. price at position close - initial price). In summary, her notional amount of 5000 USDC passes the margin requirement test with a marginRatio
of 20%. More details about margin .
Increment stores the current fundingRate
for the user, which is the current funding rate on the market. This info will be used later on to determine the fundingPayments
when closing (or reducing) the position, or when extending a position.
Example B.1: Bob opens a SHORT position in the ETHUSD trading pair, assuming a market price of 1000 ETHUSD.
Bob opens a 5x leveraged short position (with extendPosition
in ClearingHouse). His notional amount is 5000 USDC (1000 x 5).
Increment mints 5 vETH, and swaps them for 5000 vUSD. We register 5 vETH debt and 5000 vUSD assets for Bob position. His position is registered as positionSize = -5 vETH and openNotional = 5000 vUSD.
The trading fee is charged on the notional amount of the trade. At the time of writing the trading fee is assumed to be 0.1% of the openNotional
.
The system checks that the magnitude of the swap in the ETHUSD trading pair must not exceed the maximum trade size per block. Otherwise, the transaction is cancelled. This mechanism helps mitigate the risk of flash loans manipulating the system.
Insurance fee is taken from Bob's vault. At the time of writing, this value is 0.1% of the openNotional
.
The system checks that Bob's margin requirement is fulfilled. For a newly opened position, this means checking that the collateral is within the margin ratio requirement. The marginRatio
is required to be at least 8%, and with a collateral of 1000 USDC, Bob's position is valid until openNotional
surpasses an absolute value of -12500 USDC. In other words, her notional amount of 5000 USDC passes the margin requirement test with a marginRatio
of 20%.
Increment stores the current fundingRate
for the user, which is the current funding rate on the market. This info will be used later on to determine the fundingPayments
when closing (or reducing) the position, or when extending a position.
When extending an existing position, traders may or may not deposit more collateral. If they don't deposit more collateral, their existing collateral will be used to determine if the margin requirement is met. If the margin requirement is not met with the new extended position, the collateral won't be accepted and the position will stay as it is.
Example A.2: Continuing from Example A.1 above, Alice extends her LONG position in the ETHUSD trading pair with no extra collateral, essentially changing the leverage only.
Alice calls extendPosition
to make her existing LONG position of openNotional = -5000 vUSD and positionSize = 5 vETH larger (see Example A.1 above for the details of this position). She chooses not to provide additional collateral and she wants to double the notional size of her position. So she calls extendPosition
with an amount
of 5000e18 (remember amounts are in 18 decimals).
Assuming the market price hasn't changed since Alice opened her position, Increment mints an extra 5000 vUSD and swaps them for 5 vETH. The system adds 5000 vUSD debt and 5 vETH assets to Alice position. Her trader position is now positionSize = 10 vETH and openNotional = -10,000 vUSD.
The trading fee is charged on the notional amount of the trade. At the time of writing the trading fee is assumed to be 0.1% of the openNotional
.
The system checks that the magnitude of the swap in the ETHUSD trading pair must not exceed the maximum trade size per block. Otherwise, the transaction is cancelled. This mechanism helps mitigate the risk of flash loans manipulating the system.
Alice is debited from the funding payments on her previous trader position. In this case, Alice's funding rate will be computed based on the value of her previous position (positionSize of 5 vETH) and the funding rate stored at the time. The cost of the funding payments is reflected in Alice's collateral in the vault.
0.1% of Alice's added collateral is debited to the insurance reserve on the amount added to her position. In this case, it's on the 5000 extra notional amount, not the total value of 10,000 because she already paid an insurance fee for the first 5000.
The system checks that Alice's margin requirement is fulfilled. With the margin ratio of 8% and collateral of 1000, Alice position is still valid (particularly in this hypothetical scenario, the market hasn't moved an inch in the meantime).
Increment stores the new fundingRate
for the user, which is the current funding rate on the market. This info will be used later on to determine the profit when closing (or reducing) the position, and when further extending a position.
Example A.3: Continuing from Example A.2 above, Alice wants to reduce her LONG position by half (current openNotional = -10,000 vUSD and positionSize = 10 vETH).
Alice passes the reduction ratio as well as the proposedAmount
in vETH which she wishes to sell from her positionSize
asset. In this case, she simply wants to scale back her position by half from 10,000 to 5000 notional. So reductionRatio
is 0.5 (or 5e17) and she passes a proposedAmount
of 5. Computing proposedAmount
is straightforward for LONG positions.
The system checks that the proposedAmount
isn't larger than the existing positionSize
, which is indeed the case (4300 <= 8600).
Increment mints 5 vETH and swaps them for 6000 vUSD, assuming the price of vETH has increased by 20% in the meantime.
The trading fee is charged on the notional amount of the trade. At the time of writing the trading fee is assumed to be 0.1% of the openNotional
. In our case that would be 6000 * 0.1% = 6.
Increment computes the funding payments that Alice should pay or receive on the position size that she is selling. It's done using the funding rate that she got from the market at the time she last extended her position and using the current market funding rate and the size of the positionSize she is reducing. Let's say that would be -500.
The profit is calculated from 1) the vUSD proceeds of the swap (+6000 because vUSD is equivalent to USDC in this market), 2) the funding payments (-500), 3) trading fees (-6) and 4) 50% of the notional value of her position (i.e. here -5000). In this case, her profit would be 494 (6000 - 500 - 5000 - 6).
The system checks that the magnitude of the swap (step 3) in the ETHUSD trading pair must not exceed the maximum trade size per block. Otherwise, the transaction is cancelled. This mechanism helps mitigate the risk of flash loans manipulating the system.
The system adjusts Alice's position. positionSize moves from 10 to 5. openNotional moves from -10,000 to -4000. Note: the position isn't closed because Alice's positionSize is not 0.
Increment settles the 494 USDC profit (or technically in UA, but UA is 1-to-1 for USDC in this case) in Alice's vault, whereby increasing her balance from 1000 to 1494 (a sweet move for Alice!).
Example B.2: Continuing from Example B.1 above, Bob wants to reduce his SHORT position by 30% (current openNotional = 5000 vUSD and positionSize = -5 vETH).
The system checks that the proposedAmount
isn't deviating more than 50% of the average market price in the past 15min (to avoid exploit).
Increment mints 2000 vUSD and swaps them for 1.5 vETH (we assume here that 2000 vUSD is the right amount to buy back 30% of the positionSize).
The trading fee is charged on the notional amount of the trade. At the time of writing the trading fee is assumed to be 0.1% of the openNotional
. That is 0.1% * 2000 = 2.
Increment computes the funding payments that Bob should pay or receive on the position size he's selling. It's done using the funding rate he got from the market at the time of opening his position, the current market funding rate, and the size of the positionSize he's buying back. In this case, let's say the funding rate is +300.
The profit is calculated from 1) the vUSD proceeds of the swap (-2000 vUSD), 2) the funding payments (+300) 3) the trading fees (-2) and 4) 30% of the notional value of his position (i.e. here +1500). In this case, his profit would be -202, which means he made a loss.
The system checks that the magnitude of the swap in the ETHUSD trading pair must not exceed the maximum trade size per block. Otherwise, the transaction is cancelled.
Increment adjusts Bob's position. positionSize moves from 5 to 3.5 and openNotional moves from -5000 to -3000. Note that the position isn't closed yet because the absolute value of Bob's positionSize is still greater than 0.
Increment settles the -202 profit in Bob's vault, whereby decreasing it from 1000 to 798 USDC.
It's important to note that closing a position is just a special case of reducing a position where the position is reduced by 100% of its previous value, thus the user flow is the same as chart above. When doing so, the trader position is closed for the trading pair considered.
Example A.4: Continuing from the Example A.3 above, Alice closes her LONG position in the ETHUSD trading pair (current openNotional = -4000 and positionSize = 5).
Alice wants to cash out from her entire position. So reductionRatio
is 100% (or 1e18) and proposedAmount
is 5 (i.e. all the positionSize).
The system checks that the proposedAmount
isn't larger than the existing positionSize, which is indeed the case (5 <= 5).
Increment mints 5 vETH and swaps them for 4900 vUSD, according to a new market price where vETH appreciated again.
The trading fee is charged on the notional amount of the trade. At the time of writing the trading fee is assumed to be 0.1% of the openNotional
. That is 0.1% * 4000 = 4.9 ~= -5.
Increment computes the funding payments, let's assume that it is -100.
The profit is calculated from 1) the vUSD proceeds of the swap (+4900), 2) the funding payments (-100), 3) the trading fees (-5) and 4) 100% of the notional value of her position (-4000). In this case, her profit would be 795.
The system checks that the magnitude of the swap in the ETHUSD trading pair must not exceed the maximum trade size per block. Otherwise, the transaction is cancelled.
Increment adjusts Alice's position. In this case, openSize
changes to 0 which automatically closes Alice's position in this market.
Increment settles the 795 profit in Alice's vault, whereby increasing it from 1500 to 2295 USDC.
Example B.3: Bob closes his SHORT position in the ETHUSD trading pair (continues from Example B.2 where openNotional = 3000 and positionSize = -3.5).
Bob wants to close his position. So reductionRatio
is 100% (or 1e18). The passing value for proposedAmount
is still a bit more tricky to find. One way is to call getExpectedVBaseAmount
until Bob gets an amount equal to or slightly bigger than 100% of his short position (i.e. the absolute value of positionSize
). We assume that buying back 100% of the 3.5 vETH debt costs Bob 3500 vUSD.
The system checks that the proposedAmount
isn't deviating more than 50% of the average market price in the past 15min (to avoid exploit).
Increment mints 3500 vUSD and swaps them for 3.5 vETH, if the proposedAmount
in vUSD wasn't large enough Bob would be left with some of his SHORT position (even if reductionRatio
was 100%).
The trading fee is charged on the notional amount of the trade. At the time of writing the trading fee is is 0.1% of the openNotional
. That is 0.1% * 3500 = 3.5.
Increment computes the funding payments, let's assume that it is 301.
The profit is calculated from 1) the vUSD proceeds of the swap (-3500), 2) the funding payments (+301), the trading fees (-3.5) and 4) 100% of the notional value of his position (+3000). In this case, his loss would be 202.5.
The system checks that the magnitude of the swap in the ETHUSD trading pair must not exceed the maximum trade size per block. Otherwise, the transaction is cancelled.
Increment adjusts Bob's position. His positionSize is now 0, which automatically closes his position on this trading pair market.
Increment settles the 202.5 loss in Bob's vault, whereby increasing it from 798 to 595.5 USDC.
Bob deposits 1000 USDC (with the ). 1000 USDC is deposited in Bob's vault balance and will be used as his collateral.
To extend a position, traders need to call the same function as to open the position which is the contract.
Traders can reduce their existing positions by calling the contract with the correct parameters.
If Alice had provided a collateral different than USDC, her profit would still have been accounted for in UA. For example, if she had provided 1000 DAI earlier (instead of 1000 USDC), she would have ended with her 1000 DAI collateral as well as a positive balance of 494 UA. For more details on the main accounting token of the protocol, see
Bob passes the reduction ratio as well as the proposedAmount
in vUSD which represents the amount of vUSD needed to buy back 30% of the vETH debt that he owes (SHORT position means he has debt in vETH to the protocol). In this case, he wants to scale down his position by 30% from 5000 notional to 3500, so reductionRatio
is 0.3 (3e17). To find the value for passing proposedAmount
is a bit more trickier for SHORT positions than LONG positions. One way for Bob to approximate this value is to call getExpectedVBaseAmount
until he gets an amount equal or slightly larger than 30% of his short position (the absolute value of positionSize)
See for an in-depth explanation.
In the case of this example, assuming that the price of vETH increased in the market, Bob buys back 30% of the vETH debt (which is equal to 1.5 vETH) and costs about 2000 vUSD (instead of the 1500 vUSD if the market remained like it was when Bob opened the position).
As such, traders should call the same function as to reduce their positions on the market, i.e. the contract with the correct parameters.
Traders with an open position wanting to move to the opposite position (e.g. from a SHORT position to a LONG position, and vice-versa) can do so in one go with the function.