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

# Deposit Addresses

> Deterministic deposit addresses using counterfactual smart contracts

## Overview

Deposit Addresses allow users to bridge funds by sending tokens to a pre-computed address — no wallet connection, no calldata, and no approval transactions required. Under the hood, Relay uses **counterfactual smart contracts** to generate deterministic deposit addresses for each `(orderId, depositor)` pair. Funds sent to these addresses are swept into the [Depository](/references/protocol/components/depository) and attributed to the correct order and depositor.

This is powered by two contracts: a **DepositAddressFactory** (deployed once per chain) and a **DepositAddress** (a stateless implementation contract that proxies delegate to).

<Info>
  For API integration details and usage examples, see the [Deposit Addresses feature guide](/features/deposit-addresses).
</Info>

## How It Works

The flow has three phases: address computation, deposit, and sweep.

```mermaid theme={null}
sequenceDiagram
    participant API as Relay API
    participant F as DepositAddressFactory
    participant DA as Deposit Address
    participant D as Depository

    API->>F: 1. computeDepositAddress(orderId, depositor)
    F-->>API: 2. Return deterministic address
    Note over API: 3. Return address to user
    Note over DA: 4. User sends funds to address
    API->>F: 5. sweep(orderId, depositor, tokens)
    F->>DA: 6. Deploy EIP-1167 proxy via CREATE2
    DA->>D: 7. Sweep funds to Depository
```

### Address Computation

Each deposit address is deterministically derived from the **orderId** and **depositor** using CREATE2 and [EIP-1167](https://eips.ethereum.org/EIPS/eip-1167) minimal proxy clones. The factory computes a salt as `keccak256(orderId, depositor)`, so the address depends on the factory address, the implementation address, and that combined salt. This means the address can be computed **before any contract is deployed** there.

This is what makes deposit addresses "counterfactual" — the address is valid and can receive funds even though no contract exists at that address yet.

### Deposit

The user sends ERC20 tokens or native ETH directly to the computed address. No calldata is needed — a simple transfer is sufficient. The funds sit at the address until the sweep is triggered.

### Sweep

Once funds arrive, the Relay backend calls `sweep` on the DepositAddressFactory. This atomically:

1. **Deploys** an EIP-1167 minimal proxy at the pre-computed address (using CREATE2)
2. **Calls** the proxy's `sweep` function via delegatecall to the DepositAddress implementation
3. **Transfers** all funds from the deposit address into the Depository, tagged with the correct `orderId` and `depositor`

If the proxy has already been deployed (e.g., from a previous deposit for the same `(orderId, depositor)` pair), the factory calls `sweep` directly on the existing proxy — no redeployment needed.

## Contracts

### DepositAddressFactory

The factory is deployed once per supported chain. It has two key functions:

* **`computeDepositAddress(orderId, depositor)`** — Returns the deterministic address where a user should send funds for a given order and credited depositor. This is a view function that requires no gas.
* **`sweep(orderId, depositor, tokens)`** — Deploys the proxy (if needed) and sweeps all specified tokens to the Depository. The `tokens` array supports sweeping multiple token types in a single transaction.

The factory holds two immutable references:

* **DEPOSITORY** — The Depository contract on that chain
* **IMPLEMENTATION** — The DepositAddress implementation contract

### DepositAddress

The DepositAddress is a stateless implementation contract. It is never called directly — instead, EIP-1167 minimal proxies delegate to it. When called via a proxy, it:

1. Reads the token balance at the proxy address
2. For **ERC20 tokens**: approves the Depository and calls `depositErc20(depositor, token, amount, orderId)`
3. For **native ETH**: calls `depositNative(depositor, orderId)` with the ETH value

The DepositAddress includes a `receive()` function to handle edge cases where ETH is sent to the proxy via `selfdestruct` or block rewards, preventing griefing attacks that could block proxy deployment.

## Multi-Token Support

A single deposit address can receive multiple token types. The `sweep` function accepts an array of token addresses, sweeping each one to the Depository in a single transaction. The zero address (`0x0000000000000000000000000000000000000000`) represents native ETH.

## Security

* **Deterministic and verifiable** — Anyone can independently compute a deposit address from the `orderId` and `depositor` and verify it matches what the API returned
* **Atomic operations** — `sweep` is atomic: if any part fails, the entire transaction reverts and funds remain safe at the deposit address
* **No approval risk** — Users send funds via simple transfers. No token approvals are granted to third parties
* **Non-upgradable** — Both the factory and DepositAddress are immutable contracts
* **Re-sweep safe** — If additional funds are sent to an address after the initial sweep, they can be recovered by calling `sweep` again

## Source Code

The DepositAddressFactory and DepositAddress contracts are part of the [`settlement-protocol`](https://github.com/relayprotocol/settlement-protocol) repository.
