Skip to content

Commit

Permalink
Merge pull request #115 from valory-xyz/base_bridge
Browse files Browse the repository at this point in the history
Base bridge
  • Loading branch information
mariapiamo authored Feb 23, 2024
2 parents 96ab51f + 5984bc5 commit 60a9983
Show file tree
Hide file tree
Showing 17 changed files with 851 additions and 101 deletions.
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

0 comments on commit 60a9983

Please sign in to comment.