Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 213 additions & 1 deletion docs/bridging/bridging-fa-how.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The process of bridging FA-compatible tokens from layer 1 to Etherlink (also kno
For information about token access control, see [Token standards](https://docs.tezos.com/architecture/tokens#token-standards) on docs.tezos.com.

1. The user calls the helper contract's `deposit` entrypoint.
The request includes the amount of tokens to bridge, the address of the Etherlink Smart Rollup, and the user's Etherlink wallet address, but not the tokens themselves.
The request includes the address of the Etherlink Smart Rollup, the user's Etherlink account address, and the amount of tokens to bridge, but not the tokens themselves.

1. The token bridge helper contract stores the address of the Etherlink Smart Rollup and the user's Etherlink address temporarily.

Expand All @@ -55,6 +55,12 @@ The request includes the amount of tokens to bridge, the address of the Etherlin
1. Any user can call the FA bridging precompiled contract's `claim` function, which causes the contract to call the ERC-20 proxy contract.
For tokens supported by the bridge, an automated program calls the `claim` function for you.

You can call the `claim` function yourself with this ABI, using the `depositId` field from the event:

```
claim(uint256 depositId)
```

1. The ERC-20 proxy contract mints the equivalent tokens and sends them to the user's Etherlink account.

This diagram is an overview of the process of bridging tokens from layer 1 to Etherlink:
Expand Down Expand Up @@ -93,3 +99,209 @@ This transaction includes the target layer 1 address.
This diagram is an overview of the process of bridging tokens from Etherlink to layer 1:

<img src="/img/bridging-withdrawal-fa.png" alt="Overview of the FA token bridging withdrawal process" style={{width: 500}} />

## Event reference

The contracts that manage the FA bridge emit several events.

### Decoding event information

You can get information about events from the logs of the FA bridging precompiled contract via the Etherlink indexer at this link: https://explorer.etherlink.com/address/0xff00000000000000000000000000000000000002?tab=logs.

You can also decode the information in events with toolkits such as Ethers.js.
For example, this JavaScript program decodes the information from a `QueuedDeposit` event and prints the payload fields:

```javascript
const { ethers } = require("ethers");

// Data from the event
// Topic
const topic = "0xb02d79c5657e344e23d91529b954c3087c60a974d598939583904a4f0b959614";
// Indexed field 1
const index1 = "0x9d4704c610c2ca997e1ad4d4062e09bee26bb5136598b0e525ed357da99bd602";
// Indexed field 2
const index2 = "0x00000000000000000000000001f07f4d78d47a64f4c3b2b65f513f15be6e1854";
// Event data payload
const eventData = "0x0000000000000000000000000000000000000000000000000000000000004ddb000000000000000000000000953d1668bc03e0ee9145a7c4f79956b73db90b67000000000000000000000000000000000000000000000000000000012a05f2000000000000000000000000000000000000000000000000000000000000af1a770000000000000000000000000000000000000000000000000000000000000010";

const abi = [
"event QueuedDeposit(uint256 indexed ticketHash, address indexed proxy, uint256 nonce, address receiver, uint256 amount, uint256 inboxLevel, uint256 inboxMsgId)"
];

const iface = new ethers.Interface(abi);

const log = {
topics: [
topic,
index1,
index2,
],
data: eventData,
};

// Parse the event log
const parsed = iface.parseLog(log);

// Print the non-indexed fields
console.log(JSON.stringify(parsed.args, (_, v) => typeof v === 'bigint' ? v.toString() : v));
```

The result is a list of the decoded fields, in this case, the nonce, receiving address, amount, block level, and message ID for the deposit:

```json
[
"71138596315992044722794716610043613304890979059019361625149303880140533257730",
"0x01F07f4d78d47A64F4C3B2b65f513f15Be6E1854",
"19931",
"0x953D1668BC03e0EE9145A7c4F79956b73db90B67",
"5000000000",
"11475575",
"16"
]
```

### `QueuedDeposit` event

When a deposit is ready to be claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `QueuedDeposit` event.

The ABI for this event is:

```solidity
event QueuedDeposit(
uint256 indexed ticketHash,
address indexed proxy,
uint256 nonce,
address receiver,
uint256 amount,
uint256 inboxLevel,
uint256 inboxMsgId
);
```

The topics for this event are:

Field | Type | Description
--- | --- | ---
Signature | `keccak256` | `QueuedDeposit(uint256, address)`
`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)`
`proxy` | address | The proxy address through which the deposit is routed

The payload includes these fields:

Field | Type | Description
--- | --- | ---
`nonce` | uint256 | The global counter for the transaction
`receiver` | address | The Etherlink address that receives the tokens
`amount` | uint256 | The amount of tokens in the transaction
`inboxLevel` | uint256 | The layer 1 block in which the deposit was submitted
`inboxMsgId` | uint256 | An identifier for the Smart Rollup inbox message

### `Deposit` event

When a deposit has been claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `Deposit` event.

The ABI for this event is:

```solidity
event Deposit(
uint256 indexed ticketHash,
address ticketOwner,
address receiver,
uint256 amount,
uint256 inboxLevel,
uint256 inboxMsgId
);
```

The topics for this event are:

Field | Type | Description
--- | --- | ---
Signature | `keccak256` | `Deposit(uint256)`
`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)`

The payload includes these fields:

Field | Type | Description
--- | --- | ---
`ticketOwner` | address | The ERC-20 proxy contract that manages the tokens
`receiver` | address | The ERC-20 proxy contract that manages the tokens (a duplicate of the `ticketOwner` field)
`amount` | uint256 | The amount of tokens
`inboxLevel` | uint256 | The layer 1 block in which the deposit was submitted
`inboxMsgId` | uint256 | An identifier for the Smart Rollup inbox message, which you can use to find the corresponding `QueuedDeposit` event and the Etherlink address that receives the tokens

### `Withdrawal` event

When an account initiates a withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `Withdrawal` event.

The ABI for this event is:

```solidity
event Withdrawal(
uint256 indexed ticketHash,
address sender,
address ticketOwner,
bytes22 receiver,
bytes22 proxy,
uint256 amount,
uint256 withdrawalId
);
```

The topics for this event are:

Field | Type | Description
--- | --- | ---
Signature | `keccak256` | `Withdrawal(uint256)`
`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)`

The payload includes these fields:

Field | Type | Description
--- | --- | ---
`sender` | address | The Etherlink address that is withdrawing the tokens
`ticketOwner` | address | The ERC-20 proxy contract that manages the tokens
`receiver` | bytes22 | The layer 1 address that receives the tokens
`proxy` | bytes22 | The proxy address through which the deposit is routed
`amount` | uint256 | The amount of tokens
`withdrawalId` | uint256 | An internal ID for the withdrawal

### `FastFaWithdrawal` event

When an account initiates a fast withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `FastFaWithdrawal` event.

The ABI for this event is:

```solidity
event FastFaWithdrawal(
uint256 indexed ticketHash,
address sender,
address ticketOwner,
bytes22 receiver,
bytes22 proxy,
uint256 amount,
uint256 withdrawalId,
uint256 timestamp,
bytes payload
);
```

The topics for this event are:

Field | Type | Description
--- | --- | ---
Signature | `keccak256` | `FastFaWithdrawal(uint256)`
`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)`

The payload includes these fields:

Field | Type | Description
--- | --- | ---
`sender` | address | The Etherlink address that is withdrawing the tokens
`ticketOwner` | address | The ERC-20 proxy contract that manages the tokens
`receiver` | bytes22 | The layer 1 address that receives the tokens
`proxy` | bytes22 | The proxy address through which the deposit is routed
`amount` | uint256 | The amount of tokens
`withdrawalId` | uint256 | An internal ID for the withdrawal
`timestamp` | uint256 | The timestamp of the block that includes the fast withdrawal request
`payload` | bytes | Information about the fast withdrawal to forward to the fast withdrawal contact
13 changes: 12 additions & 1 deletion docs/bridging/bridging-fa-transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,20 @@ Follow these steps to deposit FA-compliant tokens from layer 1 to Etherlink:
--burn-cap 0.1
```

For reference, this is the Micheline type for the parameter for this transaction:

```michelson
(pair %deposit (address %rollup) (pair (bytes %receiver) (nat %amount)))
```

The token bridge helper contract sends the tokens to the ticketer contract, which issues a ticket that represents the tokens.
The token bridge helper contract sends that ticket to Etherlink.

When Etherlink receives that deposit, the FA bridging precompiled contract (`0xff0...0002`) emits a `QueuedDeposit` event that includes the `depositId` for the deposit, which is needed to claim the deposit; see [Event reference](/bridging/bridging-fa-how#event-reference).

1. When the deposit is in an Etherlink block, call the FA bridging precompiled contract contract's `claim` function to cause the ERC-20 proxy contract to mint the tokens.

The address of the precompiled contract is `0xff00000000000000000000000000000000000002` and to call the function you can use the ABI `claim(uint256 depositId)`, where `depositId` matches the `depositId` that was emitted in a previous event for this transfer by the precompile (`QueuedDeposit(uint256 depositId, address recipient, uint256 amount, uint256 timelock, uint256 depositCount)`).
The address of the precompiled contract is `0xff00000000000000000000000000000000000002` and to call the function you can use the ABI `claim(uint256 depositId)`, where `depositId` matches the `depositId` that was emitted in a previous event.

As a reference, here is an [example of the sequencer injecting a deposit](https://explorer.etherlink.com/tx/0x5a06fe64e880d6d1f53c243477cd5656204712f1543b607340996ad246158669) and here is an [example of the corresponding claim transaction](https://explorer.etherlink.com/tx/0xe017665cd7bfdef375a863114ac9f7ed2538da4d8584b0f1e0aa71ce96342aee).

Expand All @@ -72,6 +80,8 @@ Follow these steps to deposit FA-compliant tokens from layer 1 to Etherlink:

:::

When the deposit has been claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `Deposit` event; see [Event reference](/bridging/bridging-fa-how#event-reference).

To see the tokens in your Etherlink wallet, look up the ERC-20 proxy contract in a block explorer or use its address to manually add the tokens to your wallet.
Because the Etherlink tokens are compatible with the ERC-20 standard, EVM-compatible wallets should be able to display them.

Expand All @@ -87,5 +97,6 @@ Therefore, if the system that runs these outbox transactions is down for two wee
Neither of these transactions are easy to do by yourself.
Initiating the withdrawal requires sending complex information about the ticket and contracts to the FA2 withdrawal precompile on Etherlink.
Running the outbox transaction requires you to know the level of the Etherlink commitment that contains it in order to get its proof and commitment, and there is no easy way to get that information without using an indexer to check each level for the transaction.
You can also watch for the `Withdrawal` and `FastFaWithdrawal` events, as described in [Event reference](/bridging/bridging-fa-how#event-reference).

The command-line tool at https://github.com/baking-bad/etherlink-bridge provides commands that can help with the withdrawal transactions.