Deposit and Withdrawal
Deposit and withdraw funds to and from keystore accounts
Keystore accounts support deposit and withdrawal operations to transfer funds between Ethereum (L1) and the keystore rollup. Deposits move ETH from L1 to a keystore account, while withdrawals transfer funds from a keystore account back to L1.
Deposits
Deposit is the process of moving funds from L1 to a keystore account on the rollup, which is done by executing a DEPOSIT
transaction on the keystore. DEPOSIT
transaction are L1-initiated transactions. A transaction must be submitted to the rollup bridge on L1 using the initiateL1Transaction
function. The bridge performs validation to ensure sufficient funds are deposited.
L1-Initiated Transactions Format
L1-initiated transactions follow this structure defined in the keystore bridge contract:
Here, the fields are given by:
txType
is the transaction type. ForDEPOSIT
transactions, it isKeystoreTxType.DEPOSIT
.data
is the transaction data, serialized differently depending on the transaction type. ForDEPOSIT
transactions, it represents the keystore address.
Deposit transaction amount is determined by the L1-initiated transaction value.
Withdrawals
Withdrawal is the process of moving funds from keystore to L1, which is done by executing a WITHDRAW
transaction on the keystore. A WITHDRAW
transaction is serialized in the following format:
Here the fields are given by:
bool isL1Initiated
: Whether the transaction is L1-initiated.bytes l1InitiatedNonce
: Represents theuint256
L1-initiated nonce for the transaction if the transaction is L1-initiated and the empty bytestringbytes(0x)
otherwise.uint256 nonce
: The nonce for the transaction.bytes feePerGas
: Represents theuint256
fee per gas for the transaction if the transaction is not L1-initiated and the empty bytestringbytes(0x)
otherwise.address to
: The L1 Ethereum address to withdraw to.uint256 amt
: The amount of ETH in wei to withdraw.KeystoreAccount userAcct
: The user account paying for the transaction.bytes userProof
: The user’s ZK authentication proof for the transaction.
Then, the serialized transaction can be sent to the sequencer via the keystore_sendRawTransaction
RPC endpoint.
Once a withdrawal transaction is finalized on L1, it is possible to withdraw funds from the keystore bridge contract to the requested L1 Ethereum address, which is determined by the to
field of the withdrawal transaction. This process is called finalizing a withdrawal.
To finalize a withdrawal, call the finalizeWithdrawal
method on the keystore bridge contract, which is defined as:
Let say we want to finalize withdrawal transaction tx
. Assume tx
was included in block k
, and k
was committed in batch c
. Also assume c
is finalized on L1.
To finalize tx
(to withdraw funds from bridge contract) user needs to call finalizeWithdrawal
method on the contract with following arguments:
batchIndex
suchbatchIndex >= c
, such that there is a batchh
whereh.batchIndex = batchIndex
.preimage
must be aOutputRootPreImage
where:preimage.stateRoot = h.lastBlock.stateRoot
preimage.withdrawalsRoot = h.lastBlock.withdrawalsRoot
preimage.lastValidBlockhash = h.lastBlock.blockhash
keystoreAddress = t.userAcct.keystoreAddress
withdrawAmount = t.amt
nonce = t.nonce
to = t.to
proof
to be a Merkle Proof showing(withdrawalHash, withdrawal)
pair exists in the withdrawals state at blockh.lastBlock
, where:withdrawalHash = keccak256(abi.encodePacked(t.userAcct.keystoreAddress, t.nonce))
withdrawal = Withdrawal(t.to, t.amt)
isLeft
is auint256
that packs all theisLeft
booleans in the Merkle proof returned by the node JSONRPC server.
The Axiom SDK simplifies this process by providing a single method, buildFinalizeWithdrawalArgs
that prepares the required arguments for finalizeWithdrawal
.
Latency
The latency of deposits is mainly determined by the L1-initiated transaction inclusion time. This refers to the total time from the submission of an L1-initiated transaction to L1 until it is included in an L2 block. This timing depends on how closely the sequencer follows L1. In keystore, the sequencer lags behind L1 blocks by 10–30 blocks.
The latency of a withdrawal can be broken down into two parts:
- Proof generation time: the total time it takes for the signature prover to generate the ZK proof(s) for a transaction.
- Transaction finalization: the total time from the submission of a transaction to the sequencer until it is finalized on the L1 bridge.
Deposit and Withdrawals with the SDK
We provide a Typescript SDK for helping interacting with the keystore. You can find an example of a key rotation using this SDK here.