Perpetual Trading - Forced Withdrawal and Forced Trade
For perpetual trading applications, there are two forced actions: Forced Withdrawal and Forced Trade.
We show an example scenario to explain why these two forced operations are required to guarantee self-custody of funds.
Alice has a position with +1 BTC and 0 USDC and BTC price is 20,000 USDC. Alice wants to withdraw all of her funds. She can submit an on-chain Forced Withdrawal request. However, due to the risk factor of the synthetic asset, she can only withdraw 19,300 USDC and not the entire amount (20,000 USDC). Otherwise, her position would fall below the maintenance margin. In order to get the entire amount, she must own only collateral. To achieve that, she can use Forced Trade operation and sell her BTC for USDC.
The general flow of a forced request is described here. This section describes the specific parameters of Forced Withdrawal and Forced Trade requests.
Since off-chain limit order and withdrawals require
When Alice wants to perform Forced Withdrawal, she calls the
fullWithdrawalRequestfunction in the StarkEx contract. This function gets three parameters:
The request is treated by the off-chain application only if the
starkKeyparameter is associated with the Ethereum address that initiated the transaction. Otherwise, the request is rejected by the StarkEx smart contract.
Off-chain, the request is valid only if the provided
starkKey corresponds to the provided
vaultId, and the supplied amount of funds can indeed be withdrawn without falling below the maintenance margin.
It is recommended to first close a position with Forced Trade and only then to use Forced Withdrawal when there is only collateral left in the vault. Otherwise, careless Forced Withdrawal requests can lead to liquidation.
In order to submit Forced Trade, both sides of the trade must agree in advance on the trade.
"Both sides" may in real life, be the same person. This is useful in the case of key recovery (moving funds from the old vault with the lost starkKey to a new one with a newly generated starkKey)
Then, one of them submits an on-chain request that contains the signature of the second party. The request contains the following parameters:
vaultIdof both parties
amountSyntheticto transfer in return
a_is_buying_synthetic- a flag that indicates which of them is buying the synthetics
submission_expiration_timestamp- given in hours. This is to protect the non-submitter side from executing the trade in an arbitrary future time
nonce- used to protect the non-submitter side in the trade against replay attack
eth_signature- the non-submitter signature on all the parameters
premiumCost- a parameter that determines the gas-cost of the transaction. See forcedWithdrawal for details.
Forced Trade is a fee-less operation, but note that the submitter of this request would probably pay a much higher price for gas than the fees he would be paying for an off-chain trade.
A Forced Trade request is considered valid at the smart contract level (i.e. it is recorded as an action item that the application must serve), only if the
starkKey values of both traders match their Ethereum addresses, there has been no request with the same parameters (including the nonce) before, and
blockchain_time / 3600 <= submission_expiration_time .
If this is the case, the request is moved to the application. The trade takes effect if the specified
vaultId values correspond to the specified
starkKey values and the trade leaves both positions above the maintenance margin (or improve their value to maintenance margin ratio)
If this is not the case StarkEx will prove the invalidity of the request and would not execute the trade.