Deposit and withdrawal for off-chain accounts

Deposit

To deposit ETH, call the payable function deposit, which takes the amount through msg.value.

To deposit ERC-20, ERC-721, or ERC-1155 to StarkEx, use the following functions:

  1. approval on the ERC-20, ERC-721, or ERC-1155 contract, authorizing StarkEx to transfer funds on behalf of the user.

  2. deposit (ETH, ERC-20) or depositWithTokenId (ERC-721, ERC-1155) on the StarkEx contract, with the following parameters:

    • the user’s public Stark key

    • assetType

    • tokenId (ERC-721, ERC-1155)

    • the user’s vaultId

    • quantizedAmount and to send the deposit.

The result of the operation, assuming all requirements are met, is that the amount of ETH, ERC-20, ERC-721, or ERC-1155 tokens, specified in the deposit call and multiplied by the quantization factor, is transferred on behalf of the user to the contract.

In addition, the contract adds the funds to an accumulator of pending deposits for the provided public Stark key, assetType and vaultId. The public Stark key can belong to the user that called deposit or to a different user. When this happens, the event LogDeposit is emitted.

To inspect the funds in the Pending Deposits area, call getDepositBalance and getQuantizedDepositBalance. Both of these functions get starkKey, assetId and vaultId and return the pending amount of funds that correspond to the input parameters. These funds are pending deposit to the vault vaultId belonging to the user that owns the specified public Stark key. Be aware that if there are several pending deposits with the same parameters, these functions return the accumulated value.

In order to remove funds from the Pending Deposits area, the application needs to include the removal of funds in a proof, which results in the addition of the amount deposited to the specified vault. When the contract receives a valid proof, it deducts the transferred funds from the pending deposits for the specified starkKey, assetType and vaultId.

Until that point, the user can cancel the deposit by performing a time-locked cancel-deposit operation that consists of calls to the following functions:

  • depositCancel: Sets a timer. When the timer expires, the user can reclaim the deposit. Before the timer expires, the user cannot reclaim funds because the application might be processing the deposit to include in the off-chain vault. Only the recipient of the funds can call depositCancel. When this function completes, it emits the event LogDepositCancel.

  • depositReclaim: Transfers funds from the contract back to the on-chain user account. This transfer only succeeds if the timer set by depositCancel has expired. This operation results in a transfer of all pending funds, that is, funds not accounted for in proofs for off-chain inclusion, back to the user account on the ERC-20, ERC-721, or ERC-1155 contract, or on their ETH balance. When this function completes, it emits the event LogDepositCancelReclaimed.

The operator must monitor cancellation requests, either by checking the request state with the getCancellationRequest() function, or by monitoring cancellation request events.

The operator should never service a deposit for which a cancellation request event has been issued. Servicing such a request can cause a batch to fail, depending on the timing of the cancellation.

However, if the operator fails to implement this correctly, user funds are never at risk. Either a depositReclaim transaction fails, or an updateState transaction fails, resulting in an L2 rollback, and a request for an alternative transaction. Fast withdrawals are the sole responsibility of the operator and finality of fund balances are only valid for batches accepted on-chain.

For information on alternative transaction requests, see request for an alternative transaction

If according to the off-chain state, the vaultId and public Stark key specified in the deposit request do not match each other, this deposit is not valid and cannot be included in a proof. The funds remain in the deposit area. However, the funds can still be reclaimed to the address, ethereumAddress, that deposited them by using depositCancel and depositReclaim. The user that owns the public Stark key in the original deposit function call must call these functions.

Register and deposit

The following functions are wrappers around registerUser and deposit. You can call these functions to add a user to StarkEx:

StarkEx for Perpetual Trading: These functions creates a mapping between the user’s public Stark key and the user’s ethereumAddress and deposits funds in the same transaction. StarkEx for Spot Trading: These functions are equivalent to deposit. These functions still exist for backwards-compatibility.

Withdrawing funds from the StarkEx contract

You can withdraw funds once they are in the on-chain contract. The following types of withdrawals relate to different asset types in the system:

  • ETH

  • ERC-20 tokens

  • ERC-721 tokens

  • ERC-1155 tokens

  • Assets that were minted off-chain

The procedures for withdrawing these asset types vary slightly.

Funds become available for an on-chain withdrawal

When a new state update is submitted on-chain, it may contain off-chain withdrawal transactions (see The withdrawal flow). This transaction results in an addition of the withdrawn amount to the on-chain pending withdrawals area, specifically under the vault owner’s public Stark key and the appropriate assetType. At the same time, this amount is also deducted from the off-chain vault.

When this happens, an event is emitted, with the following parameters: public Stark key, assetType and the (non-accumulative)quantizedAmount and unquantized amount as parameters. The event is of type LogWithdrawalAllowed or LogNftWithdrawalAllowed for ERC-20, ETH, ERC-721, and off-chain minted asset respectively.

After this step, the funds can be viewed with the function getWithdrawalBalance that gets the public Stark key and assetId as input. Note that the funds are still at the StarkEx contract.

On-chain calls to extract assets from the StarkEx contract

Anyone can send a transaction to withdraw funds to L1.

To withdraw to on-chain, use one of these functions:

The parameters for these functions are as follows:

  • ownerKey and assetType for all assets

  • tokenID for ERC-721/ERC-1155

  • mintingblob for assets minted off-chain.

ownerKey is either a public Stark key or an Ethereum address. If it is a public Stark key, it needs to be registered on the StarkEx contract. For information on registering the public Stark key, see

Registering a public Stark key is expensive. Unless you have a specific reason to register a starkKey, it is recommended to withdraw to an Ethereum address.

After a withdrawal takes place, one of the following events is emitted as a notification that a withdrawal has occurred:

  • For ERC-20/ETH withdrawal, the event LogWithdrawalPerformed is emitted, with the parameters of the relevant starkKey, the recipient Ethereum address, the assetType, quantizedAmount and unquantized amounts.

  • For ERC-721 withdrawal, the event LogNftWithdrawalPerformed is emitted, with the parameters of the relevant starkKey, the recipient Ethereum address, the assetId.

  • For off-chain minted assets, the event LogMintWithdrawalPerformed is emitted, with the parameters of the relevant starkKey, the recipient Ethereum address, the assetType, quantizedAmount , unquantized amounts and assetId

The result of the operation, assuming all requirements are met, is that an amount of assets in the pending withdrawal account, (times the quantization factor for ERC-20/ETH) , is transferred to the corresponding account of the recipient.

It is possible to perform multiple withdrawals from off-chain vaults, and withdraw the entire amount using only one withdraw call to the on-chain contract, as long as the withdrawals are of the same assetId/mintingBlob and starkKey or an Ethereum address.

A withdrawal request cannot be canceled. Once funds reach the pending withdrawals account on-chain, they cannot be moved back into an off-chain vault before completion of the withdrawal to the corresponding account of the user.

Assets that are already on-chain can still be reclaimed even when the contract is Frozen by calling the relevant withdraw function from the following: