Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base bridge #115

Merged
merged 4 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 253 additions & 0 deletions abis/0.8.23/OptimismMessenger.json

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions docs/configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,49 @@
"address": "0x670Ac235EE13C0B2a5065282bBB0c61cfB354592"
}
]
},
{
"name": "optimistic",
"chainId": "10",
"contracts": [
{
"name": "OptimismMessenger",
"artifact": "abis/0.8.23/OptimismMessenger.json",
"address": ""
}
]
},
{
"name": "optimisticSepolia",
"chainId": "11155420",
"contracts": [
{
"name": "OptimismMessenger",
"artifact": "abis/0.8.23/OptimismMessenger.json",
"address": "0x670Ac235EE13C0B2a5065282bBB0c61cfB354592"
}
]
},
{
"name": "base",
"chainId": "8453",
"contracts": [
{
"name": "OptimismMessenger",
"artifact": "abis/0.8.23/OptimismMessenger.json",
"address": ""
}
]
},
{
"name": "baseSepolia",
"chainId": "84532",
"contracts": [
{
"name": "OptimismMessenger",
"artifact": "abis/0.8.23/OptimismMessenger.json",
"address": "0xeDd71796B90eaCc56B074C39BAC90ED2Ca6D93Ee"
}
]
}
]
227 changes: 134 additions & 93 deletions scripts/audit_chains/audit_contracts_setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const { ethers } = require("ethers");
const { expect } = require("chai");
const fs = require("fs");

const verifyRepo = false;
const verifySetup = true;

