packages/contracts-core/script/DeployMessaging003SynChain.s.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
// ═════════════════════════════ CONTRACT IMPORTS ══════════════════════════════
import {AgentFlag, AgentStatus} from "../contracts/libs/Structures.sol";
import {BondingManager} from "../contracts/manager/BondingManager.sol";
import {Inbox} from "../contracts/inbox/Inbox.sol";
// ═════════════════════════════ INTERNAL IMPORTS ══════════════════════════════
import {DeployMessaging003BaseScript} from "./DeployMessaging003Base.s.sol";
// ═════════════════════════════ EXTERNAL IMPORTS ══════════════════════════════
import {console, stdJson} from "forge-std/Script.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
// solhint-disable no-console
// solhint-disable ordering
contract DeployMessaging003SynChainScript is DeployMessaging003BaseScript {
using stdJson for string;
using Strings for uint256;
/// @dev Deploys BondingManager or LightManager
/// Note: requires Origin, Destination, StatementInbox and Summit addresses to be set
function _deployAgentManager() internal override returns (address deployment, bytes memory constructorArgs) {
// new BondingManager(domain)
constructorArgs = abi.encode(synapseDomain);
deployment = factoryDeploy(agentManagerName(), type(BondingManager).creationCode, constructorArgs);
require(origin != address(0), "Origin not set");
require(destination != address(0), "Destination not set");
require(statementInbox != address(0), "Statement Inbox not set");
require(summit != address(0), "Summit not set");
}
/// @dev Initializes BondingManager or LightManager
function _initializeAgentManager(address deployment) internal override {
if (BondingManager(deployment).owner() == address(0)) {
console.log(" %s: initializing", agentManagerName());
BondingManager(deployment).initialize({
origin_: origin,
destination_: destination,
inbox_: statementInbox,
summit_: summit
});
} else {
console.log(" %s: already initialized", agentManagerName());
}
}
/// @dev Deploys Inbox or LightInbox
/// Note: requires AgentManager, Origin, Destination and Summit addresses to be set
function _deployStatementInbox() internal override returns (address deployment, bytes memory constructorArgs) {
// new Inbox(domain)
constructorArgs = abi.encode(synapseDomain);
deployment = factoryDeploy(statementInboxName(), type(Inbox).creationCode, constructorArgs);
require(agentManager != address(0), "Agent Manager not set");
require(origin != address(0), "Origin not set");
require(destination != address(0), "Destination not set");
require(summit != address(0), "Summit not set");
}
/// @dev Initializes Inbox or LightInbox
function _initializeStatementInbox(address deployment) internal override {
if (Inbox(deployment).owner() == address(0)) {
console.log(" %s: initializing", statementInboxName());
Inbox(deployment).initialize({
agentManager_: agentManager,
origin_: origin,
destination_: destination,
summit_: summit
});
} else {
console.log(" %s: already initialized", statementInboxName());
}
}
/// @dev Adds agents to BondingManager (no-op for LightManager)
function _addAgents() internal override {
console.log("Adding Agents");
uint256[] memory domains = globalConfig.readUintArray(".domains");
for (uint256 i = 0; i < domains.length; ++i) {
uint256 domain = domains[i];
// Key is ".agents.0: for Guards, ".agents.10" for Optimism Notaries, etc
address[] memory agents = globalConfig.readAddressArray(string.concat(".agents.", domain.toString()));
for (uint256 j = 0; j < agents.length; ++j) {
address agent = agents[j];
if (BondingManager(agentManager).agentStatus(agent).flag != AgentFlag.Unknown) {
console.log(" [address: %s] [domain: %s] skipped (already added)", agent, domain);
continue;
}
// Get a proof of non-inclusion
bytes32[] memory proof = BondingManager(agentManager).getProof(agent);
BondingManager(agentManager).addAgent(uint32(domain), agent, proof);
console.log(" [address: %s] [domain: %s] added", agent, domain);
}
}
string memory proofsKey = "proofs";
string memory proofsJson = "";
for (uint256 i = 0; i < domains.length; ++i) {
uint256 domain = domains[i];
// Key is ".agents.0: for Guards, ".agents.10" for Optimism Notaries, etc
address[] memory agents = globalConfig.readAddressArray(string.concat(".agents.", domain.toString()));
string[] memory agentsStr = globalConfig.readStringArray(string.concat(".agents.", domain.toString()));
for (uint256 j = 0; j < agents.length; ++j) {
address agent = agents[j];
// Get a proof of inclusion
bytes32[] memory proof = BondingManager(agentManager).getProof(agent);
proofsJson = proofsKey.serialize(agentsStr[j], proof);
}
}
// Save resulting agent root for deployments on other chains
bytes32 agentRoot = BondingManager(agentManager).agentRoot();
string memory agentRootConfig = "agentRoot";
agentRootConfig.serialize("initialAgentRoot", agentRoot);
agentRootConfig = agentRootConfig.serialize("proofs", proofsJson);
string memory path = globalDeployConfigPath("Messaging003AgentRoot");
agentRootConfig.write(path);
}
/// @dev Checks that all agents have been added correctly to BondingManager
/// or that they could be added to LightManager.
function _checkAgents() internal override {
console.log("Checking Agents");
uint256[] memory domains = globalConfig.readUintArray(".domains");
// Agent indexes start from 1
uint256 expectedIndex = 1;
for (uint256 i = 0; i < domains.length; ++i) {
uint256 domain = domains[i];
// Key is ".agents.0: for Guards, ".agents.10" for Optimism Notaries, etc
address[] memory agents = globalConfig.readAddressArray(string.concat(".agents.", domain.toString()));
for (uint256 j = 0; j < agents.length; ++j) {
address agent = agents[j];
AgentStatus memory status = BondingManager(agentManager).agentStatus(agent);
console.log(" [index: %s] [address: %s] [domain: %s]", status.index, agent, status.domain);
require(status.flag == AgentFlag.Active, "Agent is not active");
require(status.domain == uint32(domain), "Agent is not on correct domain");
require(status.index == expectedIndex, "Agent has incorrect index");
++expectedIndex;
}
}
}
}