Forced operations overview

forced operation

In order to guarantee self custody of funds, thereby preventing censorship, StarkEx enables a user to perform a forced request at any point in time. The user initiates a forced request with an onchain transaction. If the operator does not serve the request within a specified period of time, the user can freeze the contract, and thus the exchange. Once the exchange is frozen, any user can withdraw directly from the frozen contract.

Registration

StarkEx Perpetual Trading 2.0 and later

Before a user can enforce any forced operation, they must first register, by calling the registerEthAddress function in the StarkEx contract. This function is signed and receives three parameters: starkKey, ethereumAddress and starkSignature, where starkSignature is a signature on the given ethereumAddress using the user’s private Stark key.

For more information, see registerEthAddress.

StarkEx for Perpetual Trading v1.0

The registration function is invoked as a part of the user onboarding flow. For more information, see Registration (StarkEx Perpetual Trading v1.0)

Since offchain limit order and withdrawals require Stark key signatures, forced actions are also the recommended way for users that have lost their private Stark key to get their funds from the system.

Forced withdrawal and forced trade

StarkEx Perpetual Trading supports the following forced operations:

  • Forced withdrawal

  • Forced trade

Forced withdrawal

The forcedWithdrawalRequest function is an anti-censorship mechanism that enables a user to withdraw their funds without the application’s permission.

A potential attacker could attempt a denial of service (DoS) attack on the application with a flood of forced withdrawal requests. To limit the number of such requests, thereby preventing such an attack, the forcedWithdrawalRequest function provides a mechanism to protect against such an attack, while also enabling honest users access to their funds without charging them a premium: The premiumCost parameter.

When premiumCost is set to true, the transaction is guaranteed to be accepted, but the cost of the transaction is set to 1M gas.

When premiumCost is set to false, the cost is lower, but the StarkEx smart contract accepts only ten such forcedWithdrawalRequest transactions per block.

For information on regular withdrawals, see The withdrawal flow and Withdrawing funds from the StarkEx contract

Forced trade

Forced withdrawal can only withdraw collateral. When a user holds any synthetic assets and wants to withdraw the entire value of their position, they must first execute a forced trade to sell their synthetic assets in exchange for collateral.

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

  • The values of the public Stark keys for both traders match their Ethereum addresses.

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

  • \(\text{blockchain_time} / 3600 \leq \text{submission_expiration_time}\)

If these conditions are true, the request is moved to the application. The trade takes effect if the following conditions are true:

  • The position IDs and the public Stark keys, which are specified as parameters of the forcedTradeRequest function, correspond with each other.

  • The trade leaves both positions above the maintenance margin, or improves the ratio of value to maintenance margin.

If either of these conditions is not true, StarkEx processes the transaction, but proves the request to be invalid and does not execute the trade. This satisfies the forced operation mechanism to show that the application served the request.

The second position in a forced trade can belong to the same user.

Forced trade has no fee other than a normal gas fee, but the gas fee that the submitter pays is much higher than the offchain trade fees.

Example: Forced trade and forced withdrawal

Alice wants to withdraw all of her funds.

  • She has a position with +1 BTC and 0 USDC.

  • The price of 1 BTC is 20,000 USDC.

She must first register before she can enforce any forced operation, using the registerEthAddress function in the StarkEx contract. (Not necessary for StarkEx Perpetual Trading 1.0.)

Alice wants to submit an onchain forced withdrawal request. However, she can only withdraw collateral. Because of the risk factor of the synthetic asset, she can only withdraw 19,300 USDC, not the entire amount, 20,000 USDC. Otherwise, StarkEx invalidates her transaction, since it would cause her position to fall below the maintenance margin. In order to get the entire amount, she must own only collateral.

So she submits a forced trade request to sell her BTC for USDC.

After the forced trade is fulfilled Alice can execute a forced withdrawal request to obtain all her funds.

Frozen contracts and escaping: When the operator withholds funds

The ability to freeze the operator’s contract protects users from an unscrupulous operator.

When a user submits a forced action, the operator must serve the forced action within a time period defined by the FREEZE_GRACE_PERIOD constant. After this time period, any user, not only the one that submitted the forced action, can freeze the operator’s contract, thereby essentially shutting down the operator’s application. Subsequently, any user can escape from the contract without the operator’s consent.

When a contract is already frozen, any user can access their funds without performing a forced operation. Any user can execute a normal onchain withdrawal, without first executing a forced trade, and StarkEx converts all synthetic assets the user holds to collateral, using the last oracle price tick as the basis for the conversion. The withdrawal then transfers their funds from the operator’s contract to the user’s Ethereum account.

Example: Freezing a contract

In the previous example, Alice submitted a valid forced trade request, and a valid forced withdrawal request, and the operator served both transactions.

Suppose that the operator did not serve either of these forced actions within the time specified by the FREEZE_GRACE_PERIOD constant.

The first step that Alice needs to perform in order to gain access to her funds by is calling the freezeRequest function. After she calls this function, the exchange becomes frozen, and it can accept no further state updates. Withdrawals of onchain funds are still possible.

Example: Escaping from a frozen contract

Although Alice can only withdraw collateral, as in Example: Forced trade and forced withdrawal, the contract is frozen, so she does not need to first submit a forced trade or a forced withdrawal request.

The last oracle price tick before the contract was frozen set the price of 1 BTC at 20,000, so she submits a normal onchain withdrawal request for 20,000 USDC. StarkEx serves the request within the same amount of time it does for any normal withdrawal request.

Forced operation flows

There are two possible flows, based on how the operator responds to the forced operation request:

The operator serves the forced operation

  1. The user sends the forced operation to the contract on L1.

  2. The operator sends the forced operation to StarkEx.

  3. StarkEx validates the onchain request, based on the identity of the exact request and the business logic involved.

Example: Serving the forced operation

  1. Alice sends an onchain forced withdrawal request to withdraw 1,000 USDC from a specific offchain position that she claims to own.

  2. The operator sends the forced operation to StarkEx.

    The operator determines the order in which it processes transactions, and can place the forced operation anywhere in the transaction queue as long as they process it within the grace period.

  3. StarkEx determines if the forced operation is valid.

    Valid request

    1,000 USDC is deducted from Alice’s offchain balance, and registered onchain as belonging to Alice.

    Invalid request

    If either of the following is true, StarkEx proves the request is not valid, and does not move any funds onchain:

    • Alice has less than 1,000 USDC.

    • Alice’s public Stark key does not match the public Stark key registered with the position .

    After the proof for this request is submitted, whether the request is valid or invalid, the request is removed from the pending forced operations area in the StarkEx contract. If the request is invalid, the operator does not need to serve the request, and Alice cannot freeze the contract. If Alice wants to try again, she must submit a new request.

The operator does not serve the forced operation

  1. The user sends the forced operation to the contract.

  2. The operator does not send the forced operation to StarkEx.

When the freeze grace period has passed and the forced operation is still in the pending forced operations area, any user can call the freezeRequest function, with the public Stark key and the position ID they used in the ignored forced operation.

As a result, the exchange becomes frozen, and it can accept no further state updates. Withdrawals of onchain funds are still possible.

When a contract is already frozen, any user can access their funds without performing a forced operation. Any user can execute a normal onchain withdrawal, without first executing a forced trade, and StarkEx converts all synthetic assets the user holds to collateral, using the last oracle price tick as the basis for the conversion. The withdrawal then transfers their funds from the operator’s contract to the user’s Ethereum account.