// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "forge-std/Script.sol"; import {GrcDiamond} from "@gru/GrcDiamond.sol"; import {IDiamondCut} from "@gru/interfaces/IDiamondCut.sol"; import {PauseFacet} from "@gru/facets/PauseFacet.sol"; import {AccessFacet} from "@gru/facets/AccessFacet.sol"; import {M00MainnetBridgeFacet} from "../../contracts/m00-diamond/facets/M00MainnetBridgeFacet.sol"; import {M00DiamondInit} from "../../contracts/m00-diamond/M00DiamondInit.sol"; import {RWAInstrumentFacet} from "../../contracts/rwa/diamond/facets/RWAInstrumentFacet.sol"; import {RWADocumentFacet} from "../../contracts/rwa/diamond/facets/RWADocumentFacet.sol"; import {RWAStandardsRegistryFacet} from "../../contracts/rwa/diamond/facets/RWAStandardsRegistryFacet.sol"; import {IM00MainnetBridgeFacet} from "../../contracts/m00-diamond/interfaces/IM00MainnetBridgeFacet.sol"; import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol"; /** * @title DeployM00DiamondHub138 * @notice Deploy GRC-2535 M00 Diamond hub on Chain 138 with RWA + mainnet mirror/tether/checkpoint bridge facet. * @dev Paris profile mandatory. Wire env from project .env (load-project-env before forge). * * Env: PRIVATE_KEY, GOVERNANCE_CONTROLLER or OWNER * CHAIN138_BATCH_EMITTER, TRANSACTION_MIRROR_ADDRESS (138 local), CHAIN138_MAINNET_CHECKPOINT_PROXY (mainnet) * TRANSACTION_MIRROR_MAINNET, MAINNET_TETHER_ADDRESS * RWA_TOKEN_FACTORY, RWA_TOKEN_REGISTRY */ contract DeployM00DiamondHub138 is Script { function run() external { uint256 pk = vm.envUint("PRIVATE_KEY"); address deployer = vm.addr(pk); address governance = vm.envOr("GOVERNANCE_CONTROLLER", vm.envOr("OWNER", deployer)); vm.startBroadcast(pk); // Diamond owner must be broadcaster for initial diamondCut (ErrUpgradeRole otherwise). GrcDiamond diamond = new GrcDiamond(deployer, "M00.1.0"); PauseFacet pause = new PauseFacet(); AccessFacet access = new AccessFacet(); M00MainnetBridgeFacet bridge = new M00MainnetBridgeFacet(governance); RWAInstrumentFacet rwaInst = new RWAInstrumentFacet(governance); RWADocumentFacet rwaDoc = new RWADocumentFacet(governance); RWAStandardsRegistryFacet rwaStd = new RWAStandardsRegistryFacet(governance); M00DiamondInit init = new M00DiamondInit(); IDiamondCut.FacetCut[] memory cut = _buildCuts( address(pause), address(access), address(bridge), address(rwaInst), address(rwaDoc), address(rwaStd) ); IM00MainnetBridgeFacet.BridgeConfig memory cfg = IM00MainnetBridgeFacet.BridgeConfig({ chain138BatchEmitter: vm.envOr("CHAIN138_BATCH_EMITTER", address(0)), chain138Mirror: vm.envOr("TRANSACTION_MIRROR_ADDRESS", address(0)), mainnetCheckpoint: vm.envOr("CHAIN138_MAINNET_CHECKPOINT_PROXY", address(0)), mainnetMirror: vm.envOr("TRANSACTION_MIRROR_MAINNET", address(0)), mainnetTether: vm.envOr("MAINNET_TETHER_ADDRESS", address(0)), rwaTokenFactory: vm.envOr("RWA_TOKEN_FACTORY", address(0)), rwaTokenRegistry: vm.envOr("RWA_TOKEN_REGISTRY", address(0)) }); diamond.diamondCut(cut, address(init), abi.encodeCall(M00DiamondInit.init, (cfg, governance))); console.log("M00Diamond", address(diamond)); console.log("M00MainnetBridgeFacet", address(bridge)); console.log("RWAInstrumentFacet", address(rwaInst)); vm.stopBroadcast(); } function _buildCuts( address pause, address access, address bridge, address rwaInst, address rwaDoc, address rwaStd ) internal pure returns (IDiamondCut.FacetCut[] memory cut) { cut = new IDiamondCut.FacetCut[](6); cut[0] = _add(pause, _pauseSelectors()); cut[1] = _add(access, _accessSelectors()); cut[2] = _add(bridge, _bridgeSelectors()); cut[3] = _add(rwaInst, _rwaInstSelectors()); cut[4] = _add(rwaDoc, _rwaDocSelectors()); cut[5] = _add(rwaStd, _rwaStdSelectors()); } function _add(address facet, bytes4[] memory sels) internal pure returns (IDiamondCut.FacetCut memory) { return IDiamondCut.FacetCut({ facetAddress: facet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: sels }); } function _pauseSelectors() internal pure returns (bytes4[] memory s) { s = new bytes4[](4); s[0] = PauseFacet.setGlobalPause.selector; s[1] = PauseFacet.setFunctionPause.selector; s[2] = PauseFacet.isPaused.selector; s[3] = PauseFacet.isGlobalPaused.selector; } function _accessSelectors() internal pure returns (bytes4[] memory s) { s = new bytes4[](6); s[0] = AccessFacet.grantRoles.selector; s[1] = AccessFacet.revokeRoles.selector; s[2] = AccessFacet.ROLE_UPGRADE_BIT.selector; s[3] = AccessFacet.ROLE_GOVERNANCE_BIT.selector; s[4] = AccessFacet.ROLE_INDEX_BIT.selector; s[5] = AccessFacet.ROLE_MONETARY_BIT.selector; } function _bridgeSelectors() internal pure returns (bytes4[] memory s) { s = new bytes4[](11); s[0] = M00MainnetBridgeFacet.wireMainnetBridge.selector; s[1] = M00MainnetBridgeFacet.getMainnetBridgeConfig.selector; s[2] = M00MainnetBridgeFacet.commitBatchOn138.selector; s[3] = M00MainnetBridgeFacet.sendBatchToMainnet.selector; s[4] = M00MainnetBridgeFacet.scheduleMirrorToMainnet.selector; s[5] = M00MainnetBridgeFacet.mirrorOnMainnet.selector; s[6] = M00MainnetBridgeFacet.anchorStateProofOnMainnet.selector; s[7] = M00MainnetBridgeFacet.ackInboundCheckpoint.selector; s[8] = IAccessControl.grantRole.selector; s[9] = IAccessControl.revokeRole.selector; s[10] = IAccessControl.hasRole.selector; } function _rwaInstSelectors() internal pure returns (bytes4[] memory s) { s = new bytes4[](5); s[0] = RWAInstrumentFacet.setIssuanceMode.selector; s[1] = RWAInstrumentFacet.setInstrumentIdentity.selector; s[2] = RWAInstrumentFacet.setTokenPointer.selector; s[3] = RWAInstrumentFacet.getIssuanceMode.selector; s[4] = RWAInstrumentFacet.getTokenPointer.selector; } function _rwaDocSelectors() internal pure returns (bytes4[] memory s) { s = new bytes4[](2); s[0] = RWADocumentFacet.anchorDocument.selector; s[1] = RWADocumentFacet.setPrimaryContentHash.selector; } function _rwaStdSelectors() internal pure returns (bytes4[] memory s) { s = new bytes4[](3); s[0] = RWAStandardsRegistryFacet.enableStandard.selector; s[1] = RWAStandardsRegistryFacet.disableStandard.selector; s[2] = RWAStandardsRegistryFacet.bindAssetStandardFacet.selector; } }