From 62827ad03aa8c96a521cec6e8d13b2a6ca1098cd Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Thu, 18 Sep 2025 13:16:47 -0400 Subject: [PATCH 1/8] WIP first attempt --- docs/bridging/bridging-fa-how.md | 102 +++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index b15e90d2..a4a291ad 100644 --- a/docs/bridging/bridging-fa-how.md +++ b/docs/bridging/bridging-fa-how.md @@ -93,3 +93,105 @@ This transaction includes the target layer 1 address. This diagram is an overview of the process of bridging tokens from Etherlink to layer 1: Overview of the FA token bridging withdrawal process + +## Event reference + +The contracts that manage the FA bridge emit these events: + +### `QueuedDeposit` event + +When a deposit is ready to be claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `QueuedDeposit` event that includes the following information: + +Field | Type | Description +--- | --- | --- +`ticket_owner` | address | ??? +`receiver` | address | The Etherlink account that will receive the claimed tokens +`amount` | uint256 | The amount of tokens +`inbox_level` | unit256 | ??? +`inbox_msg_id` | unit256 | The ID of the bridging transaction that users need to claim the pending deposit + +### `Deposit` event + +When a deposit has been claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `Deposit` event that includes the following information: + +Field | Type | Description +--- | --- | --- +`nonce` | unit256 | The nonce for the bridging transaction +`receiver` | address | The Etherlink account that received the claimed tokens +`amount` | uint256 | The amount of tokens +`inbox_level` | unit256 | ??? +`inbox_msg_id` | unit256 | The ID of the bridging transaction + +TODO ^ This info from `etherlink/kernel_latest/evm_execution/src/fa_bridge/deposit.rs` does not match with the blog post, which says that the signature should be `Deposit(uint256,address,address,uint256,uint256,uint256)` + +### `Withdrawal` event + +When an account initiates a withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `Withdrawal` event that includes the following information: + + +Field | Type | Description +--- | --- | --- +`amount` | unit256 | The amount of tokens +`sender` | address | The address of the Etherlink account sending the tokens +`receiver` | bytes22 | A bytecode representation of the Tezos address of the account receiving the tokens +`withdrawalId` | unit256 | The ID of the bridging transaction + +### TODO other events + +TODO other withdrawal events from `etherlink/kernel_latest/evm_execution/src/fa_bridge/withdrawal.rs`: + +```rust +alloy_sol_types::sol! { + event SolStandardWithdrawalInput ( + address ticket_owner, + bytes routing_info, + uint256 amount, + bytes22 ticketer, + bytes content, + ); +} + +alloy_sol_types::sol! { + event SolFastWithdrawalInput ( + address ticket_owner, + bytes routing_info, + uint256 amount, + bytes22 ticketer, + bytes content, + string fast_withdrawal_contract_address, + bytes payload, + ); +} + +alloy_sol_types::sol! { + event SolStandardWithdrawalProxyCallData ( + address sender, + uint256 amount, + uint256 ticket_hash, + ); +} + +alloy_sol_types::sol! { + event SolStandardWithdrawalEvent ( + address sender, + address ticket_owner, + bytes22 receiver, + bytes22 proxy, + uint256 amount, + uint256 withdrawal_id, + ); +} + +alloy_sol_types::sol! { + event SolFastFAWithdrawalEvent ( + address sender, + address ticket_owner, + bytes22 receiver, + bytes22 proxy, + uint256 amount, + uint256 withdrawal_id, + uint256 timestamp, + bytes payload, + ); +} +``` \ No newline at end of file From 0d62d03b5793f1a21405a287b835288446a1b4ab Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Thu, 18 Sep 2025 14:53:49 -0400 Subject: [PATCH 2/8] WIP more info about ABIs and events --- docs/bridging/bridging-fa-how.md | 19 ++++++++++++------- docs/bridging/bridging-fa-transactions.md | 12 +++++++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index a4a291ad..99748304 100644 --- a/docs/bridging/bridging-fa-how.md +++ b/docs/bridging/bridging-fa-how.md @@ -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. @@ -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: @@ -104,11 +110,11 @@ When a deposit is ready to be claimed, the FA bridging precompiled contract (`0x Field | Type | Description --- | --- | --- -`ticket_owner` | address | ??? -`receiver` | address | The Etherlink account that will receive the claimed tokens +`depositId` | uint265 | The ID of the bridging transaction that users need to claim the pending deposit +`recipient` | address | The Etherlink account that will receive the claimed tokens `amount` | uint256 | The amount of tokens -`inbox_level` | unit256 | ??? -`inbox_msg_id` | unit256 | The ID of the bridging transaction that users need to claim the pending deposit +`timelock` | uint256 | ??? +`depositCount` | uint256 | ??? ### `Deposit` event @@ -128,7 +134,6 @@ TODO ^ This info from `etherlink/kernel_latest/evm_execution/src/fa_bridge/depos When an account initiates a withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `Withdrawal` event that includes the following information: - Field | Type | Description --- | --- | --- `amount` | unit256 | The amount of tokens @@ -138,7 +143,7 @@ Field | Type | Description ### TODO other events -TODO other withdrawal events from `etherlink/kernel_latest/evm_execution/src/fa_bridge/withdrawal.rs`: +TODO other withdrawal events from `etherlink/kernel_latest/evm_execution/src/fa_bridge/withdrawal.rs` but I'm not sure if these fields translate directly to the fields in the event because they seemed to be different for the deposit events: ```rust alloy_sol_types::sol! { diff --git a/docs/bridging/bridging-fa-transactions.md b/docs/bridging/bridging-fa-transactions.md index 1bbac265..5e184778 100644 --- a/docs/bridging/bridging-fa-transactions.md +++ b/docs/bridging/bridging-fa-transactions.md @@ -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). @@ -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. From d3062408f7fdd1b4f92f260bf9c080643df19bab Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Mon, 1 Dec 2025 12:47:23 -0500 Subject: [PATCH 3/8] Corrected info about FA bridge events --- docs/bridging/bridging-fa-how.md | 110 ++++++++++--------------------- 1 file changed, 35 insertions(+), 75 deletions(-) diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index 99748304..9ed860e6 100644 --- a/docs/bridging/bridging-fa-how.md +++ b/docs/bridging/bridging-fa-how.md @@ -110,11 +110,13 @@ When a deposit is ready to be claimed, the FA bridging precompiled contract (`0x Field | Type | Description --- | --- | --- -`depositId` | uint265 | The ID of the bridging transaction that users need to claim the pending deposit -`recipient` | address | The Etherlink account that will receive the claimed tokens -`amount` | uint256 | The amount of tokens -`timelock` | uint256 | ??? -`depositCount` | uint256 | ??? +`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 +`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 @@ -122,13 +124,12 @@ When a deposit has been claimed, the FA bridging precompiled contract (`0xff0... Field | Type | Description --- | --- | --- -`nonce` | unit256 | The nonce for the bridging transaction -`receiver` | address | The Etherlink account that received the claimed tokens +`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` +`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 -`inbox_level` | unit256 | ??? -`inbox_msg_id` | unit256 | The ID of the bridging transaction - -TODO ^ This info from `etherlink/kernel_latest/evm_execution/src/fa_bridge/deposit.rs` does not match with the blog post, which says that the signature should be `Deposit(uint256,address,address,uint256,uint256,uint256)` +`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 @@ -136,67 +137,26 @@ When an account initiates a withdrawal, the FA bridging precompiled contract (`0 Field | Type | Description --- | --- | --- -`amount` | unit256 | The amount of tokens -`sender` | address | The address of the Etherlink account sending the tokens -`receiver` | bytes22 | A bytecode representation of the Tezos address of the account receiving the tokens -`withdrawalId` | unit256 | The ID of the bridging transaction - -### TODO other events - -TODO other withdrawal events from `etherlink/kernel_latest/evm_execution/src/fa_bridge/withdrawal.rs` but I'm not sure if these fields translate directly to the fields in the event because they seemed to be different for the deposit events: - -```rust -alloy_sol_types::sol! { - event SolStandardWithdrawalInput ( - address ticket_owner, - bytes routing_info, - uint256 amount, - bytes22 ticketer, - bytes content, - ); -} - -alloy_sol_types::sol! { - event SolFastWithdrawalInput ( - address ticket_owner, - bytes routing_info, - uint256 amount, - bytes22 ticketer, - bytes content, - string fast_withdrawal_contract_address, - bytes payload, - ); -} - -alloy_sol_types::sol! { - event SolStandardWithdrawalProxyCallData ( - address sender, - uint256 amount, - uint256 ticket_hash, - ); -} - -alloy_sol_types::sol! { - event SolStandardWithdrawalEvent ( - address sender, - address ticket_owner, - bytes22 receiver, - bytes22 proxy, - uint256 amount, - uint256 withdrawal_id, - ); -} - -alloy_sol_types::sol! { - event SolFastFAWithdrawalEvent ( - address sender, - address ticket_owner, - bytes22 receiver, - bytes22 proxy, - uint256 amount, - uint256 withdrawal_id, - uint256 timestamp, - bytes payload, - ); -} -``` \ No newline at end of file +`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` +`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 that includes the following information: + +Field | Type | Description +--- | --- | --- +`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` +`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 From 88170d869980266e810688d4a6cb5f5bf1b997ea Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Mon, 1 Dec 2025 12:49:38 -0500 Subject: [PATCH 4/8] Reference for withdrawal events --- docs/bridging/bridging-fa-transactions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/bridging/bridging-fa-transactions.md b/docs/bridging/bridging-fa-transactions.md index 5e184778..0f9ddc25 100644 --- a/docs/bridging/bridging-fa-transactions.md +++ b/docs/bridging/bridging-fa-transactions.md @@ -97,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. From b3cfcb045bc2625fe4c09c0ffdbf121f0673a17d Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Tue, 2 Dec 2025 09:48:34 -0500 Subject: [PATCH 5/8] Separate indexed fields as topics --- docs/bridging/bridging-fa-how.md | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index 9ed860e6..69cbc2e8 100644 --- a/docs/bridging/bridging-fa-how.md +++ b/docs/bridging/bridging-fa-how.md @@ -106,12 +106,19 @@ The contracts that manage the FA bridge emit these events: ### `QueuedDeposit` event -When a deposit is ready to be claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `QueuedDeposit` event that includes the following information: +When a deposit is ready to be claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `QueuedDeposit` event. + +The event includes these topics: Field | Type | Description --- | --- | --- `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 @@ -120,11 +127,16 @@ Field | Type | Description ### `Deposit` event -When a deposit has been claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `Deposit` event that includes the following information: +When a deposit has been claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `Deposit` event. + +The event includes these topics: Field | Type | Description --- | --- | --- `ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` + +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 @@ -133,11 +145,16 @@ Field | Type | Description ### `Withdrawal` event -When an account initiates a withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `Withdrawal` event that includes the following information: +When an account initiates a withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `Withdrawal` event. + +The event includes these topics: Field | Type | Description --- | --- | --- `ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` + +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 @@ -147,11 +164,16 @@ Field | Type | Description ### `FastFaWithdrawal` event -When an account initiates a fast withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `FastFaWithdrawal` event that includes the following information: +When an account initiates a fast withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `FastFaWithdrawal` event. + +The event includes these topics: Field | Type | Description --- | --- | --- `ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` + +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 From 7bbef85c407e92f8f1f04a74f653912359396654 Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Tue, 2 Dec 2025 10:46:43 -0500 Subject: [PATCH 6/8] Separate ABI? --- docs/bridging/bridging-fa-how.md | 83 ++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index 69cbc2e8..7b176f82 100644 --- a/docs/bridging/bridging-fa-how.md +++ b/docs/bridging/bridging-fa-how.md @@ -108,17 +108,26 @@ The contracts that manage the FA bridge emit these events: When a deposit is ready to be claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `QueuedDeposit` event. -The event includes these topics: - -Field | Type | Description ---- | --- | --- -`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: +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 +); +``` + +These are the fields in the event: Field | Type | Description --- | --- | --- +`ticketHash` | uint256 (indexed) | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` +`proxy` | address (indexed) | The proxy address through which the deposit is routed `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 @@ -129,14 +138,24 @@ Field | Type | Description When a deposit has been claimed, the FA bridging precompiled contract (`0xff0...0002`) emits a `Deposit` event. -The event includes these topics: +The ABI for this event is: -Field | Type | Description ---- | --- | --- -`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` +```solidity +event Deposit( + uint256 indexed ticketHash, + address ticketOwner, + address receiver, + uint256 amount, + uint256 inboxLevel, + uint256 inboxMsgId +); +``` + +These are the fields in the event: Field | Type | Description --- | --- | --- +`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` `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 @@ -147,14 +166,25 @@ Field | Type | Description When an account initiates a withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `Withdrawal` event. -The event includes these topics: +The ABI for this event is: -Field | Type | Description ---- | --- | --- -`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` +```solidity +event Withdrawal( + uint256 indexed ticketHash, + address sender, + address ticketOwner, + bytes22 receiver, + bytes22 proxy, + uint256 amount, + uint256 withdrawalId +); +``` + +These are the fields in the event: Field | Type | Description --- | --- | --- +`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` `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 @@ -166,14 +196,27 @@ Field | Type | Description When an account initiates a fast withdrawal, the FA bridging precompiled contract (`0xff0...0002`) emits a `FastFaWithdrawal` event. -The event includes these topics: +The ABI for this event is: -Field | Type | Description ---- | --- | --- -`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` +```solidity +event FastFaWithdrawal( + uint256 indexed ticketHash, + address sender, + address ticketOwner, + bytes22 receiver, + bytes22 proxy, + uint256 amount, + uint256 withdrawalId, + uint256 timestamp, + bytes payload +); +``` + +These are the fields in the event: Field | Type | Description --- | --- | --- +`ticketHash` | uint256 | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` `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 From 1f96ddc75db4d78096d3d499cc3889ac86bbad00 Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Tue, 2 Dec 2025 11:09:43 -0500 Subject: [PATCH 7/8] Separate topics and payload --- docs/bridging/bridging-fa-how.md | 36 ++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index 7b176f82..ae5f3e5c 100644 --- a/docs/bridging/bridging-fa-how.md +++ b/docs/bridging/bridging-fa-how.md @@ -122,12 +122,18 @@ event QueuedDeposit( ); ``` -These are the fields in the event: +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 --- | --- | --- -`ticketHash` | uint256 (indexed) | The hash of the ticket that represents the transferred tokens, computed as `keccak256(L1 ticketer + content)` -`proxy` | address (indexed) | The proxy address through which the deposit is routed `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 @@ -151,11 +157,17 @@ event Deposit( ); ``` -These are the fields in the event: +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 @@ -180,11 +192,17 @@ event Withdrawal( ); ``` -These are the fields in the event: +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 @@ -212,11 +230,17 @@ event FastFaWithdrawal( ); ``` -These are the fields in the event: +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 From 091c992eba10787003bb1cd0ce220e5e6b2fa551 Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Fri, 9 Jan 2026 12:53:11 -0500 Subject: [PATCH 8/8] Decoding the data --- docs/bridging/bridging-fa-how.md | 58 +++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index ae5f3e5c..75881bcc 100644 --- a/docs/bridging/bridging-fa-how.md +++ b/docs/bridging/bridging-fa-how.md @@ -102,7 +102,63 @@ This diagram is an overview of the process of bridging tokens from Etherlink to ## Event reference -The contracts that manage the FA bridge emit these events: +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