Learn how to withdraw assets from your Arc application.

The withdraw operation allows users to withdraw assets from the Arc platform to the Ethereum Layer 1. The action can be executed via a simple API call with support for all types of assets available in the platform. Mintable tokens that were minted directly into Arc will be converted to their Layer 1 representation at the time of withdrawal.

The Arc Bridge, scheduled to be released as part of the public testnet, will allow for withdrawals to any EVM compatible chain (eg. Arbitrum, BNB Chain, Polygon).

There are two types of withdrawals: Regular Withdrawals and Fast Withdrawals.

Register Ethereum address

In order to withdraw Arc assets into the Ethereum L1 users must first bind their public STARK key to an Ethereum address, via a smart contract call to the registerEthAddress function.

/// @notice Binds an Ethereum address to a public STARK key.
/// @param ethKey The Ethereum address to register.
/// @param starkKey The corresponding STARK key.
/// @param starkSignature The user authentication signature.
function registerEthAddress(
    address ethKey,
    uint256 starkKey,
    bytes calldata starkSignature
) external;

This call requires the user to compute a STARK signature, using the user's public STARK key, in order to ensure that it is coupled with the correct Ethereum address. The message to be signed can be computed as follows:

keccak256(abi.encodePacked("UserRegistration:",ethKey,starkKey))keccak256(abi.encodePacked("UserRegistration:", ethKey, starkKey))

The STARK signature, over the previous message, can be calculated by:

// init arc client
const arcClient: Client = await ClientFactory.createCustomClient(
      { url: DefaultProviderUrls.TESTNET } as IProvider,
// withdraw asset
const withdrawData: WithdrawModel = {
  vaultId: '6554d7c3-364e-4536-9cd7-bb0ce8f7c600',
  amount: '65350000',

const withdraw: ResponseData<WithdrawDetailsDto> = await arcClient
// init cryptoUtils
const cryptoUtils: ICryptoUtils = new CryptoUtils();
await cryptoUtils.init(message);

// onchain withdraw
await cryptoUtils.withdraws().withdrawOnChain(withdraw.result);

Regular Withdrawals

Regular withdrawals do not use a liquidity provider to accelerate the withdrawal process, and hence must wait for a Arc batch to be included on-chain before they are processed. Arc batches are settled on Layer 1 approximately once every 10 hours, although this could be more or less frequent (up to 20 hours) depending on network conditions.

A user initiates a regular withdrawal by sending a request to the Arc API:

Once the Arc batch containing the withdrawal is settled, the amount to be withdrawn is transferred to the Ethereum Layer 1 pending withdrawals account of the user. In order to claim these funds, the user must perform a call to the withdraw contract, by sending an Ethereum transaction claiming the funds.

It is possible that for multiple withdrawal calls to the API, a single withdrawal call to the contract may retrieve all funds, as long as they are all for the same asset ID.

The Ethereum function to call, in order to complete the withdrawal, depends on the withdrawn asset type:

// ETH and ERC-20 assets.
function withdraw(uint256 ownerKey, uint256 assetType) external;

Only a user holding the Ethereum key corresponding to the STARK key of a pending withdrawals account may perform this operation.

Fast Withdrawals

Fast withdrawals use a withdrawal liquidity provider to deliver funds instantly, removing the requirement for customers to wait for a Arc batch to be settled on Ethereum. Users don't need to send any transactions in order to conduct a quick withdrawal. Behind the scenes, the withdrawal liquidity provider will transmit an Ethereum transaction, which will be mined and subsequently credited to the user. To compensate operational costs and gas prices, consumers must pay a premium fee to the liquidity provider for processing fast withdrawals.

Fast withdrawals will be available in Q2 2023.

Last updated