1+ // script/DeployDiamond.s.sol
2+ pragma solidity ^ 0.8.0 ;
3+
4+ import {Script, console2} from "forge-std/Script.sol " ;
5+ import {IDiamondCut} from "../src/interfaces/IDiamondCut.sol " ;
6+
7+ // 1. Manually import all required contracts/facets
8+ import {Registry} from "../src/registry/Registry.sol " ;
9+ import {Diamond} from "../src/Diamond/Diamond.sol " ;
10+ import {DiamondCutFacet} from "../src/facets/Diamond/DiamondCutFacet.sol " ;
11+ import {DiamondLoupeFacet} from "../src/facets/Diamond/DiamondLoupeFacet.sol " ;
12+ import {OwnershipFacet} from "../src/facets/Ownership/OwnershipFacet.sol " ;
13+ import {ERC20Facet } from "../src/facets/ERC20/ERC20Facet.sol " ;
14+
15+ contract DeployDiamondScript is Script {
16+ // Define the contract owner/governance
17+ address public constant OWNER = address (0xBEEF );// Replace with your desired owner address
18+
19+ function run () external {
20+ uint256 deployerPrivateKey = vm.envUint ("PRIVATE_KEY " );
21+ // vm.startBroadcast() is called with the private key to sign and submit transactions
22+ vm.startBroadcast (deployerPrivateKey);
23+
24+ // --- 1. Deploy Facets and Registry ---
25+ console2.log ("1. Deploying Facets and Registry... " );
26+ DiamondCutFacet cutFacet = new DiamondCutFacet ();
27+ DiamondLoupeFacet loupeFacet = new DiamondLoupeFacet ();
28+ OwnershipFacet ownershipFacet = new OwnershipFacet ();
29+ ERC20Facet erc20Facet = new ERC20Facet ();
30+ Registry registry = new Registry ();
31+
32+ console2.log ("Registry Address: " , address (registry));
33+
34+ // --- 2. Deploy the Diamond Proxy ---
35+ console2.log ("2. Deploying Diamond Proxy... " );
36+ Diamond diamond = new Diamond ();
37+ address diamondAddress = address (diamond);
38+ console2.log ("Diamond Address: " , diamondAddress);
39+
40+ // --- 3. Construct the DiamondCut array (The 'Add' operation) ---
41+ IDiamondCut.FacetCut[] memory cuts = new IDiamondCut.FacetCut [](4 );
42+
43+ cuts[0 ] = buildCut (address (cutFacet));
44+ cuts[1 ] = buildCut (address (loupeFacet));
45+ cuts[2 ] = buildCut (address (ownershipFacet));
46+ cuts[3 ] = buildCut (address (erc20Facet));
47+
48+ // --- 4. Execute the Initial DiamondCut ---
49+ console2.log ("4. Executing initial DiamondCut... " );
50+ IDiamondCut diamondCut = IDiamondCut (diamondAddress);
51+
52+ // Execute the cut to link all facets to the Diamond proxy
53+ diamondCut.diamondCut (
54+ cuts,
55+ address (0 ), // _init: Address of initializer contract (0x0 since we use an immediate cut)
56+ "" // _calldata: Calldata for the initializer function
57+ );
58+
59+ // --- 5. Optional: Initialize/Configure ---
60+ // Call the OwnershipFacet function on the Diamond address to set the final owner
61+ OwnershipFacet (diamondAddress).transferOwnership (OWNER);
62+
63+ // Register the Diamond itself in the registry for tracking
64+ registry.register ("Diamond_V1 " , diamondAddress, 1 );
65+
66+ console2.log ("Deployment and initial DiamondCut completed. " );
67+
68+ // vm.stopBroadcast() tells Foundry to stop recording transactions
69+ vm.stopBroadcast ();
70+ }
71+
72+ // --- Helper Function using vm.parseSelectors ---
73+ function buildCut (address _facetAddress )
74+ internal
75+ view // Changed to view since we are using vm.parseSelectors which is off-chain
76+ returns (IDiamondCut.FacetCut memory )
77+ {
78+ // vm.parseSelectors reads the bytecode of the contract at _facetAddress
79+ // and returns all exposed function signatures (bytes[]).
80+ bytes [] memory sigs = vm.parseSelectors (_facetAddress);
81+ bytes4 [] memory selectors = new bytes4 [](sigs.length );
82+
83+ for (uint256 i = 0 ; i < sigs.length ; i++ ) {
84+ // Convert the full signature bytes to the 4-byte selector
85+ selectors[i] = bytes4 (sigs[i]);
86+ }
87+
88+ return IDiamondCut.FacetCut ({
89+ facetAddress: _facetAddress,
90+ action: IDiamondCut.FacetCutAction.Add,
91+ functionSelectors: selectors
92+ });
93+ }
94+ }
0 commit comments