|
| 1 | +# How to add ZamaOFT on BNB Chain |
| 2 | + |
| 3 | +Currently, we have `ZamaERC20` and `ZamaOFTAdapter` deployed on Ethereum mainnet, and `ZamaOFT` deployed on Gateway mainnet. The `ZamaOFTAdapter` contract's owner and delegate are already setup to be an Aragon DAO contract. |
| 4 | + |
| 5 | +The goal of this runbook is to guide you step by step on how to deploy a `ZamaOFT` instance on BNB Chain, and how to wire it to the already deployed `ZamaOFTAdapter` on Ethereum, via the Aragon DAO. We only add a single bidirectional pathway: `BNB <-> Ethereum` (i.e there is no step to wire `BNB <-> Gateway`). |
| 6 | + |
| 7 | +## Step 1 : Recreating deployments |
| 8 | + |
| 9 | +The first step is to recreate deployments artifacts for the already deployed contract. This is inspired from the official [LayerZero V2 docs](https://docs.layerzero.network/v2/tools/create-lz-oapp-cli/recreating-deployments). |
| 10 | + |
| 11 | +First, run `pnpm install` and setup your `.env` file with all required values (see [`.env.example`](./.env.example)). |
| 12 | + |
| 13 | +Create a `/deployments` folder in the root of the [/token] directory. The eventual structure would look like this: |
| 14 | + |
| 15 | +``` |
| 16 | +/deployments |
| 17 | + /ethereum-mainnet |
| 18 | + .chainId |
| 19 | + ZamaERC20.json |
| 20 | + ZamaOFTAdapter.json |
| 21 | + /gateway-mainnet |
| 22 | + .chainId |
| 23 | + ZamaOFT.json |
| 24 | +``` |
| 25 | + |
| 26 | +`/deployments/ethereum-mainnet/.chainId` - this file should contain the chain ID for the network, i.e `1` for Ethereum mainnet. |
| 27 | + |
| 28 | +`/deployments/ethereum-mainnet/ZamaERC20.json` - for now, the only key that is necessary in the JSON file is `address`, note that the `abi` key is also necessary but this will be added via a script at the end of current step. Insert your ERC20 address into the address field. |
| 29 | + |
| 30 | +``` |
| 31 | +{ |
| 32 | + "address": "<ZamaERC20Address>" |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +Follow the same similar steps for the remaining files, i.e `/deployments/ethereum-mainnet/ZamaOFTAdapter.json`, `/deployments/gateway-mainnet/.chainId` and `/deployments/gateway-mainnet/ZamaOFT.json`. |
| 37 | + |
| 38 | +Then modifiy `hardhat.config.ts` by replacing `0x0` by the `ZamaERC20` address under the `ethereum-mainnet` field: |
| 39 | + |
| 40 | +```typescript |
| 41 | +oftAdapter: { |
| 42 | + tokenAddress: '0x0', // Replace `0x0` with the address of the ERC20 token you want to adapt to the OFT functionality. |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +Then, run `npx hardhat compile` to ensure relevant artifacts that are required by Hardhat helper tasks involving the EVM OFT are generated. |
| 47 | + |
| 48 | +Finally, in order to copy all the `abi` values in the `deployments` artifacts from the compilation artifacts located in `artifacts` folder, just run: |
| 49 | + |
| 50 | +``` |
| 51 | +npx ts-node scripts/copyAbiToDeployments.ts |
| 52 | +``` |
| 53 | + |
| 54 | +## Step 2 : Deploy ZamaOFT on BNB Chain |
| 55 | + |
| 56 | +Run `npx hardhat deploy --network bnb-mainnet --tags ZamaOFT` command. |
| 57 | + |
| 58 | +You can then verify the contract on bscscan by running `pnpm verify:etherscan:bnb:mainnet`. |
| 59 | + |
| 60 | +## Step 3 : Wire the BNB OFT to Ethereum OFTAdapter |
| 61 | + |
| 62 | +This can be done easily, since your deployer hot wallet is still the owner and delegate of the `ZamaOFT` instance on BNB Chain - later, after full wiring on both chains, ownership and delegate roles should be transferred to governance on BNB Chain, which should be a Safe multisig deployed on BNB mainnet. |
| 63 | + |
| 64 | +You just have to run: |
| 65 | + |
| 66 | +```npx hardhat lz:oapp:wire --oapp-config layerzero.config.mainnet.bnb.ts --skip-connections-from-eids <EID_ETHEREUM_V2_MAINNET>,<EID_ZAMA_V2_MAINNET>``` |
| 67 | + |
| 68 | +In previous command, replace `<EID_ETHEREUM_V2_MAINNET>` by `30101` and `EID_ZAMA_V2_MAINNET` by `30397`. |
| 69 | + |
| 70 | +## Step 4 : Wire the Ethereum OFTAdapter to BNB OFT |
| 71 | + |
| 72 | +This step is more complex, since the delegate of the OFTAdapter is an Aragon DAO, i.e it requires creating, approving and executing a DAO proposal via the Aragon DAO. |
| 73 | + |
| 74 | +First, create an `ethereum-wiring.json` file containing the different transactions needed to be done, by running: |
| 75 | + |
| 76 | +``` |
| 77 | +npx hardhat lz:oapp:wire --oapp-config layerzero.config.mainnet.bnb.ts --output-filename ethereum-wiring.json |
| 78 | +``` |
| 79 | + |
| 80 | +When running previous command, select **no** when requested if you would you like to submit the required transactions (otherwise it would fail anyways). You should now have generated a new `ethereum-wiring.json` file in the root of the directory. |
| 81 | + |
| 82 | +Now, run: |
| 83 | + |
| 84 | +``` |
| 85 | +npx ts-node scripts/convertToAragonProposal.ts ethereum-wiring.json aragonProposal.json |
| 86 | +``` |
| 87 | + |
| 88 | +This will convert the `ethereum-wiring.json` file to a new `aragonProposal.json` which could be directly uploaded inside the Aragon App UI, when creating an Aragon proposal, to streamling the process. |
| 89 | + |
| 90 | +More precisely, in Aragon App, when you reach "Step 2 of 3" of proposal creation, click on the `Upload` button there, in select the newly created `aragonProposal.json` file to upload it and create the wiring proposal on Ethereum. |
| 91 | + |
| 92 | + |
| 93 | + |
| 94 | +After voting and execution of the wiring proposal, your OFT is now successfully setup. |
| 95 | + |
| 96 | +## Step 5 : Test OFT transfers |
| 97 | + |
| 98 | +You can test that the OFT BNB has been correctly wired by sending some amount of tokens from Ethereum to BNB Chain, and the other way around, by using commands such as: |
| 99 | + |
| 100 | +``` |
| 101 | +npx hardhat lz:oft:send --src-eid 30101 --dst-eid 30102 --amount 0.1 --to <RECEIVER_ADDRESS> --oapp-config layerzero.config.mainnet.bnb.ts |
| 102 | +``` |
| 103 | + |
| 104 | +to send 0.1 Zama token from Ethereum to BNB mainnet, and: |
| 105 | + |
| 106 | +``` |
| 107 | +npx hardhat lz:oft:send --src-eid 30102 --dst-eid 30101 --amount 0.1 --to <RECEIVER_ADDRESS> --oapp-config layerzero.config.mainnet.bnb.ts |
| 108 | +``` |
| 109 | + |
| 110 | +to send 0.1 Zama token from BNB mainnet to Ethereum. |
| 111 | + |
| 112 | +## Step 6 : transfer delegate and owner |
| 113 | + |
| 114 | +Once the transfer tests are successful, don't forget to transfer the delegate and owners roles of the BNB OFT instance to governance (i.e BNB Safe Multisig). |
| 115 | + |
| 116 | +Those `cast` commands are helpful for transferring roles: |
| 117 | + |
| 118 | +To get current OFT owner address: |
| 119 | + |
| 120 | +``` |
| 121 | +cast call <BNB_OFT_ADDRESS> "owner()(address)" --rpc-url <BNB_RPC_URL> |
| 122 | +``` |
| 123 | + |
| 124 | +To get current `EndpointV2` address: |
| 125 | + |
| 126 | +``` |
| 127 | +cast call <BNB_OFT_ADDRESS> "endpoint()(address)" --rpc-url <BNB_RPC_URL> |
| 128 | +``` |
| 129 | + |
| 130 | +To get current delegate: |
| 131 | + |
| 132 | +``` |
| 133 | +cast call <LZ_ENDPOINT_V2_ADDRESS> "delegates(address)(address)" <BNB_OFT_ADDRESS> --rpc-url <BNB_RPC_URL> |
| 134 | +``` |
| 135 | + |
| 136 | +To transfer delegate role: |
| 137 | + |
| 138 | +``` |
| 139 | +cast send <BNB_OFT_ADDRESS> "setDelegate(address)" <BNB_SAFE_ADDRESS> --rpc-url <BNB_RPC_URL> --private-key <DEPLOYER_PRIVATE_KEY> |
| 140 | +``` |
| 141 | + |
| 142 | +To transfer owner role: |
| 143 | + |
| 144 | +``` |
| 145 | +cast send <BNB_OFT_ADDRESS> "transferOwnership(address)" <BNB_SAFE_ADDRESS> --rpc-url <BNB_RPC_URL> --private-key <DEPLOYER_PRIVATE_KEY> |
| 146 | +``` |
0 commit comments