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
USDC is one of the most bridged assets across the crypto ecosystem, and USDC is often bridged to new chains prior to any action from Circle. This can create a challenge when bridged USDC achieves substantial marketshare, but native USDC (issued by Circle) is preferred by the ecosystem, leading to fragmentation between multiple representations of USDC. Circle introduced the [Bridged USDC Standard](https://www.circle.com/en/bridged-usdc) to ensure that chains can easily deploy a form of USDC that is capable of being upgraded in-place by Circle to native USDC, if and when appropriate, and prevent the fragmentation problem.
4
4
5
-
Bridged USDC Standard for the OP Stack allows for an efficient and modular solution for expanding the Bridged USDC Standard across the Superchain ecosystem.
6
-
7
-
Chain operators can use the Bridged USDC Standard for the OP Stack to get bridged USDC on their OP Stack chain while also providing the optionality for Circle to seamlessly upgrade bridged USDC to native USDC and retain existing supply, holders, and app integrations.
5
+
Bridged USDC Standard for the OP Stack allows for an efficient and modular solution for expanding the Bridged USDC Standard across the Superchain ecosystem.
8
6
7
+
Chain operators can use the Bridged USDC Standard for the OP Stack to get bridged USDC on their OP Stack chain while also providing the optionality for Circle to seamlessly upgrade bridged USDC to native USDC and retain existing supply, holders, and app integrations.
9
8
10
9
## Contracts
10
+
11
11
> :exclamation:`L1OpUSDCFactory.sol` has been deployed to the following addresses:
_`L1OpUSDCFactory.sol`_ - Factory contract to deploy and setup the `L1OpUSDCBridgeAdapter` contract on L1. Precalculates the addresses of the L2 deployments and triggers their deployment, by sending a transaction to L2.
25
29
26
30
_`L2OpUSDCDeploy.sol`_ - One time use deployer contract deployed from the L1 factory through a cross-chain deployment. Used as a utility contract for deploying the L2 USDC Proxy, and `L2OpUSDCBridgeAdapter` contract, all at once in its constructor.
@@ -40,6 +44,7 @@ _`L2OpUSDCBridgeAdapter`_ - Contract that allows for the transfer of USDC from t
40
44
For a user to make a deposit, the process is the following:
41
45
42
46
### Deposits
47
+
43
48
1. Users approve the `L1OpUSDCBridgeAdapter` to spend USDC.
44
49
2. Users proceed to deposit USDC by calling the contract.
45
50
3. The `L1OpUSDCBridgeAdapter` sends the message to the appointed CrossDomainMessenger.
@@ -49,6 +54,7 @@ For a user to make a deposit, the process is the following:
49
54
Similarly, for withdrawals:
50
55
51
56
### Withdrawals
57
+
52
58
1. Users send `bridgedUSDC` to the `L2OpUSDCBridgeAdapter`.
53
59
2. The `L2OpUSDCBridgeAdapter` burns the token.
54
60
3. The `L2OpUSDCBridgeAdapter` sends the message to the appointed CrossDomainMessenger.
Bridged USDC representation involves locking liquidity in the home chain and minting tokens on the destination chain. Migrating to native means transferring ownership of the bridged USDC to Circle and burning the locked funds on the home chain to consolidate liquidity across chains, making the bridged USDC canonical. ⚠️ This process is irreversible and will deprecate the adapters ⚠️.
74
+
75
+
### Step by step
76
+
77
+
1. Call `migrateToNative()` on L1
78
+
- Params
79
+
-`_roleCaller` The address that will be allowed to transfer the USDC roles on the destination chain.
80
+
-`_burnCaller` The address that will be allowed to call this contract to burn the USDC tokens
81
+
-`_minGasLimitReceiveOnL2` Minimum gas limit that the message for the`receiveMigrateToNative` call can be executed with on L2
82
+
-`_minGasLimitSetBurnAmount` Minimum gas limit that the message can be executed with to set the burn amount (This param is set on L2, and it represents the `minGasLimit` for when the withdrawal is finalized on L1)
83
+
- Effects
84
+
- Sets the `burnCaller` variable
85
+
- Changes the `messengerStatus` variable locking this function to avoid calling this process twice and locking `sendMessage`, `stopMessaging` and `resumeMessaging`.
86
+
- Enables `setBurnAmount` that is only callable by the Linked Adapter.
87
+
- Sends message to call `receiveMigrateToNative` on destination chain.
88
+
- ⚠️ Note: Once this step is executed the bridges can’t be unpaused.
89
+
2. Call `receiveMigrateToNative` on L2 (Automatically relayed)
90
+
91
+
- Params
92
+
-`_roleCaller` The address that will be allowed to transfer the USDC roles on the destination chain.
93
+
-`_setBurnAmountMinGasLimit` Minimum gas limit that the setBurnAmount message can be executed on L1
94
+
- Effects
95
+
- Changes the `messengerStatus` variable locking `receiveStopMessaging`, `receiveResumeMessaging`, and `sendMessage`. Modifying `receiveMessage` behavior to return pending messages to L1 that could arrive after the migration. Also, modifies `withdrawLockedFunds` behavior to send the locked funds to the spender through a message to L1.
96
+
- Removes L2 Adapter as minter form USDC contract.
97
+
- Calculates the amount of USDC that is going to be burned on origin.
98
+
- Sends message to call `setBurnAmount` on origin chain.
99
+
⚠️ Note: Messages sent from L2 to L1 are not automatically relayed, so this message needs to be manually treated as the [Optimism Docs](https://docs.optimism.io/app-developers/bridging/messaging#for-l2-to-l1-transactions) suggest, first submit the transaction proof on the portal and then wait 7 days to finalize the withdrawal.
100
+
⚠️ Note: User friendly interface to submit the transaction proof: [Superchain Relayer](https://console.optimism.io/relayer)
101
+
- Note: This function is not blocked to be triggered again from L1 if a withdrawal for `setBurnAmount` was not yet finalized.
102
+
103
+
***
104
+
105
+
After this point L1 (burn locked USDC) and L2 sequences (transfer bridged USDC roles) can be called in any order.
106
+
107
+
***
108
+
109
+
- L2 Sequence
110
+
1. Call `transferUSDCRoles`
111
+
- Params
112
+
-`_owner` The address to transfer ownership to
113
+
- Effects
114
+
- Transfers the ownership of the Bridged USDC contract to the `_owner`
115
+
- Transfer the admin rights of the Bridged USDC proxy to the `msg.sender` (a.k.a. `roleCaller`)
116
+
- L1 Sequence (MUST wait at least 7 days to execute this sequence).
117
+
1. Call `setBurnAmount`
118
+
- Params
119
+
-`_amount` The amount of USDC tokens that will be burned
120
+
- Effects
121
+
- Sets `burnAmount` variable that will be later used by `burnLockedUSDC`
122
+
- Changes the `messengerStatus` to `Deprecated` disabling all the function related to migration and sending messages.
123
+
- ⚠️ Note: After this point the `burnCaller` and the `roleCaller` are not longer updatable
124
+
2. Call `burnLockedUSDC`
125
+
- Effects
126
+
- Burns the USDC locked in the adapter based on the `burnAmount` variable or the contract balance.
127
+
- Reset `burnAmount` and `burnCaller` variables, to avoid calling the function more than once.
128
+
-`receiveWithdrawLockedFundsPostMigration` is enabled, this function handles the messages that were in-flight during the migration and were sent back from L2 by transferring the locked USDC to the user.
129
+
130
+
### Contracts behavior after migration
131
+
132
+
The following functions will revert or won't be callable after migration:
133
+
134
+
-`L1OpUSDCBridgeAdapter`
135
+
-`migrateToNative`
136
+
-`setBurnAmount`
137
+
-`burnLockedUSDC`
138
+
-`stopMessaging`
139
+
-`resumeMessaging`
140
+
-`sendMessage`
141
+
-`L2OpUSDCBridgeAdapter`
142
+
-`receiveMigrateToNative`
143
+
-`transferUSDCRoles`
144
+
-`receiveStopMessaging`
145
+
-`receiveResumeMessaging`
146
+
-`sendMessage`
147
+
-`callUsdcTransaction`
148
+
149
+
The following functions will be callable after migration:
150
+
151
+
-`L1OpUSDCBridgeAdapter`
152
+
-`receiveMessage`
153
+
-`receiveWithdrawLockedFundsPostMigration`
154
+
-`withdrawLockedFunds`
155
+
-`L2OpUSDCBridgeAdapter`
156
+
Note: Since the adapter is deprecated these functions will handle the messages that were in-flight during the migration and will sent locked funds (if the address was blocked by Circle at the moment of the relaying the message and then unblocked) back to the spender through a message to L1.
The referenced implementation for the OP Stack has undergone audits from [Spearbit](https://spearbit.com/) and is recommended for production use. The audit report is available [here](./audits/spearbit.pdf).
68
167
69
168
## Setup
@@ -142,12 +241,13 @@ ETHEREUM_RPC=
142
241
```
143
242
144
243
After all these variables are set, navigate to the `script/mainnet/Deploy.s.sol` file and edit the following lines with your desired configuration, we add a sanity check that will revert if you forget to change this value:
244
+
145
245
```solidity
146
246
// NOTE: We have these hardcoded to default values, if used in product you will need to change them
@@ -157,21 +257,25 @@ After all these variables are set, navigate to the `script/mainnet/Deploy.s.sol`
157
257
```
158
258
159
259
Then run this command to test:
260
+
160
261
```bash
161
262
yarn script:deploy
162
263
```
163
264
164
265
And when you are ready to deploy to mainnet, run:
266
+
165
267
```bash
166
268
yarn script:deploy:broadcast
167
269
```
168
270
169
271
In addittion, the L1OpUSDCFactory deployment command is:
272
+
170
273
```bash
171
274
yarn deploy:mainnet:factory
172
275
```
173
276
174
277
And when you are ready to deploy to mainnet, run:
278
+
175
279
```bash
176
280
yarn deploy:mainnet:factory:broadcast
177
281
```
@@ -193,9 +297,11 @@ Alternatively, you can run the deployment scripts over your desired testent by r
193
297
```
194
298
195
299
## Migrating to Native USDC
196
-
> ⚠️ Migrating to native USDC is a manual process that requires communication with Circle, this section assumes both parties are ready to migrate to native USDC. Please review [Circle’s documentation](https://www.circle.com/blog/bridged-usdc-standard) to learn about the process around Circle obtaining ownership of the Bridged USDC Standard token contract.
300
+
301
+
> ⚠️ Migrating to native USDC is a manual process that requires communication with Circle, this section assumes both parties are ready to migrate to native USDC. Please review [Circle’s documentation](https://www.circle.com/blog/bridged-usdc-standard) to learn about the process around Circle obtaining ownership of the Bridged USDC Standard token contract.
197
302
198
303
In order to migrate to native USDC, you will need to fill out these variables in the `.env` file:
304
+
199
305
```python
200
306
# The address of the L1 opUSDC bridge adapter
201
307
L1_ADAPTER=
@@ -208,19 +314,21 @@ BURN_CALLER
208
314
```
209
315
210
316
After all these variables are set, run this command to test:
317
+
211
318
```bash
212
319
yarn script:migrate
213
320
```
214
321
215
322
And when you are ready to migrate to native USDC, run:
323
+
216
324
```bash
217
325
yarn script:migrate:broadcast
218
326
```
219
327
220
328
### What will Circle need at migration?
221
329
222
330
#### Circle will need the metadata from the original deployment of the USDC implementation that was used
223
-
331
+
224
332
To do this you will need to go back to the `stablecoin-evm` github repo that the implementation was deployed from in order to extract the raw metadata from the compiled files. The compiled files are usually found in the `out/` or `artifacts/` folders. To extract the raw metadata you can run a command like this:
225
333
226
334
```bash
@@ -234,6 +342,7 @@ You will need to do this for both the token contract and any external libraries
234
342
The primary license for the boilerplate is MIT, see [`LICENSE`](https://github.com/defi-wonderland/opUSDC/blob/main/LICENSE)
235
343
236
344
## Bridged USDC Standard Factory Disclaimer
237
-
This software is provided “as is,” without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
238
345
239
-
Please review [Circle’s disclaimer](https://github.com/circlefin/stablecoin-evm/blob/master/doc/bridged_USDC_standard.md#for-more-information) for the limitations around Circle obtaining ownership of the Bridged USDC Standard token contract.
346
+
This software is provided “as is,” without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
347
+
348
+
Please review [Circle’s disclaimer](https://github.com/circlefin/stablecoin-evm/blob/master/doc/bridged_USDC_standard.md#for-more-information) for the limitations around Circle obtaining ownership of the Bridged USDC Standard token contract.
0 commit comments