synapsecns/sanguine

View on GitHub
packages/contracts-core/test/utils/SynapseTest.t.sol

Summary

Maintainability
Test Coverage
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {AgentFlag, BondingManager} from "../../contracts/manager/BondingManager.sol";
import {AgentStatus, LightManager} from "../../contracts/manager/LightManager.sol";
import {IAgentSecured} from "../../contracts/interfaces/IAgentSecured.sol";
import {Destination} from "../../contracts/Destination.sol";
import {GasOracle} from "../../contracts/GasOracle.sol";
import {Origin} from "../../contracts/Origin.sol";
import {Summit} from "../../contracts/Summit.sol";

import {Inbox} from "../../contracts/inbox/Inbox.sol";
import {LightInbox} from "../../contracts/inbox/LightInbox.sol";

import {BondingManagerHarness} from "../harnesses/manager/BondingManagerHarness.t.sol";
import {LightManagerHarness} from "../harnesses/manager/LightManagerHarness.t.sol";

import {DestinationMock} from "../mocks/DestinationMock.t.sol";
import {GasOracleMock} from "../mocks/GasOracleMock.t.sol";
import {OriginMock} from "../mocks/OriginMock.t.sol";
import {SummitMock} from "../mocks/SummitMock.t.sol";

import {ProductionEvents} from "./events/ProductionEvents.t.sol";
import {SuiteEvents} from "./events/SuiteEvents.t.sol";
import {SynapseAgents} from "./SynapseAgents.t.sol";
import {SynapseProofs} from "./SynapseProofs.t.sol";

