-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(protocol): USDCAdaptor deployment script + documentation (#15478)
Co-authored-by: David <[email protected]>
- Loading branch information
1 parent
ea2d929
commit f4b0955
Showing
3 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Taiko native vs. wrapped token bridging | ||
|
||
![Wrapped_vs_Native](./native_bridge/native_support.png "Wrapped vs. Native bridging") | ||
|
||
Taiko's briding concept is a lock-and-mint type. It simply means (the red path above) on the canonical chain we take custody of the assets and on the destination chain we mint the wrapped counterpart. When someone wants to bridge back (from destination to canonical) it will first burn the tokens, then release the funds on the canonical chain. | ||
|
||
But there might be some incentives (e.g.: adoption, liquidity fragmentation, etc.) when deploying a native token on the destination chain is beneficial. For this reason Taiko introduced the possibilty of deploying the canonical assets (together with all their sub/parent/proxy contracts) and plug it into our ERC20Vault via adaptors (green path). | ||
|
||
Important to note that while wrapped asset briding is 'automatical', the native one requires the willingness and efforts from Taiko side (and maybe also original token issuer green light to recognise officially as "native"), to support that type of asset-transfer. | ||
|
||
## Howto | ||
|
||
There are some steps to do in order to facilitate native token bridging. In the next steps, here is a TLDR breakdown how we do it with USDC. | ||
|
||
1. Deploy the same (bytecode equivalent) ERC-20 token on L2. An example of the contracts + deployments can be found in our [USDC repo](https://github.com/taikoxyz/USDC). | ||
2. Deploy adaptor (e.g.: [USDC adaptor](../contracts/tokenvault/adaptors/USDCAdaptor.sol)). As this will serve as the plug-in to our `ERC20Vault` for custom (native) tokens. This adaptor serves multiple purposes. It is also a wrapper around the native token in a way - that it matches our conform `ERC20Vault` interfaces so that we can be sure any kind of native ERC-20 can be supported on L2. Also can handle custom logic required by the native asset (roles handling, specific logic, etc.). | ||
3. Transfer the ownership (if not already owned by) to `ERC20Vault` owner since those 2 have to be owned by the same address. (!IMPORTANT! Not the token owned by the same owner, but the token adpter! USDC owner will still be Circle on L2.) | ||
4. Since our bridge is permissionless, there might have been some USDC bridge operations in the past. It would mean, there is already an existing `BridgedUSDC` on our L2. To overcome liquidity fragmentation, we (Taiko) need to call `ERC20Vault` `changeBridgedToken()` function with the appropriate parameters. This way the "old" `BridgedUSDC` can be migrated to this new native token and the bridging operation will mint into the new token frm that point on. | ||
|
||
The above steps (2. - 4.) is incorporated into the script [DeployUSDCAdaptor.s.sol](../script/DeployUSDCAdaptor.s.sol). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// SPDX-License-Identifier: MIT | ||
// _____ _ _ _ _ | ||
// |_ _|_ _(_) |_____ | | __ _| |__ ___ | ||
// | |/ _` | | / / _ \ | |__/ _` | '_ (_-< | ||
// |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/ | ||
// | ||
// Email: [email protected] | ||
// Website: https://taiko.xyz | ||
// GitHub: https://github.com/taikoxyz | ||
// Discord: https://discord.gg/taikoxyz | ||
// Twitter: https://twitter.com/taikoxyz | ||
// Blog: https://mirror.xyz/labs.taiko.eth | ||
// Youtube: https://www.youtube.com/@taikoxyz | ||
|
||
pragma solidity 0.8.20; | ||
|
||
import "../contracts/tokenvault/adaptors/USDCAdaptor.sol"; | ||
import "../contracts/tokenvault/ERC20Vault.sol"; | ||
import "../test/DeployCapability.sol"; | ||
|
||
/// @title DeployUSDCAdaptor | ||
/// @notice This script deploys the adaptor contract for USDC. | ||
contract DeployUSDCAdaptor is DeployCapability { | ||
address public usdcProxyL2 = vm.envAddress("NATIVE_USDC_PROXY_ON_L2"); | ||
address public usdcProxyL1 = vm.envAddress("NATIVE_USDC_PROXY_ON_L1"); | ||
address public l2SharedAddressManager = vm.envAddress("L2_SHARED_ADDRESS_MANAGER"); | ||
address public erc20Vault = vm.envAddress("ERC20_VAULT_ADDRESS"); | ||
address public erc20VaultOwner = vm.envAddress("ERC20_VAULT_OWNER"); | ||
|
||
uint256 public deployerPrivKey = vm.envUint("ADAPTOR_DEPLOYER_PRIVATE_KEY"); | ||
uint256 public masterMinterPrivKey = vm.envUint("MASTER_MINTER_PRIVATE_KEY"); | ||
|
||
uint256 public erc20VaultOwnerPrivKey = vm.envUint("ERC20_VAULT_OWNER_PRIVATE_KEY"); | ||
|
||
// Fixed, not changed. (From circle contracts) | ||
// https://holesky.etherscan.io/tx/0xbfb68e7d92506498553e09ee22aba0adc23401108d508fc92f56da5e42ffc828 | ||
bytes4 public configureMinterSelector = 0x4e44d956; | ||
|
||
error CANNOT_CONFIGURE_MINTER(); | ||
error CANNOT_CHANGE_BRIDGED_TOKEN(); | ||
|
||
function setUp() external { } | ||
|
||
function run() external { | ||
require(deployerPrivKey != 0, "invalid deplyoer priv key"); | ||
require(masterMinterPrivKey != 0, "invalid master minter priv key"); | ||
vm.startBroadcast(deployerPrivKey); | ||
// Verify this contract after deployment (!) | ||
address adaptorProxy = deployProxy({ | ||
name: "usdc_adaptor", | ||
impl: address(new USDCAdaptor()), | ||
data: abi.encodeCall(USDCAdaptor.init, (l2SharedAddressManager, IUSDC(usdcProxyL2))) | ||
}); | ||
|
||
USDCAdaptor(adaptorProxy).transferOwnership(erc20VaultOwner); | ||
|
||
vm.stopBroadcast(); | ||
|
||
// Grant the adaptor the minter role by master minter | ||
vm.startBroadcast(masterMinterPrivKey); | ||
(bool success, bytes memory retVal) = address(usdcProxyL2).call( | ||
abi.encodeWithSelector(configureMinterSelector, adaptorProxy, type(uint256).max) | ||
); | ||
|
||
if (!success) { | ||
console2.log("Error is:"); | ||
console2.logBytes(retVal); | ||
revert CANNOT_CONFIGURE_MINTER(); | ||
} | ||
|
||
vm.stopBroadcast(); | ||
|
||
vm.startBroadcast(erc20VaultOwnerPrivKey); | ||
ERC20Vault.CanonicalERC20 memory canonicalToken = ERC20Vault.CanonicalERC20({ | ||
chainId: 17_000, // On mainnet, Ethereum chainID | ||
addr: usdcProxyL1, // On mainnet, USDC contract address | ||
decimals: 6, | ||
symbol: "USDC", | ||
name: "USD Coin" | ||
}); | ||
|
||
(success, retVal) = erc20Vault.call( | ||
abi.encodeWithSelector( | ||
ERC20Vault.changeBridgedToken.selector, canonicalToken, adaptorProxy | ||
) | ||
); | ||
|
||
if (!success) { | ||
console2.log("Error is:"); | ||
console2.logBytes(retVal); | ||
revert CANNOT_CHANGE_BRIDGED_TOKEN(); | ||
} | ||
|
||
vm.stopBroadcast(); | ||
} | ||
} |
f4b0955
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
bridge-ui-v2-internal – ./packages/bridge-ui-v2
bridge-ui-v2-internal-taikoxyz.vercel.app
bridge-ui-v2-internal.vercel.app
bridge-ui-v2-internal-git-alpha-6-taikoxyz.vercel.app
f4b0955
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
bridge-ui-v2-a6 – ./packages/bridge-ui-v2
bridge-ui-v2-a6-git-alpha-6-taikoxyz.vercel.app
bridge-ui-v2-a6-taikoxyz.vercel.app
bridge-ui-v2-a6.vercel.app
bridge.katla.taiko.xyz