Withdrawing and escaping without the application’s approval (StarkEx Perpetual)

In order for a user to take control of their funds without the application’s approval, they need to first execute a forced withdrawal, which sometimes requires a forced trade to precede it, and then escape from the contract. The user initiates these operations on-chain.

A valid on-chain request activates a forced action request, but even if the corresponding off-chain transaction itself is invalid, the application nonetheless must serve the request, either fulfilling the request, or proving that the request is invalid.

Forced transactions are irreversible. Neither you nor the user can cancel a forced trade or forced withdrawal request.

StarkEx Perpetual Trading includes the following forced actions:

  • Forced withdrawal

  • Forced trade

    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 a forced withdrawal request can result in liquidation.

Withdrawing funds without the application’s approval

For complete information on functions, events, and contants mentioned in this topic, see the Forced operations reference.

Prerequisites
  • The private Stark key that matches the public Stark key of the relevant position.

  • A block explorer, such as Etherscan.

Executing a forced trade and forced withdrawal

Procedure
  1. This step is not necessary for StarkEx Perpetual Trading 1.0.

    Using a block explorer, such as Etherscan, the user calls the registerSender or registerEthAddress function.

  2. If the user must trade synthetic assets so that their position only holds collateral, they must find a party to trade with and agree on the terms of the trade.

    Both sides of the trade must be registered, so if the other party is not yet registered, they must also call the registerSender or registerEthAddress function.

  3. After agreeing on the terms of the trade, one party uses the block explorer to call the on-chain forcedTradeRequest function, which includes the signature of the second party.

    You must service the request within the amount of time defined by the constant FREEZE_GRACE_PERIOD. The default time period is seven days.

    After receiving the function call, the StarkEx smart contract emits the LogForcedTradeRequest event.

    If you serve the request, and the request is proven to be valid, the user can subsequently execute a forced withdrawal request. Skip the next step.

  4. If the freeze grace period passes and the forced operation is still in the pending forced operations area, the user calls the freezeRequest function.

    The exchange becomes frozen, and it can accept no further state updates.

    If you do not serve a forced action request within the freeze grace period, then any user, not just the user that submitted the request, can freeze the contract by calling the freezeRequest function with their public Stark key and position ID.

    The user now executes a forced withdrawal.

  5. Using a block explorer, such as Etherscan, the user calls the forcedWithdrawalRequest function.

    You must service the request within the amount of time defined by the constant FREEZE_GRACE_PERIOD.

    After receiving the function call, the StarkEx smart contract emits the LogForcedWithdrawalRequest event.

    If you serve the request, the user can subsequently withdraw their funds to an Ethereum vault. Skip the next step.

  6. After the freeze grace period passes, and the forced operation is still in the pending forced operations area, the user calls the freezeRequest function.

    The exchange becomes frozen, and it can accept no further state updates. Withdrawals of on-chain funds are still possible.

The user must now escape from the frozen smart contract.

Escaping from a frozen application smart contract

Once the application becomes frozen, the escape operation enables any user to withdraw their funds and leave the application.

Procedure
  1. The user obtains a Merkle path of a vault to be evicted with respect to the frozen vault tree root. Typically, once the application is frozen, such data should be made public or obtainable from an application API, depending on the application’s data availability approach.

  2. The user calls the verifyEscape function with the Merkle proof for the vault to be evicted.

    For information on the structure of the proof, see Escape verifier

    A valid proof results in the registration of the following fact:
    keccak256(starkKey, assetId, quantizedAmount, vaultRoot, height, vaultId).

  3. The user calls the escape function with the same parameters submitted to the Escape verifier.

    If a proof was accepted for the same parameters by the Escape verifier, and no prior escape call was made for the vault, the contract adds the vault balance to an on-chain pending withdrawals account under the public Stark key of the vault owner and the appropriate asset ID.

  4. The user withdraws this amount from the pending withdrawals account by calling the normal on-chain withdraw function to transfer the funds to their ETH or ERC-20 account, depending on the type of token.

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.

If you do not serve a forced action request within the freeze grace period, then any user, not just the user that submitted the request, can freeze the contract by calling the freezeRequest function with their public Stark key and position ID.

Additional resources