Settlement Facet (0.8.4)
Overview
In Symmio, users can use their unrealized profits to open new positions, effectively allowing their UPNL to back them up from being liquidated. While this provides greater flexibility and leverage for users, it introduces a potential issue during the closing of positions. When a position is closed, the losing party must pay the profit to the winning party from their allocated balances, i.e., realized PNL, not from UPNL.
Consider a scenario where a user has multiple positions:
Position A: Significant unrealized profit.
Position B: New position opened using the unrealized profit from Position A.
If Position B incurs a loss, the user may not have sufficient allocated balance to cover the loss when closing Position B, even though their overall UPNL is positive. This situation prevents the hedger (counterparty) from being able to fill the close request, as the required funds are not available in the user's allocated balance.
Previously, we mitigated this by warning users through the frontend that they couldn't close certain positions due to insufficient realized PNL, advising them to close profitable positions first. However, with the introduction of automated features like stop-loss and take-profit bots (e.g., in IntentX), this manual intervention is no longer feasible.
Additionally, users could exploit the force close option by quickly allocating more funds and forcing the close of their positions, potentially leading to losses for hedgers if they cannot react in time.
To resolve these issues, we've introduced the settleUpnl
method, which allows hedgers to settle a portion of the user's unrealized PNL, effectively converting it into realized PNL. This enables the hedger to fill the user's close requests, even when the user lacks sufficient allocated balance.
The settleUpnl
method functions similarly to our implementation for funding rates, where we updated the openedPrice
of quotes.
Detailed Example
Let's illustrate how the settleUpnl
method works with a detailed example.
Scenario
Bob (Party A) has three open positions and zero allocated balance:
Position 1 with Rasa Hedger (Party B1):
Unrealized Profit: $300
Quote ID:
1
Position 2 with PerpsHub Hedger (Party B2):
Unrealized Profit: $100
Quote ID:
2
Position 3 with PerpsHub Hedger (Party B2):
Unrealized Loss: $250
Quote ID:
3
Bob wants to close Position 3, which has an unrealized loss of $250. However, since Bob has zero allocated balance, he cannot cover this loss upon closing.
Problem
PerpsHub Hedger (Party B2) cannot fill Bob's close request for Position 3 because Bob doesn't have enough allocated balance to cover the $250 loss. Even though Bob has an overall positive UPNL ($150 net profit), his profits are unrealized and cannot be used to settle the loss directly.
Solution with settleUpnl
To enable the closing of Position 3, PerpsHub Hedger needs to settle Bob's unrealized profits from Positions 1 and 2, converting them into realized profits. This will increase Bob's allocated balance sufficiently to cover the loss.
PerpsHub only needs to settle enough unrealized profit to cover the $250 loss. They can achieve this by settling Position 2 and part of Position 1. Hedgers should prioritize settling UPNLs from their own positions with users, as they face a cooldown period when settling positions involving other hedgers.
PerpsHub initiates
settleUpnl
for Position1 and Position2:
This call will:
Update the opened prices for Position1 and Position2
Realize $150 profit for Position1 and $100 profit for Position2
Adjust Bob's allocated balance: +$150 +$100 = $250 increase
Adjust Rasa's and PerpsHub's allocated balances accordingly
After settlement, Bob's state:
Allocated balance: $250
Position2 has fully settled profit
Position1 has partially settled profit ($150 out of $300)
Position3 remains unchanged
PerpsHub can now successfully fill the close request for Position3, as Bob has sufficient allocated balance ($250) to cover the loss ($250).
Overview
The Settlement Facet allows Party B to finalize the settlement of UPnL for Party A’s positions. During settlement, the UPnL data is verified using a Muon signature and then processed to adjust the open prices for the affected quotes. The resulting changes update Party A’s allocated balance and yield new allocated balances for the involved Party Bs. This process ensures that the financial state of the positions reflects the latest market conditions.
settleUpnl
Description:
The settleUpnl
function allows Party B to settle the UPnL for a set of quotes associated with Party A. It processes settlement data provided in the SettlementSig
structure along with an array of updated prices. Once the settlement is completed, the function emits an event with the settlement details and the new allocated balances.
Function Signature:
Parameters:
settlementSig: A structure containing the settlement data. Its fields include:
reqId
: Request identifier.timestamp
: The timestamp when the settlement request was made.quotesSettlementsData
: An array ofQuoteSettlementData
structures that detail settlement data for each quote.upnlPartyBs
: An array of UPnL values for the Party Bs.upnlPartyA
: The UPnL value for Party A.gatewaySignature
: A Muon gateway signature.SettlementSig
: A structure with signature data including aSchnorrSign
.
updatedPrices: An array of new prices to be applied as the new openedPrice for the specified quotes. These should be fetched from the appropriate muon query. More information here
partyA: The address of Party A whose position settlement is being processed.
Example Usage:
Internal Processing:
The function:
Verifies the settlement signature via
LibMuonSettlement.verifySettlement
.Calls
LibSettlement.settleUpnl
to process the settlement and update balances.Returns an array of new allocated balances for Party Bs.
The function then emits the settlement event with the settlement details.
Settlement Event
Event Emitted:
Event Details:
settlementData: An array of
QuoteSettlementData
structures detailing the settlement for each quote.updatedPrices: The array of new prices applied to the quotes.
partyA: The address of Party A whose allocated balance is updated.
newPartyAAllocatedBalance: The new allocated balance for Party A after settlement.
newPartyBsAllocatedBalances: An array representing the new allocated balances for each of the Party Bs involved.
Last updated