Skip to content

Commit 4cde683

Browse files
committed
Dev tools: custom contract bridging using Matic.js
- Restructuring - Multiple fixes
1 parent f1b0949 commit 4cde683

File tree

2 files changed

+61
-55
lines changed

2 files changed

+61
-55
lines changed

docs/tools/matic-js/zkevm/message.md renamed to docs/tools/matic-js/zkevm/custom-contract-bridging.md

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,27 @@
1-
This document shows you how to customize wrapped tokens using adapter contracts, transfer tokens between Ethereum and Polygon zkEVM networks, and how to use Matic.js to bridge assets from Ethereum to Polygon zkEVM and vice versa.
1+
This document shows you how to customize wrapped tokens using adapter contracts, and how to use Matic.js to bridge assets from Ethereum to Polygon zkEVM and vice versa using the messaging layer of the Polygon bridge.
22

3-
We refer to Ethereum as the _root_ chain and zkEVM as the _child_ chain.
3+
!!! info "Terminology"
44

5-
## Bridging customized ERC20 token
5+
Within the scope of this doc, we refer to Ethereum as the _root_ chain and zkEVM as the _child_ chain.
66

7-
The existing zkEVM bridge uses the ERC-20 standard contract for creating wrapped tokens depending on the token's native network.
7+
The existing zkEVM bridge uses the ERC20 standard contract for creating wrapped tokens depending on the token's native network.
88

9-
Often, organizations want to customise their wrapped tokens by extending some functionalities.
9+
Often, organizations want to customize their wrapped tokens by extending some functionalities.
1010

1111
These functionalities could include: blacklisting, putting a cap on minting, or any sound auxiliary functionality.
1212

13-
This can be done by deploying adapter contracts that use the messaging layer of the bridge.
13+
This can be done by deploying **adapter contracts** that use the messaging layer of the bridge.
1414

15-
However, for the sake of maintaining consistency among wrapped tokens, strict standards must be followed when extending their functionalities.
15+
## Adapter contracts
1616

