diff --git a/docs/bridging/bridging-fa-how.md b/docs/bridging/bridging-fa-how.md index b15e90d2..75881bcc 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: @@ -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: Overview of the FA token bridging withdrawal process + +## 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 diff --git a/docs/bridging/bridging-fa-transactions.md b/docs/bridging/bridging-fa-transactions.md index 1bbac265..0f9ddc25 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. @@ -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.