You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/tools/matic-js/zkevm/custom-contract-bridging.md
+60-54Lines changed: 60 additions & 54 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff 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.
2
2
3
-
We refer to Ethereum as the _root_ chain and zkEVM as the _child_ chain.
3
+
!!! info "Terminology"
4
4
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.
6
6
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.
8
8
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.
10
10
11
11
These functionalities could include: blacklisting, putting a cap on minting, or any sound auxiliary functionality.
12
12
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.
14
14
15
-
However, for the sake of maintaining consistency among wrapped tokens, strict standards must be followed when extending their functionalities.
15
+
## Adapter contracts
16
16
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).
34
18
35
19
Ideally, the following adapter contracts are expected,
36
20
37
21
1.`OriginChainBridgeAdapter`
38
22
2.`WrapperChainBridgeAdapter`
39
23
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)).
41
25
42
26
```solidity
43
27
function bridgeToken(
@@ -53,61 +37,83 @@ function onMessageReceived(
53
37
) external payable {}
54
38
```
55
39
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.
57
41
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
59
43
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.
61
55
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.
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.
69
69
70
70
### OriginChainBridgeAdapter
71
71
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.
73
73
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.
75
75
76
76
### WrapperChainBridgeAdapter
77
77
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.
79
79
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.
81
81
82
82
### From Ethereum → zkEVM
83
83
84
+
!!! warning
85
+
86
+
It is assumed that the token being bridged is native to the root chain.
87
+
84
88
1. Deploy your adapter contracts on both the root chain and the child chain. (Note the address, you’ll need it later!)
85
89
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.
86
90
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=).
88
92
5. Proceed to call `claimMessage()` with the respective arguments on the `PolygonZkEVMBridge.sol` contract in the child chain (i.e., zkEVM).
89
93
90
94
The bridge will call the `onMessageReceived` function in the `WrapperChainBridgeAdapter` contract. Which should ideally have the logic to mint wrapped tokens to the recipient.
91
95
92
-
Note: It is assumed, in the above steps, that the token being bridged is native to the root chain.
93
-
94
96
### From zkEVM → Ethereum
95
97
98
+
!!! warning
99
+
100
+
It is assumed that the token being bridged is native to the root chain.
101
+
96
102
1. Deploy your adapter contracts on both the root chain and the child chain. (Note the address, you’ll need it later!)
97
103
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.
98
104
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=).
100
106
5. Proceed to call `claimMessage()` with the respective arguments on the `PolygonZkEVMBridge.sol` contract in the root chain (i.e., Ethereum).
101
107
102
108
The bridge will call the `onMessageReceived` function in the `OriginChainBridgeAdapter` contract. Which should Ideally have the logic to mint unwrapped tokens to the recipient.
103
109
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
105
111
106
-
## How to list my token in the BridgeUI?
112
+
!!! tip
107
113
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.
109
115
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).
111
117
112
118
Example:
113
119
@@ -130,13 +136,13 @@ Note that it is important to follow standardizations for easy listing.
130
136
},
131
137
```
132
138
133
-
!!!Note
139
+
!!! note "Setting the correct network ID"
134
140
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.
136
142
137
-
2. Raise a PR 🚀
143
+
2. Raise a PR 🚀.
138
144
139
-
## How to use Matic.js to bridge using adapter contracts?
145
+
## Using Matic.js to bridge using adapter contracts
140
146
141
147
Deploy your `OriginChainBridgeAdapt` and `WrapperChainBridgeAdapter`.
142
148
@@ -149,7 +155,7 @@ Make sure you are using `matic.js version > 3.6.4`.
149
155
*await* client.init({})
150
156
```
151
157
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,
0 commit comments