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 in Forced actions and escape hatch. This section describes the specific parameters of Forced Withdrawal and Forced Trade requests.

StarkEx Perpetual Trading v1.0

Since off-chain limit orders and withdrawals require Stark key signatures, forced actions are also the recommended way for users who lost their private Stark key` to get their funds from the system.

Register (v2.0 only)

First Alice must register before enforcing any forced operation. Alice calls the register function in the StarkEx contract. This function is signed and gets three parameters: starkKey, ethereumAddress, and starksignature (on the Ethereum address).

Forced Withdrawal

When Alice wants to perform a forced withdrawal, she calls the forcedWithdrawalRequest function in the StarkEx contract. This function gets three parameters: starkKey ,vaultId and amount.

The request is treated by the off-chain application only if the starkKey parameter 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 public Stark key corresponds to the provided value for 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.

Forced Trade

In order to submit a forcedTradeRequest function, both sides of the trade must agree in advance on the terms of the trade.

(StarkEx Perpetual Trading v2.0) They must also be registered.

Both sides can be the same person, which is useful when recovering a private Stark key by moving funds from the old position with the lost key to a new position with a newly generated key.

Then, one of them submits an on-chain request that contains the signature of the second party. The request contains the following parameters:

  • starkKey and vaultId of both parties

  • collateralAssetId and amountCollateral to transfer

  • syntheticAssetId and 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 Forced Withdrawal for details.

Forced Trade is a fee-less operation, but the submitter of this request likely pays a much higher price for gas than the fees he might pay for an off-chain trade.

A Forced Trade request is considered valid at the smart contract level, and the request is recorded as an action item that the application must serve, only if the following conditions are true:

  • The values of starkKey for both traders match their Ethereum addresses

  • No request has been received with the same parameters, including the nonce

  • 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 values for vaultId correspond to the specified values for starkKey and the trade leaves both positions above the maintenance margin, or improve the ratio of value to maintenance margin.

If this is not the case StarkEx proves the invalidity of the request and does not execute the trade.