Overview
StarkGate, developed by StarkWare, bridges ETH and ERC-20 tokens between Ethereum and Starknet. Its various components enable anyone to easily deposit funds to Starknet (with and without a message attached), withdraw funds to Ethereum, and add a token to StarkGate.Following Maker DAO’s announcement, StarkWare launched a new set of DAI bridge and token contracts under StarkGate. This new DAI token retains the same contract ‘symbol’ and ‘name’ as the existing one, and to differentiate between the two, the old DAI is referred to as “DAI v0” while the new DAI is simply referred to as “DAI”.Withdrawal of DAI v0 tokens is still possible with no limitations, but depositing DAI v0 using the DAI v0 bridge is disabled. Users are strongly encouraged to migrate to the new DAI token, as it cannot support StarkGate’s latest features (such as Smart Deposits and Withdrawal Limits) and will stop being compatible with Starknet altogether over time.To migrate from DAI v0 to DAI, either swap your DAI v0 for DAI using one of Starknet’s swap apps and aggregators or withdraw your current DAI v0 tokens to L1 using and re-deposit them using StarkGate (which automatically issues the new DAI).
Components
The following table details StarkGate’s key components:Contract | Description |
---|---|
Starknet Token Bridge(on both L1 and L2) | The primary StarkGate bridge contract, where the main user bridge functionality are defined. |
Starkgate Manager | Responsible for adding tokens to the multi-bridge. |
Starkgate Registry | Contains the addresses of all supported bridges and tokens and enables to stop servicing an existing bridge. An interface to the Starkgate Registry is available through IStarkgateRegistry.sol. |
Starkgate Service | An interface to check if a contract is servicing a token. |
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.
For example, the L1 bridge contract for USDC has the following two
For the complete list of legacy bridges, see the
deposit
functions: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 token (address) parameter, because the contract that contains this function only supports USDC. Therefore, the address of the token is superfluous. |
bridged_tokens
directory on GitHub.
Procedures
The following sections detail the procedures enabled by StarkGate, along with the instructions to perform them.For adding a token to Starknet, see Joel Mun’s blog. Note that enrolling a new bridge does not add it to StarkGate’s GUI.
estimateDepositFeeWei
or estimateEnrollmentFeeWei
function.
To invoke onchain contracts, use Starknet Foundry’s sncast
, Starkli, or a block explorer. To get the onchain addresses of StarkGate’s contracts, see Important addresses.
For more information on StarkGate’s various functions, see StarkGate functions and events.
Depositing funds
Using StarkGate to deposit L1 funds into the L2 Starknet requires StarkGate’sdeposit
function. The deposit
function does the following:
- Transfers the funds from the user’s Ethereum account to the StarkGate L1 contract.
-
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.
Cancelling a deposit
To ensure self-custody, StarkGate enables you to cancel a deposit if, after depositing funds with thedeposit
function on L1, you don’t see your funds appear on L2 within a reasonable amount of time.
In order to guard against an attack, it takes approximately five days to cancel a deposit. From the moment StarkGate receives the cancellation request, a counter begins. When exactly five days have passed, and the funds still do not appear on L2, you can reclaim the deposit.
To cancel a deposit, call the depositCancelRequest
request function. When StarkGate receives the cancellation request, a counter begins to count five days. When exactly five days have passed, and the funds still do not appear on L2, you can reclaim the deposit by calling depositReclaim
.
As long as the
depositReclaim
was not performed, the deposit may be processed, even if the cancellation delay time has already passed. Only the depositor is allowed to cancel a deposit, and only before depositReclaim was performed.Depositing funds with a message
A deposit with a message is a deposit that moves funds from L1 to L2 and then triggers subsequent actions. For example, a user can deposit funds and transfer those funds to another recipient, such as an exchange. ThedepositWithMessage
function enables sending a deposit with a message. depositWithMessage
is similar to the deposit
function, with an additional 256-bit message, which can contain instructions for executing additional actions.
Upon completion, the depositWithMessage
function triggers a call to a callback function, named on_receive
, on the L2 contract that receives the deposit. The on_receive
function receives the deposit message as input.
on_receive
must return true
for the deposit to succeed. If on_receive
returns false
, or if the recipient contract does not include the on_receive
function, the depositWithMessage
function’s L1 handler fails. The user can recover their funds using the depositWithMessageCancelRequest
function.
To enable deposits with messages in your application:
-
Implement the
on_receive
function in the L2 contract that should receive deposits. -
Use the
depositWithMessage
function to transfer funds from L1 to L2.
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.
-
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
.
-
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.
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.
Withdrawing funds
Using StarkGate to withdraw funds from Starknet requires StarkGate’sinitiate_token_withdraw
function to initiate a withdrawal. The function does the following:
- Burns the transferred amount of tokens from the L2 balance of the withdrawal’s initiator.
- Sends a message to the relevant L1 bridge with the amount to be transferred and the recipient’s Ethereum address.
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 thesetWithdrawLimitPCT()
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.
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.
- 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.
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
withdraw
function on L1.