> ## Documentation Index
> Fetch the complete documentation index at: https://docs.optimism.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Deposit flow

> Learn the deposit flow process for L2 deposit transactions, triggered by events on L1.

<Info>
  **Learn the OP Stack — stop 8 of 13.**
  You've followed a transaction that starts and ends on L2. This page
  adds the first cross-layer direction: how a transaction triggered on L1
  becomes an L2 transaction. When you're done, continue to
  [Withdrawal flow](/op-stack/bridging/withdrawal-flow).
</Info>

This page explains the deposit flow process for L2 deposit transactions, triggered by transactions or events on L1. In Optimism terminology, "*deposit transaction*" refers to any L2 transaction that is triggered by a transaction or event on L1.

The process is somewhat similar to the way [most networking stacks work](https://en.wikipedia.org/wiki/Encapsulation_\(networking\)).
Information is encapsulated in lower layer packets on the sending side and then retrieved and used by those layers on the receiving side while going up the stack to the receiving application.

<img src="https://mintcdn.com/optimism-373f39ad/Vw5vY8zA-CRjBsUF/public/img/op-stack/protocol/deposit-flow-dark-mode.svg?fit=max&auto=format&n=Vw5vY8zA-CRjBsUF&q=85&s=8f78795feb23731f55ea66b94f16460f" alt="Deposit Flow Diagram." width="960" height="720" data-path="public/img/op-stack/protocol/deposit-flow-dark-mode.svg" />

## L1 processing

1. An L1 entity, either a smart contract or an externally owned account (EOA), sends a deposit transaction to [`L1CrossDomainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol), using [`sendMessage`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol#L191-L211).
   This function accepts three parameters:

   * `_target`, target address on L2.
   * `_message`, the L2 transaction's calldata, formatted as per the [ABI](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html) of the target account.
   * `_minGasLimit`, the minimum gas limit allowed for the transaction on L2. Note that this is a *minimum* and the actual amount provided on L2 may be higher (but never lower) than the specified gas limit. The actual amount provided on L2 is often higher because the portal contract on L2 performs some processing before submitting the call to `_target`.

2. The L1 cross domain messenger calls [its own `_sendMessage` function](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol#L83-L91).
   It uses these parameters:

   * `_to`, the destination address, is the messenger on the other side.
     In the case of deposits, this is always [`0x4200000000000000000000000000000000000007`](https://testnet-explorer.optimism.io/address/0x4200000000000000000000000000000000000007).
   * `_gasLimit`, the gas limit.
     This value is calculated using [the `baseGas` function](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol#L357-L396).
   * `_value`, the ETH that is sent with the message.
     This amount is taken from the transaction value.
   * `_data`, the calldata for the call on L2 that is needed to relay the message.
     This is an [ABI encoded](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html) call to [`relayMessage`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol#L222-L320).

3. [`_sendMessage`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol#L83-L91) calls the portal's [`depositTransaction` function](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L684-L738).

   Note that other contracts can also call [`depositTransaction`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L684-L738) directly.
   However, doing so bypasses certain safeguards, so in most cases it's a bad idea.

4. [The `depositTransaction` function](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L684-L738) runs a few sanity checks, and then emits a [`TransactionDeposited`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L149-L155) event.

## L2 processing

1. The `op-node` component [looks for `TransactionDeposited` events on L1](https://github.com/ethereum-optimism/optimism/blob/develop/op-node/rollup/derive/deposits.go#L15-L34).
   If it sees any such events, it [parses](https://github.com/ethereum-optimism/optimism/blob/develop/op-node/rollup/derive/deposit_log.go) them.

2. Next, `op-node` [converts](https://github.com/ethereum-optimism/optimism/blob/develop/op-node/rollup/derive/deposits.go#L36-L52) those `TransactionDeposited` events into [deposit transactions](https://specs.optimism.io/protocol/deposits.html?utm_source=op-docs\&utm_medium=docs#user-deposited-transactions).

3. In most cases, user deposit transactions call the [`relayMessage`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol#L222-L320) function of [`L2CrossDomainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol#L22).

4. `relayMessage` runs a few sanity checks and then, if everything is good, [calls the real target contract with the relayed calldata](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/CrossDomainMessenger.sol#L298).

## Denial of service (DoS) prevention

As with all other L1 transactions, the L1 costs of a deposit are borne by the transaction's originator.
However, the L2 processing of the transaction is performed by the Optimism nodes.
If there were no cost attached, an attacker could submit a transaction that had high execution costs on L2, and that way perform a denial of service attack.

To avoid this DoS vector, [`depositTransaction`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L684-L738), and the functions that call it, require a gas limit parameter.
[This gas limit is encoded into the `TransactionDeposited` event](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/OptimismPortal2.sol#L733-L737), and used as the gas limit for the user deposit transaction on L2.

This L2 gas is paid for by burning L1 gas [here](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L1/ResourceMetering.sol#L149).

## Replaying failed deposits

Deposit transactions can fail on L2 — usually because not enough gas was provided, or the L2 state did not allow the transaction to succeed. When that happens the message is not lost: `L2CrossDomainMessenger` records it as a failed message, and you can replay it later, optionally with more gas.

To walk through triggering a failed deposit and replaying it end to end, follow the tutorial [Replaying a failed deposit](/app-developers/tutorials/bridging/replay-failed-deposit).