// solhint-disable no-empty-blocks
// solhint-disable ordering
abstract contract SynapseTest is ProductionEvents, SuiteEvents, SynapseAgents, SynapseProofs {
    uint256 private immutable deployMask;

    address internal gasOracleSynapse;
    address internal originSynapse;
    address internal destinationSynapse;
    address internal summit;
    Inbox internal inbox;
    BondingManagerHarness internal bondingManager;

    address internal gasOracle;
    address internal destination;
    address internal origin;
    LightInbox internal lightInbox;
    LightManagerHarness internal lightManager;

    constructor(uint256 deployMask_) {
        deployMask = deployMask_;
    }

    /// @notice Prevents this contract from being included in the coverage report
    function testSynapseTest() external {}

    function setUp() public virtual override {
        // Setup domains and create agents for them
        super.setUp();
        // Deploy a single set of messaging contracts for synapse chain
        deployBondingManager();
        deployInbox();
        deploySummit();
        deployDestinationSynapse();
        deployGasOracleSynapse();
        deployOriginSynapse();
        // Setup agents in BondingManager
        initBondingManager();
        initInbox();
        setupAgentsBM();
        // Deploy a single set of messaging contracts for local chain
        deployLightManager();
        deployLightInbox();
        deployDestination();
        deployGasOracle();
        deployOrigin();
        // Setup agents in LightManager
        initLightManager();
        initLightInbox();
        setupAgentsLM();
        // Skip block
        skipBlock();
        // cleanup the env.
        vm.chainId(DOMAIN_LOCAL);
    }

    function setupAgentsBM() public virtual {
        for (uint256 d = 0; d < allDomains.length; ++d) {
            uint32 domain = allDomains[d];
            for (uint256 i = 0; i < DOMAIN_AGENTS; ++i) {
                address agent = domains[domain].agents[i];
                addAgentBM(domain, agent);
            }
        }
    }

    function setupAgentsLM() public virtual {
        if (deployMask & DEPLOY_MASK_DESTINATION == DEPLOY_PROD_DESTINATION) {
            // Set initial agent merkle root via production Destination
            Destination(destination).initialize(getAgentRoot());
        } else {
            // Mock a call from destination instead
            bytes32 root = getAgentRoot();
            vm.prank(destination);
            lightManager.setAgentRoot(root);
        }
        for (uint256 d = 0; d < allDomains.length; ++d) {
            uint32 domain = allDomains[d];
            for (uint256 i = 0; i < DOMAIN_AGENTS; ++i) {
                address agent = domains[domain].agents[i];
                updateAgentLM(agent);
            }
        }
    }

    // ═════════════════════════════════════════════ DEPLOY CONTRACTS ══════════════════════════════════════════════════

    function deployLightManager() public virtual {
        vm.chainId(DOMAIN_LOCAL);
        lightManager = new LightManagerHarness(DOMAIN_SYNAPSE);
        vm.label(address(lightManager), "LightManager");
    }

    function initLightManager() public virtual {
        lightManager.initialize(origin, destination, address(lightInbox));
    }

    function deployBondingManager() public virtual {
        vm.chainId(DOMAIN_SYNAPSE);
        bondingManager = new BondingManagerHarness(DOMAIN_SYNAPSE);
        vm.label(address(bondingManager), "BondingManager");
    }

    function initBondingManager() public virtual {
        bondingManager.initialize(originSynapse, destinationSynapse, address(inbox), summit);
    }

    function deployLightInbox() public virtual {
        vm.chainId(DOMAIN_LOCAL);
        lightInbox = new LightInbox(DOMAIN_SYNAPSE);
    }

    function initLightInbox() public virtual {
        LightInbox(lightInbox).initialize(address(lightManager), origin, destination);
    }

    function deployInbox() public virtual {
        vm.chainId(DOMAIN_SYNAPSE);
        inbox = new Inbox(DOMAIN_SYNAPSE);
    }

    function initInbox() public virtual {
        Inbox(inbox).initialize(address(bondingManager), originSynapse, destinationSynapse, summit);
    }

    function deployGasOracle() public virtual {
        uint256 option = deployMask & DEPLOY_MASK_GAS_ORACLE;
        if (option == DEPLOY_MOCK_GAS_ORACLE) {
            gasOracle = address(new GasOracleMock());
        } else if (option == DEPLOY_PROD_GAS_ORACLE) {
            gasOracle = address(new GasOracle(DOMAIN_SYNAPSE, destination));
            GasOracle(gasOracle).initialize();
        } else {
            revert("Unknown option: GasOracle");
        }
        vm.label(gasOracle, "GasOracle Local");
    }

    function deployDestination() public virtual {
        uint256 option = deployMask & DEPLOY_MASK_DESTINATION;
        if (option == DEPLOY_MOCK_DESTINATION) {
            destination = address(new DestinationMock());
        } else if (option == DEPLOY_PROD_DESTINATION) {
            destination = address(new Destination(DOMAIN_SYNAPSE, address(lightManager), address(lightInbox)));
            // Destination will be initialized once agents are setup
        } else {
            revert("Unknown option: Destination");
        }
        vm.label(destination, "Destination Local");
    }

    function deployOrigin() public virtual {
        uint256 option = deployMask & DEPLOY_MASK_ORIGIN;
        if (option == DEPLOY_MOCK_ORIGIN) {
            origin = address(new OriginMock());
        } else if (option == DEPLOY_PROD_ORIGIN) {
            origin = address(new Origin(DOMAIN_SYNAPSE, address(lightManager), address(lightInbox), gasOracle));
            Origin(origin).initialize();
        } else {
            revert("Unknown option: Origin");
        }
        vm.label(origin, "Origin Local");
    }

    function deployGasOracleSynapse() public virtual {
        uint256 option = deployMask & DEPLOY_MASK_GAS_ORACLE_SYNAPSE;
        if (option == DEPLOY_MOCK_GAS_ORACLE_SYNAPSE) {
            gasOracleSynapse = address(new GasOracleMock());
        } else if (option == DEPLOY_PROD_GAS_ORACLE_SYNAPSE) {
            gasOracleSynapse = address(new GasOracle(DOMAIN_SYNAPSE, destinationSynapse));
            GasOracle(gasOracleSynapse).initialize();
        } else {
            revert("Unknown option: GasOracle");
        }
        vm.label(gasOracleSynapse, "GasOracle Synapse");
    }

    function deployDestinationSynapse() public virtual {
        uint256 option = deployMask & DEPLOY_MASK_DESTINATION_SYNAPSE;
        if (option == DEPLOY_MOCK_DESTINATION_SYNAPSE) {
            destinationSynapse = address(new DestinationMock());
        } else if (option == DEPLOY_PROD_DESTINATION_SYNAPSE) {
            destinationSynapse = address(new Destination(DOMAIN_SYNAPSE, address(bondingManager), address(inbox)));
            Destination(destinationSynapse).initialize(0);
        } else {
            revert("Unknown option: Destination");
        }
        vm.label(destinationSynapse, "Destination Synapse");
    }

    function deployOriginSynapse() public virtual {
        uint256 option = deployMask & DEPLOY_MASK_ORIGIN_SYNAPSE;
        if (option == DEPLOY_MOCK_ORIGIN_SYNAPSE) {
            originSynapse = address(new OriginMock());
        } else if (option == DEPLOY_PROD_ORIGIN_SYNAPSE) {
            originSynapse =
                address(new Origin(DOMAIN_SYNAPSE, address(bondingManager), address(inbox), gasOracleSynapse));
            Origin(originSynapse).initialize();
        } else {
            revert("Unknown option: Origin");
        }
        vm.label(originSynapse, "Origin Synapse");
    }

    function deploySummit() public virtual {
        vm.chainId(DOMAIN_SYNAPSE);

        uint256 option = deployMask & DEPLOY_MASK_SUMMIT;
        if (option == DEPLOY_MOCK_SUMMIT) {
            summit = address(new SummitMock());
        } else if (option == DEPLOY_PROD_SUMMIT) {
            summit = address(new Summit(DOMAIN_SYNAPSE, address(bondingManager), address(inbox)));
            Summit(summit).initialize();
        } else {
            revert("Unknown option: Summit");
        }
        vm.label(summit, "Summit");
    }

    // ═══════════════════════════════════════════════ ADDING AGENTS ═══════════════════════════════════════════════════

    function addAgentBM(uint32 domain, address agent) public {
        bytes32[] memory proof = getZeroProof();
        bondingManager.addAgent(domain, agent, proof);
        addNewAgent(domain, agent);
    }

    function updateAgentLM(address agent) public {
        bytes32[] memory proof = getAgentProof(agent);
        lightManager.updateAgentStatus(agent, getAgentStatus(agent), proof);
    }

    function checkAgentStatus(address agent, AgentStatus memory status, AgentFlag flag) public virtual {
        assertEq(uint8(status.flag), uint8(flag), "!flag");
        assertEq(status.domain, agentDomain[agent], "!domain");
        assertEq(status.index, agentIndex[agent], "!index");
    }
}