StarkGate architecture
This page is a deep-dive into Starknet’s different components. To learn how to use StarkGate, go to Guides. |
Introduction
StarkGate, developed by StarkWare, bridges ETH and ERC-20 tokens between Ethereum and Starknet. The following is an illustration of its overall architecture:

As illustrated, while StarkGate is referred to as a single bridge, some legacy tokens have their own bridge, each of which is defined in a corresponding pair of L1 and L2 contracts. Moreover, StarkGate also includes additional L1 components, used for administrative purposes. To best understand the interplay between the different components, it’s recommended to follow the lifecycles of a deposit and withdrawal.
Legacy bridges
Prior to StarkGate 2.0 (Mainnet: January 2024) tokens were bridged with a unique, custom pair of L1 and L2 bridge contracts, where the L1 contract is an instance of LegacyBridge.sol
and the L2 contract is an instance of legacy_bridge_eic.cairo
. These legacy token bridges are supported by StarkGate 2.0 in a fully backward-compatible fashion, as illustrated in the following example.
Example: USDC
For the complete list of legacy bridges, see the |
Consider the deposit
functions for the L1 bridge contract for USDC on Etherscan: 0xf6080d9fbeebcd44d89affbfd42f098cbff92816#writeProxyContract
This contract has the following two deposit
functions: deposit (0x0efe6a8b)
and deposit (0xe2bbb158)
, which shows that the bridge includes support for the legacy functionality as well as the modern functionality:
deposit (0x0efe6a8b)
|
The multi-bridge contract, which includes support for all tokens within a single contract, requiring that you enter the address of the token in the deposit function. |
deposit (0xe2bbb158)
|
The legacy contract, which is labeled Support Legacy ABI. This function does not include the |
L1 components
Contract | Description |
---|---|
Responsible for adding tokens to the multi-bridge. An interface is available through |
|
Contains the addresses of all supported bridges and tokens and enables to stop servicing an existing bridge. An interface is available through |
|
The primary StarkGate bridge contract, where the main user bridge functionality are defined. |
|
An interface to check if a contract is servicing a token. |
Lifecycles
Deposit lifecycle
Step 1: Initiating a deposit on L1
-
A call to the L1
deposit
function initiates a deposit. -
The function does the following:
-
Transfers the funds from the user’s account to the Starknet bridge.
-
Emits a
Deposit
event that includes the L1 and L2 addresses of the user, and the amount deposited. -
Sends a message to the corresponding L2 bridge with the amount deposited, and the recipient’s address.
Starknet’s sequencer is now aware of the deposit transaction.
-
-
The sequencer waits for enough L1 block confirmations to fill its quota to run before the corresponding deposit transaction is initiated on L2. During this period of time, the status of the L2 deposit transaction is
NOT_RECEIVED
.
Step 2: Triggering a deposit on L2
-
The sequencers refer to the deposit request by triggering the L1 handler using the
handle_deposit
function on the L2 bridge. -
The
handle_deposit
function verifies that the deposit indeed came from the corresponding L1 bridge. It then calls the relevant token’s contract on Starknet and mints the specified amount of the token on L2 for the user. -
The sequencers complete constructing the block.
The status of the deposit request is now ACCEPTED_ON_L2
.
Step 3: Proving the block that includes the deposit
-
Starknet’s provers prove the validity of the block and submit a state update to L1.
-
The message confirming transfer of the funds is cleared from the Starknet Core Contract, and the fact that the user has transferred their funds is part of the now finalized state of Starknet.
If the message wasn’t on L1 to begin with, that is, if the deposit request was fraudulently created on Starknet, the state update fails. |
Withdrawal lifecycle
Step 1: Initiating a withdrawal on L2
-
A call to the L2
initiate_token_withdraw
function initiates a withdrawal. -
The function does the following:
-
Burns the transferred amount of tokens from the balance of the withdrawal’s initiator.
-
Sends a message to the relevant L1 bridge with the amount to be transferred and the recipient’s address.
-
Step 2: Proving the block that includes the withdrawal
-
The sequencer completes the block construction
-
Starknet’s provers prove the validity of the block and submit a state update to L1.
-
The message from the previous step is stored in the Starknet Core Contract.
Step 3: Transferring the funds on L1
After the withdrawal message has been recorded on the Starknet Core Contract, anyone can finalize the transfer on L1 from the bridge back to the user, by calling the withdraw
function.
This step is permissionless, anyone can do it. The recipient’s address is part of the recorded message on L1, so they receive the funds regardless of who calls the |
Withdrawal limit
By default, StarkGate imposes no limit on withdrawals. However, in order to mitigate risks associated with critical vulnerabilities that could result in the loss of user funds, StarkGate can enable a withdrawal limit.
If a serious security issue arises, the security agent in the StarkGate contract can limit withdrawals to 5% of the Total Value Locked (TVL) per day for any affected token by calling the setWithdrawLimitPCT()
function in the WithdrawalLimit.sol
contract. A dedicated team can then investigate and resolve the issue.
Only a security admin quorum can disable the withdrawal limit. The quorum will consist of Starknet Foundation members, Starknet ecosystem contributors, and StarkWare representatives. This diverse group will ensure that decisions reflect the Starknet community’s broad interests.
This approach, blending manual oversight with automated detection, aims to minimize potential losses.