// Custom expect that is wrapped into try / catch block
function customExpect(arg1, arg2, log) {
try {
Expand Down Expand Up @@ -345,7 +348,25 @@ async function checkHomeMediator(chainId, provider, globalsInstance, configContr

// Check AMBContractProxyHomeAddress
const proxyHome = await homeMediator.AMBContractProxyHome();
customExpect(proxyHome, globalsInstance["AMBContractProxyHomeAddress"], log + ", function: AMBContractProxyHomeAddress()");
customExpect(proxyHome, globalsInstance["AMBContractProxyHomeAddress"], log + ", function: AMBContractProxyHome()");
}

// Check OptimismMessenger: chain Id, provider, parsed globals, configuration contracts, contract name
async function checkOptimismMessenger(chainId, provider, globalsInstance, configContracts, contractName, log) {
// Check the bytecode
await checkBytecode(provider, configContracts, contractName, log);

// Get the contract instance
const optimismMessenger = await findContractInstance(provider, configContracts, contractName);

log += ", address: " + optimismMessenger.address;
// Check the foreign governor
const foreignGovernor = await optimismMessenger.foreignGovernor();
customExpect(foreignGovernor, globalsInstance["timelockAddress"], log + ", function: foreignGovernor()");

// Check AMBContractProxyHomeAddress
const proxyHome = await optimismMessenger.CDMContractProxyHome();
customExpect(proxyHome, globalsInstance["L2CrossDomainMessengerAddress"], log + ", function: CDMContractProxyHome()");
}

async function main() {
Expand All @@ -363,123 +384,143 @@ async function main() {

const numChains = configs.length;
// ################################# VERIFY CONTRACTS WITH REPO #################################
// For now gnosis chains are not supported
const networks = {
"mainnet": "etherscan",
"goerli": "goerli.etherscan",
"polygon": "polygonscan",
"polygonMumbai": "testnet.polygonscan"
};

console.log("\nVerifying deployed contracts vs the repo... If no error is output, then the contracts are correct.");

// Traverse all chains
for (let i = 0; i < numChains; i++) {
// Skip gnosis chains
if (!networks[configs[i]["name"]]) {
continue;
}

console.log("\n\nNetwork:", configs[i]["name"]);
const network = networks[configs[i]["name"]];
const contracts = configs[i]["contracts"];

// Verify contracts
for (let j = 0; j < contracts.length; j++) {
console.log("Checking " + contracts[j]["name"]);
const execSync = require("child_process").execSync;
try {
execSync("scripts/audit_chains/audit_repo_contract.sh " + network + " " + contracts[j]["name"] + " " + contracts[j]["address"]);
} catch (error) {
if (verifyRepo) {
// For now gnosis chains are not supported
const networks = {
"mainnet": "etherscan",
"goerli": "goerli.etherscan",
"polygon": "polygonscan",
"polygonMumbai": "testnet.polygonscan",
"optimistic": "optimistic.etherscan"
};

console.log("\nVerifying deployed contracts vs the repo... If no error is output, then the contracts are correct.");

// Traverse all chains
for (let i = 0; i < numChains; i++) {
// Skip gnosis chains
if (!networks[configs[i]["name"]]) {
continue;
}

console.log("\n\nNetwork:", configs[i]["name"]);
const network = networks[configs[i]["name"]];
const contracts = configs[i]["contracts"];

// Verify contracts
for (let j = 0; j < contracts.length; j++) {
console.log("Checking " + contracts[j]["name"]);
const execSync = require("child_process").execSync;
try {
execSync("scripts/audit_chains/audit_repo_contract.sh " + network + " " + contracts[j]["name"] + " " + contracts[j]["address"]);
} catch (error) {
continue;
}
}
}
}
// ################################# /VERIFY CONTRACTS WITH REPO #################################

// ################################# VERIFY CONTRACTS SETUP #################################
const globalNames = {
"mainnet": "scripts/deployment/globals_mainnet.json",
"goerli": "scripts/deployment/globals_goerli.json",
"polygon": "scripts/deployment/bridges/polygon/globals_polygon_mainnet.json",
"polygonMumbai": "scripts/deployment/bridges/polygon/globals_polygon_mumbai.json",
"gnosis": "scripts/deployment/bridges/gnosis/globals_gnosis_mainnet.json",
"chiado": "scripts/deployment/bridges/gnosis/globals_gnosis_chiado.json"
};

const providerLinks = {
"mainnet": "https://eth-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MAINNET,
"goerli": "https://eth-goerli.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_GOERLI,
"polygon": "https://polygon-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MATIC,
"polygonMumbai": "https://polygon-mumbai.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MUMBAI,
"gnosis": "https://rpc.gnosischain.com",
"chiado": "https://rpc.chiadochain.net"
};

// Get all the globals processed
const globals = new Array();
const providers = new Array();
for (let i = 0; i < numChains; i++) {
const dataJSON = fs.readFileSync(globalNames[configs[i]["name"]], "utf8");
globals.push(JSON.parse(dataJSON));
const provider = new ethers.providers.JsonRpcProvider(providerLinks[configs[i]["name"]]);
providers.push(provider);
}
if (verifySetup) {
const globalNames = {
"mainnet": "scripts/deployment/globals_mainnet.json",
"goerli": "scripts/deployment/globals_goerli.json",
"polygon": "scripts/deployment/bridges/polygon/globals_polygon_mainnet.json",
"polygonMumbai": "scripts/deployment/bridges/polygon/globals_polygon_mumbai.json",
"gnosis": "scripts/deployment/bridges/gnosis/globals_gnosis_mainnet.json",
"chiado": "scripts/deployment/bridges/gnosis/globals_gnosis_chiado.json",
"optimistic": "scripts/deployment/bridges/optimistic/globals_optimistic_mainnet.json",
"optimisticSepolia": "scripts/deployment/bridges/optimistic/globals_optimistic_sepolia.json",
"base": "scripts/deployment/bridges/base/globals_base_mainnet.json",
"baseSepolia": "scripts/deployment/bridges/base/globals_base_sepolia.json"
};

const providerLinks = {
"mainnet": "https://eth-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MAINNET,
"goerli": "https://eth-goerli.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_GOERLI,
"polygon": "https://polygon-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MATIC,
"polygonMumbai": "https://polygon-mumbai.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY_MUMBAI,
"gnosis": "https://rpc.gnosischain.com",
"chiado": "https://rpc.chiadochain.net",
"optimistic": "https://optimism.drpc.org",
"optimisticSepolia": "https://sepolia.optimism.io",
"base": "https://mainnet.base.org",
"baseSepolia": "https://sepolia.base.org"
};

// Get all the globals processed
const globals = new Array();
const providers = new Array();
for (let i = 0; i < numChains; i++) {
const dataJSON = fs.readFileSync(globalNames[configs[i]["name"]], "utf8");
globals.push(JSON.parse(dataJSON));
const provider = new ethers.providers.JsonRpcProvider(providerLinks[configs[i]["name"]]);
providers.push(provider);
}

console.log("\nVerifying deployed contracts setup... If no error is output, then the contracts are correct.");
console.log("\nVerifying deployed contracts setup... If no error is output, then the contracts are correct.");

// L1 contracts
for (let i = 0; i < 2; i++) {
console.log("\n######## Verifying setup on CHAIN ID", configs[i]["chainId"]);
// L1 contracts
for (let i = 0; i < 2; i++) {
console.log("\n######## Verifying setup on CHAIN ID", configs[i]["chainId"]);

const initLog = "ChainId: " + configs[i]["chainId"] + ", network: " + configs[i]["name"];
const initLog = "ChainId: " + configs[i]["chainId"] + ", network: " + configs[i]["name"];

let log = initLog + ", contract: " + "OLAS";
await checkOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "OLAS", log);
let log = initLog + ", contract: " + "OLAS";
await checkOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "OLAS", log);

log = initLog + ", contract: " + "Timelock";
await checkTimelock(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "Timelock", log);
log = initLog + ", contract: " + "Timelock";
await checkTimelock(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "Timelock", log);

log = initLog + ", contract: " + "veOLAS";
await checkVEOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "veOLAS", log);
log = initLog + ", contract: " + "veOLAS";
await checkVEOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "veOLAS", log);

log = initLog + ", contract: " + "buOLAS";
await checkBUOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "buOLAS", log);
log = initLog + ", contract: " + "buOLAS";
await checkBUOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "buOLAS", log);

log = initLog + ", contract: " + "wveOLAS";
await checkWrappedVEOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "wveOLAS", log);
log = initLog + ", contract: " + "wveOLAS";
await checkWrappedVEOLAS(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "wveOLAS", log);

log = initLog + ", contract: " + "GovernorOLAS";
await checkGovernorOLAS(configs[i]["chainId"], providers[i], globals[i], globals[0], configs[i]["contracts"], "GovernorOLAS", log);
log = initLog + ", contract: " + "GovernorOLAS";
await checkGovernorOLAS(configs[i]["chainId"], providers[i], globals[i], globals[0], configs[i]["contracts"], "GovernorOLAS", log);

log = initLog + ", contract: " + "GuardCM";
await checkGuardCM(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "GuardCM", log);
log = initLog + ", contract: " + "GuardCM";
await checkGuardCM(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "GuardCM", log);

log = initLog + ", contract: " + "BridgedERC20";
await checkBridgedERC20(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "BridgedERC20", log);
log = initLog + ", contract: " + "BridgedERC20";
await checkBridgedERC20(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "BridgedERC20", log);

log = initLog + ", contract: " + "FxERC20RootTunnel";
await checkFxERC20RootTunnel(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "FxERC20RootTunnel", log);
}
log = initLog + ", contract: " + "FxERC20RootTunnel";
await checkFxERC20RootTunnel(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "FxERC20RootTunnel", log);
}

// L2 contracts
for (let i = 2; i < numChains; i++) {
console.log("\n######## Verifying setup on CHAIN ID", configs[i]["chainId"]);
// L2 contracts
for (let i = 2; i < numChains; i++) {
// Skip chains that are not yet fully setup
if (configs[i]["chainId"] == "10" || configs[i]["chainId"] == "8453") {
continue;
}

const initLog = "ChainId: " + configs[i]["chainId"] + ", network: " + configs[i]["name"];
console.log("\n######## Verifying setup on CHAIN ID", configs[i]["chainId"]);

if (configs[i]["chainId"] == "137" || configs[i]["chainId"] == "80001") {
let log = initLog + ", contract: " + "FxGovernorTunnel";
await checkFxGovernorTunnel(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "FxGovernorTunnel", log);
const initLog = "ChainId: " + configs[i]["chainId"] + ", network: " + configs[i]["name"];

log = initLog + ", contract: " + "FxERC20ChildTunnel";
await checkFxERC20ChildTunnel(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "FxERC20ChildTunnel", log);
} else {
let log = initLog + ", contract: " + "HomeMediator";
await checkHomeMediator(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "HomeMediator", log);
if (configs[i]["chainId"] == "137" || configs[i]["chainId"] == "80001") {
let log = initLog + ", contract: " + "FxGovernorTunnel";
await checkFxGovernorTunnel(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "FxGovernorTunnel", log);

log = initLog + ", contract: " + "FxERC20ChildTunnel";
await checkFxERC20ChildTunnel(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "FxERC20ChildTunnel", log);
} else if (configs[i]["chainId"] == "100" || configs[i]["chainId"] == "10200") {
let log = initLog + ", contract: " + "HomeMediator";
await checkHomeMediator(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "HomeMediator", log);
} else if (configs[i]["chainId"] == "10" || configs[i]["chainId"] == "11155420" || configs[i]["chainId"] == "8453" || configs[i]["chainId"] == "84532") {
let log = initLog + ", contract: " + "OptimismMessenger";
await checkOptimismMessenger(configs[i]["chainId"], providers[i], globals[i], configs[i]["contracts"], "OptimismMessenger", log);
}
}
}

// ################################# /VERIFY CONTRACTS SETUP #################################
}

Expand Down
47 changes: 47 additions & 0 deletions scripts/deployment/bridges/base/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Bridge-related deployment scripts
This process is the same as described in the original deployment procedure: [deployment](https://github.com/valory-xyz/autonolas-governance/blob/main/scripts/deployment).

## Steps to engage
The project has submodules to get the dependencies. Make sure you run `git clone --recursive` or init the submodules yourself.
The dependency list is managed by the `package.json` file, and the setup parameters are stored in the `hardhat.config.js` file.
Simply run the following command to install the project:
```
yarn install
```
command and compiled with the
```
npx hardhat compile
```

Create a `globals.json` file in the root folder, or copy it from the file with pre-defined parameters (i.e., `scripts/deployment/bridges/base/globals_base_sepolia.json` for the chiado testnet).

Parameters of the `globals.json` file:
- `contractVerification`: flag for verifying contracts in deployment scripts (`true`) or skipping it (`false`);
- `useLedger`: flag whether to use the hardware wallet (`true`) or proceed with the seed-phrase accounts (`false`);
- `derivationPath`: string with the derivation path;
- `gasPriceInGwei`: gas price in Gwei;
- `L2CrossDomainMessengerAddress`: (Base) CFM Contract Proxy address serving as a system processor of inbound calls across the bridge;
- `timelockAddress`: Timelock address on the root L1 network;

The script file name identifies the number of deployment steps taken up to the number in the file name.

Export network-related API keys defined in `hardhat.config.js` file that correspond to the required network.

To run the script, use the following command:
`npx hardhat run scripts/deployment/bridges/script_name --network network_type`,
where `script_number_and_name` is a script number and name, i.e. `deploy_01_home_mediator.js`, `network_type` is a network type corresponding to the `hardhat.config.js` network configuration.

## Validity checks and contract verification
Each script controls the obtained values by checking them against the expected ones. Also, each script has a contract verification procedure.
If a contract is deployed with arguments, these arguments are taken from the corresponding `verify_number_and_name` file, where `number_and_name` corresponds to the deployment script number and name.

## Data packing for cross-bridge transactions
In order to correctly pack the data and supply it to the Timelock such that it is correctly processed across the bridge,
use the following script: [cross-bridge data packing](https://github.com/valory-xyz/autonolas-governance/blob/main/scripts/deployment/bridges/pack-data.js).







Loading
Loading