17-
## Standardizations
18-
19-
1. Adapter contracts need to implement the [Polygon bridge library](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/base/PolygonERC20BridgeBase.sol) and expose `bridgeToken()` and `onMessageReceived()` functions.
20-
2. There should be two separate adapter contracts; `OriginChainBridgeAdapter` and `WrapperChainBridgeAdapter`.
21-
3. `bridgeToken` function should match the exact function signature and be similar to [this](https://github.com/maticnetwork/static/blob/master/network/mainnet/cherry/artifacts/zkevm/ZkEVMBridgeAdapter.json) ABI.
22-
23-
### Nice to have
24-
25-
Expose the following variables,
26-
27-
1. `originTokenAddress`: Address of the native token.
28-
2. `originTokenNetwork`: `networkId` of the chain to which the token is native.
29-
3. `wrappedTokenAddress`: Address of the wrapped token.
30-
31-
## What is an adapter?
32-
33-
An adapter is a wrapper contract that implements the [Polygon bridge library](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/base/PolygonERC20BridgeBase.sol). An implementation example for ERC20 can be found [here](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/lib/PolygonERC20BridgeLib.sol).
17+
An adapter is a wrapper contract that implements the [Polygon bridge library](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/base/PolygonERC20BridgeBase.sol). An example implementation for ERC20 can be found [here](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/lib/PolygonERC20BridgeLib.sol).
3418

3519
Ideally, the following adapter contracts are expected,
3620

3721
1. `OriginChainBridgeAdapter`
3822
2. `WrapperChainBridgeAdapter`
3923

40-
Irrespective of whether an ERC-20 token is Ethereum native (root chain) or ZkEvm native (child chain), an adapter contract should have the following functions (these are already part of the [library](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/base/PolygonERC20BridgeBase.sol).
24+
Irrespective of whether an ERC20 token is Ethereum native (root chain) or zkEVM native (child chain), an adapter contract should have the following functions: (these are already part of the [library](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/base/PolygonERC20BridgeBase.sol)).
4125

4226
```solidity
4327
function bridgeToken(
@@ -53,61 +37,83 @@ function onMessageReceived(
5337
) external payable {}
5438
```
5539

56-
## How does it work?
40+
For the sake of maintaining consistency among wrapped tokens in terms of the bridging mechanism, there are certain standard functions and variables that need be included in the adapter contracts.
5741

58-
`PolygonZkEVMBridge` is the main bridge contract. It exposes a `bridgeMessage()` function, which users can call in order to bridge messages from L1 to L2, or vice versa. The `claimMessage()` function can be called in the receiving chain to claim the sent message.
42+
## Standardizations
5943

60-
For example, a user who wants to bridge a message from Ethereum to zkEVM, can call `bridgeMessage()` in Ethereum and then call `claimMessage()` in zkEVM. Once the `claimMessage()` function is called, the bridge calls `onMessageReceived` in the destination address.
44+
1. Adapter contracts need to implement the [Polygon bridge library](https://github.com/0xPolygonHermez/code-examples/blob/main/customERC20-bridge-example/contracts/base/PolygonERC20BridgeBase.sol) and expose `bridgeToken()` and `onMessageReceived()` functions.
45+
2. There should be two separate adapter contracts; `OriginChainBridgeAdapter` and `WrapperChainBridgeAdapter`.
46+
3. `bridgeToken` function should match the exact function signature and be similar to [this](https://github.com/maticnetwork/static/blob/master/network/mainnet/cherry/artifacts/zkevm/ZkEVMBridgeAdapter.json) ABI.
47+
48+
### Nice to have
49+
50+
Expose the following variables,
51+
52+
1. `originTokenAddress`: Address of the native token.
53+
2. `originTokenNetwork`: `networkId` of the chain to which the token is native.
54+
3. `wrappedTokenAddress`: Address of the wrapped token.
6155

62-
Adapter contracts are basically abstractions that uses `bridgeMessage()` to bridge and `onMessageReceived()` to process a `claimMessage()` in respective chains.
56+
## Bridging mechanism
57+
58+
`PolygonZkEVMBridge` is the main bridge contract. It exposes a `bridgeMessage()` function, which users can call in order to bridge messages from L1 to L2, or vice versa. The `claimMessage()` function can be called on the receiving chain to claim the sent message.
59+
60+
For example, a user who wants to bridge a message from Ethereum to zkEVM, can call `bridgeMessage()` on Ethereum and then call `claimMessage()` on zkEVM. Once the `claimMessage()` function is called, the bridge calls `onMessageReceived` for the specified destination address.
61+
62+
Adapter contracts are basically abstractions that use `bridgeMessage()` to bridge and `onMessageReceived()` to process a `claimMessage()` on respective chains.
6363

6464
![Figure: Adapter contract](../../../img/learn/maticjs-adapter-contract-01.png)
6565

66-
## ERC-20 transfer
66+
## ERC20 transfer contract interaction
6767

68-
The transfer of ERC-20 tokens using each of the adapter contracts can be broken down as follows.
68+
The transfer of ERC20 tokens using each of the adapter contracts and the actions performed in the process are described below.
6969

7070
### OriginChainBridgeAdapter
7171

72-
The `bridgeToken()` function is called by the deployed adapter contract, to deposit an ERC-20 token from Ethereum to zkEVM.
72+
When depositing an ERC20 token from Ethereum to zkEVM, the adapter contract calls the `bridgeToken()` function.
7373

74-
The `onMessageReceived()` function is then called by the [PolygonZkEvmBridge.sol](https://github.com/0xPolygonHermez/zkevm-contracts/blob/main/contracts/PolygonZkEVMBridge.sol) contract when `claimMessage()` is called during withdrawal of tokens from zkEVM.
74+
During withdrawal from zkEVM, the [PolygonZkEvmBridge.sol](https://github.com/0xPolygonHermez/zkevm-contracts/blob/main/contracts/PolygonZkEVMBridge.sol) contract calls the `onMessageReceived()` function when `claimMessage()` is invoked.
7575

7676
### WrapperChainBridgeAdapter
7777

78-
The `bridgeToken()` function is called by the deployed adapter contract to withdraw ERC20 from ZkEVM to Ethereum
78+
When withdrawing an ERC20 token from zkEVM to Ethereum, the adapter contract calls the `bridgeToken()` function.
7979

80-
The `onMessageReceived` function is called by the [PolygonZkEvmBridge.sol](https://github.com/0xPolygonHermez/zkevm-contracts/blob/main/contracts/PolygonZkEVMBridge.sol) contract when `claimMessage()` is called when tokens are deposited to ZkEVM.
80+
During a deposit to zkEVM, the [PolygonZkEvmBridge.sol](https://github.com/0xPolygonHermez/zkevm-contracts/blob/main/contracts/PolygonZkEVMBridge.sol) contract calls the `onMessageReceived()` function when `claimMessage()` is invoked.
8181

8282
### From Ethereum → zkEVM
8383

84+
!!! warning
85+
86+
It is assumed that the token being bridged is native to the root chain.
87+
8488
1. Deploy your adapter contracts on both the root chain and the child chain. (Note the address, you’ll need it later!)
8589
2. Approve the tokens to be transferred by calling the `approve()` function (on the root token) with the address of the `originChainBridgeAdapter` and the token amount, as arguments.
8690
3. Proceed to call `bridgeToken()` while using as arguments: the recipient, amount, and setting `forceUpdateGlobalExitRoot` to `true` on the `originChainBridgeAdapter` in the root chain (i.e., Ethereum).
87-
4. Get the Merkle proof for this bridge transaction using the [proof api](https://proof-generator.polygon.technology/api/zkevm/testnet/merkle-proof?net_id=0&deposit_cnt=).
91+
4. Get the Merkle proof for this bridge transaction using the [proof API](https://proof-generator.polygon.technology/api/zkevm/testnet/merkle-proof?net_id=0&deposit_cnt=).
8892
5. Proceed to call `claimMessage()` with the respective arguments on the `PolygonZkEVMBridge.sol` contract in the child chain (i.e., zkEVM).
8993

9094
The bridge will call the `onMessageReceived` function in the `WrapperChainBridgeAdapter` contract. Which should ideally have the logic to mint wrapped tokens to the recipient.
9195

92-
Note: It is assumed, in the above steps, that the token being bridged is native to the root chain.
93-
9496
### From zkEVM → Ethereum
9597

98+
!!! warning
99+
100+
It is assumed that the token being bridged is native to the root chain.
101+
96102
1. Deploy your adapter contracts on both the root chain and the child chain. (Note the address, you’ll need it later!)
97103
2. Approve the tokens to be transferred by calling the `approve()` function (on the wrapped token) with the address of the `wrapperChainBridgeAdapter` and the token amount as arguments.
98104
3. Proceed to call `bridgeToken()`, using as arguments: the recipient, amount, and setting `forceUpdateGlobalExitRoot` to `true` on the `WrapperChainBridgeAdapter` in the child chain (i.e., zkEVM). Ideally, this function should have the logic to burn the wrapped tokens.
99-
4. Get the Merkle proof for this bridge transaction using the [proof api](https://proof-generator.polygon.technology/api/zkevm/testnet/merkle-proof?net_id=0&deposit_cnt=).
105+
4. Get the Merkle proof for this bridge transaction using the [proof API](https://proof-generator.polygon.technology/api/zkevm/testnet/merkle-proof?net_id=0&deposit_cnt=).
100106
5. Proceed to call `claimMessage()` with the respective arguments on the `PolygonZkEVMBridge.sol` contract in the root chain (i.e., Ethereum).
101107

102108
The bridge will call the `onMessageReceived` function in the `OriginChainBridgeAdapter` contract. Which should Ideally have the logic to mint unwrapped tokens to the recipient.
103109

104-
Note: It is assumed, in the above steps, that the token being bridge is native to the root chain.
110+
## Listing tokens in Bridge UI
105111

106-
## How to list my token in the BridgeUI?
112+
!!! tip
107113

108-
Note that it is important to follow standardizations for easy listing.
114+
Note that it is important to follow [standardizations](#standardizations) for easy listing.
109115

110-
1. Add your token to this list [https://github.com/maticnetwork/polygon-token-list/blob/dev/src/tokens/zkevmPopularTokens.json]
116+
1. Add your token to this [token list on GitHub](https://github.com/maticnetwork/polygon-token-list/blob/dev/src/tokens/zkevmPopularTokens.json).
111117

112118
Example:
113119

@@ -130,13 +136,13 @@ Note that it is important to follow standardizations for easy listing.
130136
},
131137
```
132138
133-
!!!Note
139+
!!! note "Setting the correct network ID"
134140
135-
If the token is ethereum native then `originTokenNetwork` should be `0`. If the token is zkEVM native, then `originTokenNetwork` should be `1`. Similarly for the `wrappedTokenNetwork`.
141+
If the token is Ethereum native, then `originTokenNetwork` should be `0`. If the token is zkEVM native, then `originTokenNetwork` should be `1`. The same rule applies for the `wrappedTokenNetwork` field.
136142
137-
2. Raise a PR 🚀
143+
2. Raise a PR 🚀.
138144
139-
## How to use Matic.js to bridge using adapter contracts?
145+
## Using Matic.js to bridge using adapter contracts
140146
141147
Deploy your `OriginChainBridgeAdapt` and `WrapperChainBridgeAdapter`.
142148
@@ -149,7 +155,7 @@ Make sure you are using `matic.js version > 3.6.4`.
149155
*await* client.init({})
150156
```
151157
152-
- Create an ERC-20 token instance which you would like to bridge,
158+
- Create an ERC20 token instance which you would like to bridge,
153159
154160
```jsx
155161
*const* erc20Token = client.erc20("<tokenAddress>", "<isRootChain>", "<bridgeAdapterAddress>");
@@ -165,7 +171,7 @@ Make sure you are using `matic.js version > 3.6.4`.
165171
console.log("Transaction Hash", txHash);
166172
```
167173
168-
2. **Claim Deposit**
174+
2. **Claim deposit**
169175
170176
```jsx
171177
const claimTx = await erc20.customERC20DepositClaim("<deposit tx hash>");
@@ -183,7 +189,7 @@ Make sure you are using `matic.js version > 3.6.4`.
183189
console.log("Transaction Hash", txHash);
184190
```
185191
186-
2. **Claim Deposit**
192+
2. **Claim withdrawal**
187193
188194
```jsx
189195
const claimTx = await erc20.customERC20WithdrawExit("<withdraw tx hash>");
@@ -196,7 +202,7 @@ Make sure you are using `matic.js version > 3.6.4`.
196202
197203
Below we provide the two basic functions used for _error passing_ in each of the two directions: L1 --> L2 and L2 --> L1.
198204
199-
- From root to child (L1 --> L2)
205+
### Root to child (L1 L2)
200206
201207
```jsx
202208
const bridgeTx = zkEvmClient.rootChainBridge.bridgeMessage(
@@ -222,10 +228,10 @@ const claimTx = zkEvmClient.childChainBridge.claimMessage(
222228
option: ITransactionOption
223229
);
224230
225-
// proof can be found from the proof gen API
231+
// proof can be fetched from the proof gen API
226232
```
227233

228-
- From child to root (L2 --> L1)
234+
### Child to root (L2 L1)
229235

230236
```jsx
231237
const bridgeTx = zkEvmClient.childChainBridge.bridgeMessage(
@@ -251,5 +257,5 @@ const claimTx = zkEvmClient.rootChainBridge.claimMessage(
251257
option: ITransactionOption
252258
);
253259

254-
// proof can be found from the proof gen API
260+
// proof can be fetched from the proof gen API
255261
```

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ nav:
455455
- zkEVM:
456456
- zkEVM client: tools/matic-js/zkevm/initialize.md
457457
- ERC20: tools/matic-js/zkevm/erc20.md
458-
- Message: tools/matic-js/zkevm/message.md
458+
- Custom contracts and bridging: tools/matic-js/zkevm/custom-contract-bridging.md
459459
- Common methods: tools/matic-js/zkevm/common-methods.md
460460
- Storage:
461461
- IPFS: tools/storage/ipfs.md

0 commit comments

Comments
 (0)