Forced actions and escape hatch

Register (StarkEx Perpetual Trading v2.0)

Before calling any forced operation, the user must call the registration function in the StarkEx contract. This function is signed and gets three parameters: starkKey, ethereumAddress, and starksignature (on that Ethereum address)

Forced Withdrawal

The function forcedWithdrawalRequest is a part of an anti-censorship mechanism that allows the user to withdraw funds.

The user supplies positionId and the starkKey, as well as the quantizedAmount he wishes to withdraw, and a boolean called premiumCost. Only the user to whom this starkKey belongs can submit this request. When this function is called, the event LogForceWithdrawalRequest (with the relevant starkKey, positionId) is emitted.

The role of the parameter premiumCost is to prevent DoS attack performed through StarkEx Forced Withdrawal mechanism by setting a high cost to perform this operation. On the other hand, we do not wish to set a high cost for an honest usage of this mechanism. Hence, StarkEx smart contract will accept only 10 transactions per block with premiumCost set to False. If a user sends a Forced Withdrawal transaction with premiumCost set to true, it is guaranteed that the transaction will be accepted, but then the gas cost of the transaction is set to 1M.

If the application fails to service the request (does not submit a proof attesting the invalidity of the request or the execution of it), upon the expiration of a FREEZE_GRACE_PERIOD, the user is entitled to freeze the contract by calling freezeRequest. (See Forced operations for the entire flow, and Forced Withdrawal and Forced Trade for the conditions under which the forcedWithdrawal request is valid). The user supplies the positionId, the starkKey and the quantizedAmount, and indicating the positionId for which the forced withdrawal request has not been serviced. Once the contract is frozen, funds can be extracted using the escape operation, fully described in Escapes.

A user cannot cancel Forced Withdrawal requests.

Forced Trade

In order to allow users to close their positions prior to submitting Forced Withdrawal requests, the user can call the forcedTradeRequest function in order to trade with another position. Potentially, this other vault might also belong to the same user, which can be useful for recovering a key. See Forced operations for a discussion of the general flow, and Forced Trade for the full details on the parameters, as well as on-chain validity checks performed on them.

If the application fails to service the request (or prove its invalidity), upon the expiration of a FREEZE_GRACE_PERIOD, the user is entitled to freeze the contract by calling freezeRequest, supplying the parameters for the original request, other than submissionExpirationTime, nonce, signature, and premiumCost, for which the Forced Trade request has not been serviced. Once the contract is frozen, funds can be extracted using the escape operation, fully described in Escapes.

Both sides of the trade must be registered.


Once the application becomes frozen the escape operation is what allows users to withdraw their funds and leave the application.

Any escaper entity or user may perform an escape operation as follows:

Step 1: Escapers must obtain a Merkle path of a vault to be evicted with respect to the frozen vault tree root. StarkEx for perpetual uses ZK-Rollups to provide on-chain data availability. Therefore, the data to generate a Merkle path is available through the calldata submitted on-chain along with the proof.

An open-source python script that generates these MerklePaths from the on-chain data will be published by StarkWare soon.

Step 2: Escapers call verifyEscape function on the EscapeVerifier contract with the Merkle proof for the vault to be evicted. See Escape Verifier for more details on the proof structure. If the proof is valid, this results in the registration of the following fact - keccak256(starkKey, quantizedAmount, balanceTreeRoot, positionId), when starkKey is the public key of the user, balanceTreeRoot is the last root of the balanceTreesaved on-chain, and quantizedAmount represents the amount of USDC the user is allowed to withdraw, according to the prices of all the synthetic assets in the last approved batch, as well as the position state.

Step 3: Escapers call escape function with the same parameters as submitted to the EscapeVerifier (starkKey, quantizedAmount, positionId). If a proof was accepted for the same parameters by the EscapeVerifier, and no prior escape call was made for the position, the contract adds the position balance to an on-chain pending withdrawals account under the starkKey of the position owner (from the collateral asset).

Step 4: The owner of the position can then withdraw this amount from the pending withdrawals account by calling the normal withdraw function (see Withdrawal) to transfer the funds to the user’s ETH or ERC-20 account (depending on the token type).

Note that while anyone can perform the initial steps of the escape operation (including the application, for example), only the position owner can perform the final step of transferring the funds.