@diamondslab/diamonds-hardhat-foundry 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -63,8 +63,18 @@ abstract contract DiamondFuzzBase is Test {
63
63
 
64
64
  /// @notice Load deployed Diamond address
65
65
  /// @dev Override this function to provide custom Diamond address loading logic
66
- /// @dev Default implementation uses vm.envAddress("DIAMOND_ADDRESS") if available, otherwise uses a test deployment
66
+ /// @dev When using generated DiamondDeployment helper, return DiamondDeployment.getDiamondAddress()
67
67
  /// @return diamondAddress The deployed Diamond contract address
68
+ /// @custom:example
69
+ /// ```solidity
70
+ /// // Import the generated helper
71
+ /// import {DiamondDeployment} from "test/foundry/helpers/DiamondDeployment.sol";
72
+ ///
73
+ /// // Override to use helper's address (automatically matches --diamond-name)
74
+ /// function _loadDiamondAddress() internal view override returns (address) {
75
+ /// return DiamondDeployment.getDiamondAddress();
76
+ /// }
77
+ /// ```
68
78
  function _loadDiamondAddress() internal view virtual returns (address diamondAddress) {
69
79
  // Try to load from environment variable
70
80
  try vm.envAddress("DIAMOND_ADDRESS") returns (address addr) {
@@ -78,8 +88,19 @@ abstract contract DiamondFuzzBase is Test {
78
88
  }
79
89
 
80
90
  /// @notice Get the path to the Diamond ABI file
81
- /// @dev Override this to use a different ABI file path
91
+ /// @dev Override this to use a different ABI file path or return DiamondDeployment.getDiamondABIPath()
92
+ /// @dev When using generated DiamondDeployment helper, you can simply return DiamondDeployment.getDiamondABIPath()
82
93
  /// @return abiPath The path to the Diamond ABI JSON file
94
+ /// @custom:example
95
+ /// ```solidity
96
+ /// // Import the generated helper
97
+ /// import {DiamondDeployment} from "test/foundry/helpers/DiamondDeployment.sol";
98
+ ///
99
+ /// // Override to use helper's path (automatically matches --diamond-name)
100
+ /// function _getDiamondABIPath() internal view override returns (string memory) {
101
+ /// return DiamondDeployment.getDiamondABIPath();
102
+ /// }
103
+ /// ```
83
104
  function _getDiamondABIPath() internal view virtual returns (string memory abiPath) {
84
105
  return "./diamond-abi/ExampleDiamond.json";
85
106
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HelperGenerator.d.ts","sourceRoot":"","sources":["../../src/framework/HelperGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAI1D;;GAEG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,yBAAyB;IAElD;;OAEG;IACG,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxD;;OAEG;IACG,yBAAyB,CAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,mBAAmB,GAClC,OAAO,CAAC,MAAM,CAAC;IA6BlB;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAuE/C;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CAgH9B"}
1
+ {"version":3,"file":"HelperGenerator.d.ts","sourceRoot":"","sources":["../../src/framework/HelperGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAI1D;;GAEG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,yBAAyB;IAElD;;OAEG;IACG,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxD;;OAEG;IACG,yBAAyB,CAC7B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,mBAAmB,GAClC,OAAO,CAAC,MAAM,CAAC;IA6BlB;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAuE/C;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CA0I9B"}
@@ -136,6 +136,14 @@ class HelperGenerator {
136
136
  source += ` * ⚠️ DO NOT EDIT MANUALLY - Changes will be overwritten on next generation\n`;
137
137
  source += " */\n";
138
138
  source += "library DiamondDeployment {\n";
139
+ // Diamond name
140
+ source += ` /// @notice Name of the Diamond contract\n`;
141
+ source += ` /// @dev Used for identifying the Diamond in tests\n`;
142
+ source += ` string constant DIAMOND_NAME = "${diamondName}";\n\n`;
143
+ // Diamond ABI path
144
+ source += ` /// @notice Path to the Diamond ABI file\n`;
145
+ source += ` /// @dev Used by DiamondFuzzBase to load ABI for testing\n`;
146
+ source += ` string constant DIAMOND_ABI_PATH = "./diamond-abi/${diamondName}.json";\n\n`;
139
147
  // Diamond address
140
148
  source += ` /// @notice Address of the deployed ${diamondName} contract\n`;
141
149
  source += ` /// @dev This is the main Diamond proxy address\n`;
@@ -164,6 +172,20 @@ class HelperGenerator {
164
172
  source += " // Helper Functions\n";
165
173
  source += " // ========================================\n\n";
166
174
  source += " /**\n";
175
+ source += " * @notice Get the Diamond name\n";
176
+ source += " * @return The name of the Diamond contract\n";
177
+ source += " */\n";
178
+ source += " function getDiamondName() internal pure returns (string memory) {\n";
179
+ source += " return DIAMOND_NAME;\n";
180
+ source += " }\n\n";
181
+ source += " /**\n";
182
+ source += " * @notice Get the path to the Diamond ABI file\n";
183
+ source += " * @return The path to the Diamond ABI JSON file\n";
184
+ source += " */\n";
185
+ source += " function getDiamondABIPath() internal pure returns (string memory) {\n";
186
+ source += " return DIAMOND_ABI_PATH;\n";
187
+ source += " }\n\n";
188
+ source += " /**\n";
167
189
  source += " * @notice Get the Diamond contract address\n";
168
190
  source += " * @return The address of the deployed Diamond proxy\n";
169
191
  source += " */\n";
@@ -1 +1 @@
1
- {"version":3,"file":"HelperGenerator.js","sourceRoot":"","sources":["../../src/framework/HelperGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["import { DeployedDiamondData } from \"@diamondslab/diamonds\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { HardhatRuntimeEnvironment } from \"hardhat/types\";\nimport { join } from \"path\";\nimport { Logger } from \"../utils/logger\";\n\n/**\n * HelperGenerator - Generates Solidity helper files for testing\n */\nexport class HelperGenerator {\n constructor(private hre: HardhatRuntimeEnvironment) {}\n\n /**\n * Scaffold project with initial test structure\n */\n async scaffoldProject(outputDir?: string): Promise<void> {\n const helpersDir = outputDir || this.hre.diamondsFoundry.helpersDir;\n const basePath = join(this.hre.config.paths.root, helpersDir);\n\n Logger.section(\"Scaffolding Forge Test Structure\");\n \n // Create directories\n Logger.step(\"Creating directories...\");\n mkdirSync(basePath, { recursive: true });\n mkdirSync(join(basePath, \"../unit\"), { recursive: true });\n mkdirSync(join(basePath, \"../integration\"), { recursive: true });\n mkdirSync(join(basePath, \"../fuzz\"), { recursive: true });\n\n Logger.success(`Test structure created at ${basePath}`);\n }\n\n /**\n * Generate DiamondDeployment.sol from deployment record\n */\n async generateDeploymentHelpers(\n diamondName: string,\n networkName: string,\n chainId: number,\n deploymentData: DeployedDiamondData\n ): Promise<string> {\n Logger.section(\"Generating Diamond Deployment Helper\");\n\n const helpersDir = this.hre.diamondsFoundry.helpersDir;\n const outputPath = join(\n this.hre.config.paths.root,\n helpersDir,\n \"DiamondDeployment.sol\"\n );\n\n const content = this.generateLibrarySource(\n diamondName,\n networkName,\n chainId,\n deploymentData\n );\n\n // Ensure directory exists\n mkdirSync(join(this.hre.config.paths.root, helpersDir), {\n recursive: true,\n });\n\n // Write file\n writeFileSync(outputPath, content, \"utf8\");\n\n Logger.success(`Generated: ${outputPath}`);\n return outputPath;\n }\n\n /**\n * Generate example test files\n */\n async generateExampleTests(): Promise<string[]> {\n const generated: string[] = [];\n const examples = this.hre.diamondsFoundry.exampleTests;\n\n if (!this.hre.diamondsFoundry.generateExamples) {\n Logger.info(\"Example generation disabled in config\");\n return generated;\n }\n\n Logger.section(\"Generating Example Tests\");\n\n const basePath = join(this.hre.config.paths.root, \"test\", \"foundry\");\n const templatesPath = join(__dirname, \"../templates\");\n\n for (const type of examples) {\n let templateFile = \"\";\n let outputPath = \"\";\n\n switch (type) {\n case \"unit\":\n templateFile = join(templatesPath, \"ExampleUnitTest.t.sol.template\");\n outputPath = join(basePath, \"unit\", \"ExampleUnit.t.sol\");\n break;\n case \"integration\":\n templateFile = join(templatesPath, \"ExampleIntegrationTest.t.sol.template\");\n outputPath = join(basePath, \"integration\", \"ExampleIntegration.t.sol\");\n break;\n case \"fuzz\":\n templateFile = join(templatesPath, \"ExampleFuzzTest.t.sol.template\");\n outputPath = join(basePath, \"fuzz\", \"ExampleFuzz.t.sol\");\n break;\n default:\n Logger.warn(`Unknown example type: ${type}`);\n continue;\n }\n\n try {\n // Check if template exists\n if (!existsSync(templateFile)) {\n Logger.warn(`Template not found: ${templateFile}`);\n continue;\n }\n\n // Read template content\n const templateContent = readFileSync(templateFile, \"utf8\");\n\n // Ensure output directory exists\n mkdirSync(join(basePath, type), { recursive: true });\n\n // Check if file already exists\n if (existsSync(outputPath)) {\n Logger.info(`Skipping ${type} example (already exists): ${outputPath}`);\n continue;\n }\n\n // Write example test file\n writeFileSync(outputPath, templateContent, \"utf8\");\n Logger.success(`Generated ${type} example: ${outputPath}`);\n generated.push(outputPath);\n } catch (error: any) {\n Logger.error(`Failed to generate ${type} example: ${error.message}`);\n }\n }\n\n if (generated.length === 0) {\n Logger.info(\"No new example tests generated (may already exist)\");\n }\n\n return generated;\n }\n\n /**\n * Generate Solidity library source from deployment data\n * @private\n */\n private generateLibrarySource(\n diamondName: string,\n networkName: string,\n chainId: number,\n deploymentData: DeployedDiamondData\n ): string {\n const timestamp = new Date().toISOString();\n const networkInfo = `${networkName}-${chainId}`;\n const deploymentFileName = `${diamondName.toLowerCase()}-${networkInfo}.json`;\n const deploymentFilePath = `diamonds/${diamondName}/deployments/${deploymentFileName}`;\n\n let source = \"\";\n\n // SPDX and pragma\n source += \"// SPDX-License-Identifier: MIT\\n\";\n source += \"pragma solidity ^0.8.19;\\n\\n\";\n\n // Header comments\n source += \"/**\\n\";\n source += ` * @title DiamondDeployment\\n`;\n source += ` * @notice Auto-generated deployment data for ${diamondName}\\n`;\n source += ` * @dev This library provides constants and helper functions for accessing\\n`;\n source += ` * deployment data in Forge tests. It is auto-generated from the deployment\\n`;\n source += ` * record and should not be edited manually.\\n`;\n source += ` *\\n`;\n source += ` * Generated from: ${deploymentFilePath}\\n`;\n source += ` * Generated at: ${timestamp}\\n`;\n source += ` *\\n`;\n source += ` * To regenerate this file:\\n`;\n source += ` * npx hardhat diamonds-forge:generate-helpers --diamond ${diamondName}\\n`;\n source += ` *\\n`;\n source += ` * ⚠️ DO NOT EDIT MANUALLY - Changes will be overwritten on next generation\\n`;\n source += \" */\\n\";\n source += \"library DiamondDeployment {\\n\";\n\n // Diamond address\n source += ` /// @notice Address of the deployed ${diamondName} contract\\n`;\n source += ` /// @dev This is the main Diamond proxy address\\n`;\n source += ` address constant DIAMOND_ADDRESS = ${deploymentData.DiamondAddress};\\n\\n`;\n\n // Deployer address\n source += ` /// @notice Address of the deployer account\\n`;\n source += ` /// @dev Account that deployed the Diamond\\n`;\n source += ` address constant DEPLOYER_ADDRESS = ${deploymentData.DeployerAddress};\\n\\n`;\n\n // Facet addresses\n source += \" // ========================================\\n\";\n source += \" // Facet Addresses\\n\";\n source += \" // ========================================\\n\\n\";\n\n const facets = deploymentData.DeployedFacets ?? {};\n for (const [facetName, facetData] of Object.entries(facets)) {\n const constantName = facetName\n .replace(/Facet$/, \"\")\n .replace(/([A-Z])/g, \"_$1\")\n .toUpperCase()\n .replace(/^_/, \"\") + \"_FACET\";\n\n source += ` /// @notice Address of ${facetName} implementation\\n`;\n source += ` address constant ${constantName} = ${facetData.address};\\n`;\n }\n source += \"\\n\";\n\n // Helper functions\n source += \" // ========================================\\n\";\n source += \" // Helper Functions\\n\";\n source += \" // ========================================\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get the Diamond contract address\\n\";\n source += \" * @return The address of the deployed Diamond proxy\\n\";\n source += \" */\\n\";\n source += \" function getDiamondAddress() internal pure returns (address) {\\n\";\n source += \" return DIAMOND_ADDRESS;\\n\";\n source += \" }\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get the deployer address\\n\";\n source += \" * @return The address of the deployer account\\n\";\n source += \" */\\n\";\n source += \" function getDeployerAddress() internal pure returns (address) {\\n\";\n source += \" return DEPLOYER_ADDRESS;\\n\";\n source += \" }\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get facet implementation address by name\\n\";\n source += \" * @param facetName The name of the facet\\n\";\n source += \" * @return The address of the facet implementation\\n\";\n source += \" */\\n\";\n source += \" function getFacetAddress(string memory facetName) internal pure returns (address) {\\n\";\n\n let firstFacet = true;\n for (const [facetName, facetData] of Object.entries(facets)) {\n const constantName = facetName\n .replace(/Facet$/, \"\")\n .replace(/([A-Z])/g, \"_$1\")\n .toUpperCase()\n .replace(/^_/, \"\") + \"_FACET\";\n\n const condition = firstFacet ? \"if\" : \"else if\";\n source += ` ${condition} (keccak256(bytes(facetName)) == keccak256(bytes(\"${facetName}\"))) {\\n`;\n source += ` return ${constantName};\\n`;\n source += \" }\\n\";\n firstFacet = false;\n }\n source += \" return address(0);\\n\";\n source += \" }\\n\";\n\n source += \"}\\n\";\n\n return source;\n }\n}\n"]}
1
+ {"version":3,"file":"HelperGenerator.js","sourceRoot":"","sources":["../../src/framework/HelperGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["import { DeployedDiamondData } from \"@diamondslab/diamonds\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { HardhatRuntimeEnvironment } from \"hardhat/types\";\nimport { join } from \"path\";\nimport { Logger } from \"../utils/logger\";\n\n/**\n * HelperGenerator - Generates Solidity helper files for testing\n */\nexport class HelperGenerator {\n constructor(private hre: HardhatRuntimeEnvironment) {}\n\n /**\n * Scaffold project with initial test structure\n */\n async scaffoldProject(outputDir?: string): Promise<void> {\n const helpersDir = outputDir || this.hre.diamondsFoundry.helpersDir;\n const basePath = join(this.hre.config.paths.root, helpersDir);\n\n Logger.section(\"Scaffolding Forge Test Structure\");\n \n // Create directories\n Logger.step(\"Creating directories...\");\n mkdirSync(basePath, { recursive: true });\n mkdirSync(join(basePath, \"../unit\"), { recursive: true });\n mkdirSync(join(basePath, \"../integration\"), { recursive: true });\n mkdirSync(join(basePath, \"../fuzz\"), { recursive: true });\n\n Logger.success(`Test structure created at ${basePath}`);\n }\n\n /**\n * Generate DiamondDeployment.sol from deployment record\n */\n async generateDeploymentHelpers(\n diamondName: string,\n networkName: string,\n chainId: number,\n deploymentData: DeployedDiamondData\n ): Promise<string> {\n Logger.section(\"Generating Diamond Deployment Helper\");\n\n const helpersDir = this.hre.diamondsFoundry.helpersDir;\n const outputPath = join(\n this.hre.config.paths.root,\n helpersDir,\n \"DiamondDeployment.sol\"\n );\n\n const content = this.generateLibrarySource(\n diamondName,\n networkName,\n chainId,\n deploymentData\n );\n\n // Ensure directory exists\n mkdirSync(join(this.hre.config.paths.root, helpersDir), {\n recursive: true,\n });\n\n // Write file\n writeFileSync(outputPath, content, \"utf8\");\n\n Logger.success(`Generated: ${outputPath}`);\n return outputPath;\n }\n\n /**\n * Generate example test files\n */\n async generateExampleTests(): Promise<string[]> {\n const generated: string[] = [];\n const examples = this.hre.diamondsFoundry.exampleTests;\n\n if (!this.hre.diamondsFoundry.generateExamples) {\n Logger.info(\"Example generation disabled in config\");\n return generated;\n }\n\n Logger.section(\"Generating Example Tests\");\n\n const basePath = join(this.hre.config.paths.root, \"test\", \"foundry\");\n const templatesPath = join(__dirname, \"../templates\");\n\n for (const type of examples) {\n let templateFile = \"\";\n let outputPath = \"\";\n\n switch (type) {\n case \"unit\":\n templateFile = join(templatesPath, \"ExampleUnitTest.t.sol.template\");\n outputPath = join(basePath, \"unit\", \"ExampleUnit.t.sol\");\n break;\n case \"integration\":\n templateFile = join(templatesPath, \"ExampleIntegrationTest.t.sol.template\");\n outputPath = join(basePath, \"integration\", \"ExampleIntegration.t.sol\");\n break;\n case \"fuzz\":\n templateFile = join(templatesPath, \"ExampleFuzzTest.t.sol.template\");\n outputPath = join(basePath, \"fuzz\", \"ExampleFuzz.t.sol\");\n break;\n default:\n Logger.warn(`Unknown example type: ${type}`);\n continue;\n }\n\n try {\n // Check if template exists\n if (!existsSync(templateFile)) {\n Logger.warn(`Template not found: ${templateFile}`);\n continue;\n }\n\n // Read template content\n const templateContent = readFileSync(templateFile, \"utf8\");\n\n // Ensure output directory exists\n mkdirSync(join(basePath, type), { recursive: true });\n\n // Check if file already exists\n if (existsSync(outputPath)) {\n Logger.info(`Skipping ${type} example (already exists): ${outputPath}`);\n continue;\n }\n\n // Write example test file\n writeFileSync(outputPath, templateContent, \"utf8\");\n Logger.success(`Generated ${type} example: ${outputPath}`);\n generated.push(outputPath);\n } catch (error: any) {\n Logger.error(`Failed to generate ${type} example: ${error.message}`);\n }\n }\n\n if (generated.length === 0) {\n Logger.info(\"No new example tests generated (may already exist)\");\n }\n\n return generated;\n }\n\n /**\n * Generate Solidity library source from deployment data\n * @private\n */\n private generateLibrarySource(\n diamondName: string,\n networkName: string,\n chainId: number,\n deploymentData: DeployedDiamondData\n ): string {\n const timestamp = new Date().toISOString();\n const networkInfo = `${networkName}-${chainId}`;\n const deploymentFileName = `${diamondName.toLowerCase()}-${networkInfo}.json`;\n const deploymentFilePath = `diamonds/${diamondName}/deployments/${deploymentFileName}`;\n\n let source = \"\";\n\n // SPDX and pragma\n source += \"// SPDX-License-Identifier: MIT\\n\";\n source += \"pragma solidity ^0.8.19;\\n\\n\";\n\n // Header comments\n source += \"/**\\n\";\n source += ` * @title DiamondDeployment\\n`;\n source += ` * @notice Auto-generated deployment data for ${diamondName}\\n`;\n source += ` * @dev This library provides constants and helper functions for accessing\\n`;\n source += ` * deployment data in Forge tests. It is auto-generated from the deployment\\n`;\n source += ` * record and should not be edited manually.\\n`;\n source += ` *\\n`;\n source += ` * Generated from: ${deploymentFilePath}\\n`;\n source += ` * Generated at: ${timestamp}\\n`;\n source += ` *\\n`;\n source += ` * To regenerate this file:\\n`;\n source += ` * npx hardhat diamonds-forge:generate-helpers --diamond ${diamondName}\\n`;\n source += ` *\\n`;\n source += ` * ⚠️ DO NOT EDIT MANUALLY - Changes will be overwritten on next generation\\n`;\n source += \" */\\n\";\n source += \"library DiamondDeployment {\\n\";\n\n // Diamond name\n source += ` /// @notice Name of the Diamond contract\\n`;\n source += ` /// @dev Used for identifying the Diamond in tests\\n`;\n source += ` string constant DIAMOND_NAME = \"${diamondName}\";\\n\\n`;\n\n // Diamond ABI path\n source += ` /// @notice Path to the Diamond ABI file\\n`;\n source += ` /// @dev Used by DiamondFuzzBase to load ABI for testing\\n`;\n source += ` string constant DIAMOND_ABI_PATH = \"./diamond-abi/${diamondName}.json\";\\n\\n`;\n\n // Diamond address\n source += ` /// @notice Address of the deployed ${diamondName} contract\\n`;\n source += ` /// @dev This is the main Diamond proxy address\\n`;\n source += ` address constant DIAMOND_ADDRESS = ${deploymentData.DiamondAddress};\\n\\n`;\n\n // Deployer address\n source += ` /// @notice Address of the deployer account\\n`;\n source += ` /// @dev Account that deployed the Diamond\\n`;\n source += ` address constant DEPLOYER_ADDRESS = ${deploymentData.DeployerAddress};\\n\\n`;\n\n // Facet addresses\n source += \" // ========================================\\n\";\n source += \" // Facet Addresses\\n\";\n source += \" // ========================================\\n\\n\";\n\n const facets = deploymentData.DeployedFacets ?? {};\n for (const [facetName, facetData] of Object.entries(facets)) {\n const constantName = facetName\n .replace(/Facet$/, \"\")\n .replace(/([A-Z])/g, \"_$1\")\n .toUpperCase()\n .replace(/^_/, \"\") + \"_FACET\";\n\n source += ` /// @notice Address of ${facetName} implementation\\n`;\n source += ` address constant ${constantName} = ${facetData.address};\\n`;\n }\n source += \"\\n\";\n\n // Helper functions\n source += \" // ========================================\\n\";\n source += \" // Helper Functions\\n\";\n source += \" // ========================================\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get the Diamond name\\n\";\n source += \" * @return The name of the Diamond contract\\n\";\n source += \" */\\n\";\n source += \" function getDiamondName() internal pure returns (string memory) {\\n\";\n source += \" return DIAMOND_NAME;\\n\";\n source += \" }\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get the path to the Diamond ABI file\\n\";\n source += \" * @return The path to the Diamond ABI JSON file\\n\";\n source += \" */\\n\";\n source += \" function getDiamondABIPath() internal pure returns (string memory) {\\n\";\n source += \" return DIAMOND_ABI_PATH;\\n\";\n source += \" }\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get the Diamond contract address\\n\";\n source += \" * @return The address of the deployed Diamond proxy\\n\";\n source += \" */\\n\";\n source += \" function getDiamondAddress() internal pure returns (address) {\\n\";\n source += \" return DIAMOND_ADDRESS;\\n\";\n source += \" }\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get the deployer address\\n\";\n source += \" * @return The address of the deployer account\\n\";\n source += \" */\\n\";\n source += \" function getDeployerAddress() internal pure returns (address) {\\n\";\n source += \" return DEPLOYER_ADDRESS;\\n\";\n source += \" }\\n\\n\";\n\n source += \" /**\\n\";\n source += \" * @notice Get facet implementation address by name\\n\";\n source += \" * @param facetName The name of the facet\\n\";\n source += \" * @return The address of the facet implementation\\n\";\n source += \" */\\n\";\n source += \" function getFacetAddress(string memory facetName) internal pure returns (address) {\\n\";\n\n let firstFacet = true;\n for (const [facetName, facetData] of Object.entries(facets)) {\n const constantName = facetName\n .replace(/Facet$/, \"\")\n .replace(/([A-Z])/g, \"_$1\")\n .toUpperCase()\n .replace(/^_/, \"\") + \"_FACET\";\n\n const condition = firstFacet ? \"if\" : \"else if\";\n source += ` ${condition} (keccak256(bytes(facetName)) == keccak256(bytes(\"${facetName}\"))) {\\n`;\n source += ` return ${constantName};\\n`;\n source += \" }\\n\";\n firstFacet = false;\n }\n source += \" return address(0);\\n\";\n source += \" }\\n\";\n\n source += \"}\\n\";\n\n return source;\n }\n}\n"]}
@@ -0,0 +1,38 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ /**
5
+ * @title DiamondDeployment
6
+ * @notice Deployment data for {{DIAMOND_NAME}} on {{NETWORK_NAME}} (Chain ID: {{CHAIN_ID}})
7
+ * @dev Auto-generated by diamonds-hardhat-foundry
8
+ *
9
+ * Generated: {{TIMESTAMP}}
10
+ */
11
+ library DiamondDeployment {
12
+ // Diamond Contract Address
13
+ address constant DIAMOND_ADDRESS = {{DIAMOND_ADDRESS}};
14
+
15
+ // Deployer Address
16
+ address constant DEPLOYER_ADDRESS = {{DEPLOYER_ADDRESS}};
17
+
18
+ // Facet Addresses
19
+ {{FACET_ADDRESSES}}
20
+
21
+ /**
22
+ * @notice Get the Diamond contract address
23
+ * @return The address of the Diamond contract
24
+ */
25
+ function diamond() internal pure returns (address) {
26
+ return DIAMOND_ADDRESS;
27
+ }
28
+
29
+ /**
30
+ * @notice Get the deployer address
31
+ * @return The address that deployed the Diamond
32
+ */
33
+ function deployer() internal pure returns (address) {
34
+ return DEPLOYER_ADDRESS;
35
+ }
36
+
37
+ {{FACET_GETTERS}}
38
+ }
@@ -0,0 +1,118 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import "forge-std/Test.sol";
5
+ import "forge-std/console.sol";
6
+ import "@diamondslab/diamonds-hardhat-foundry/contracts/DiamondFuzzBase.sol";
7
+ import "@diamondslab/diamonds-hardhat-foundry/contracts/DiamondForgeHelpers.sol";
8
+ import "../helpers/DiamondDeployment.sol";
9
+
10
+ /**
11
+ * @title ExampleFuzzTest
12
+ * @notice Example fuzz test for Diamond contract
13
+ * @dev Uses DiamondFuzzBase for common fuzz testing utilities
14
+ */
15
+ contract ExampleFuzzTest is DiamondFuzzBase {
16
+ using DiamondForgeHelpers for address;
17
+
18
+ /// @notice Override to load Diamond from deployment
19
+ function _loadDiamondAddress() internal view override returns (address) {
20
+ return DiamondDeployment.diamond();
21
+ }
22
+
23
+ function setUp() public override {
24
+ super.setUp();
25
+
26
+ console.log("Fuzz test setup complete");
27
+ console.log("Diamond:", diamond);
28
+ console.log("Functions loaded:", diamondSelectors.length);
29
+ }
30
+
31
+ /**
32
+ * @notice Fuzz test with random address input
33
+ * @param randomAddress Fuzzed address parameter
34
+ */
35
+ function testFuzz_AddressInput(address randomAddress) public {
36
+ // Filter invalid addresses
37
+ vm.assume(DiamondForgeHelpers.isValidTestAddress(randomAddress));
38
+
39
+ // TODO: Test your Diamond function with fuzzed address
40
+ // Example:
41
+ // bytes4 selector = bytes4(keccak256("someFunction(address)"));
42
+ // bytes memory data = abi.encode(randomAddress);
43
+ // (bool success,) = _callDiamond(selector, data);
44
+ // assertTrue(success);
45
+
46
+ assertTrue(true, "Replace with actual fuzz test");
47
+ }
48
+
49
+ /**
50
+ * @notice Fuzz test with random amount input
51
+ * @param amount Fuzzed amount parameter
52
+ */
53
+ function testFuzz_AmountInput(uint256 amount) public {
54
+ // Bound the amount to valid range
55
+ vm.assume(DiamondForgeHelpers.isValidTestAmount(amount));
56
+
57
+ // TODO: Test your Diamond function with fuzzed amount
58
+ // Example:
59
+ // bytes4 selector = bytes4(keccak256("transfer(address,uint256)"));
60
+ // bytes memory data = abi.encode(user1, amount);
61
+ // (bool success,) = _callDiamond(selector, data);
62
+
63
+ assertTrue(true, "Replace with actual fuzz test");
64
+ }
65
+
66
+ /**
67
+ * @notice Fuzz test with multiple parameters
68
+ * @param addr Fuzzed address
69
+ * @param value Fuzzed value
70
+ * @param data Fuzzed bytes data
71
+ */
72
+ function testFuzz_MultipleParams(
73
+ address addr,
74
+ uint256 value,
75
+ bytes memory data
76
+ ) public {
77
+ // Filter inputs
78
+ vm.assume(DiamondForgeHelpers.isValidTestAddress(addr));
79
+ vm.assume(DiamondForgeHelpers.isValidTestAmount(value));
80
+ vm.assume(data.length > 0);
81
+ vm.assume(data.length < 1024); // Reasonable size limit
82
+
83
+ // TODO: Test with multiple fuzzed parameters
84
+
85
+ assertTrue(true, "Replace with actual multi-param fuzz test");
86
+ }
87
+
88
+ /**
89
+ * @notice Fuzz test for failure conditions
90
+ * @param badValue Value that should cause revert
91
+ */
92
+ function testFuzz_ExpectedRevert(uint256 badValue) public {
93
+ // Set up conditions for expected revert
94
+ vm.assume(badValue > type(uint128).max);
95
+
96
+ // TODO: Test that function reverts with invalid input
97
+ // bytes4 selector = bytes4(keccak256("someFunction(uint256)"));
98
+ // bytes memory data = abi.encode(badValue);
99
+ // _expectDiamondRevert(selector, data, bytes(""));
100
+
101
+ assertTrue(true, "Replace with actual revert fuzz test");
102
+ }
103
+
104
+ /**
105
+ * @notice Fuzz test with bounded values
106
+ * @param rawValue Raw fuzzed value
107
+ */
108
+ function testFuzz_BoundedValue(uint256 rawValue) public {
109
+ // Bound value to specific range (e.g., 1 to 1000)
110
+ uint256 boundedValue = bound(rawValue, 1, 1000);
111
+
112
+ // TODO: Test with bounded value
113
+ assertGe(boundedValue, 1, "Value should be >= 1");
114
+ assertLe(boundedValue, 1000, "Value should be <= 1000");
115
+
116
+ assertTrue(true, "Replace with actual bounded fuzz test");
117
+ }
118
+ }
@@ -0,0 +1,87 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import "forge-std/Test.sol";
5
+ import "forge-std/console.sol";
6
+ import "@diamondslab/diamonds-hardhat-foundry/contracts/DiamondForgeHelpers.sol";
7
+ import "@diamondslab/diamonds-hardhat-foundry/contracts/DiamondABILoader.sol";
8
+ import "../helpers/DiamondDeployment.sol";
9
+
10
+ /**
11
+ * @title ExampleIntegrationTest
12
+ * @notice Example integration test for Diamond contract
13
+ * @dev Tests interactions between multiple facets and Diamond functionality
14
+ */
15
+ contract ExampleIntegrationTest is Test {
16
+ using DiamondForgeHelpers for address;
17
+ using DiamondABILoader for string;
18
+
19
+ address diamond;
20
+ address deployer;
21
+
22
+ // Test users
23
+ address user1;
24
+ address user2;
25
+
26
+ function setUp() public {
27
+ // Load Diamond deployment data
28
+ diamond = DiamondDeployment.diamond();
29
+ deployer = DiamondDeployment.deployer();
30
+
31
+ // Validate Diamond
32
+ DiamondForgeHelpers.assertValidDiamond(diamond);
33
+
34
+ // Set up test users
35
+ user1 = makeAddr("user1");
36
+ user2 = makeAddr("user2");
37
+
38
+ // Fund test users
39
+ vm.deal(user1, 100 ether);
40
+ vm.deal(user2, 100 ether);
41
+
42
+ console.log("Diamond:", diamond);
43
+ console.log("User1:", user1);
44
+ console.log("User2:", user2);
45
+ }
46
+
47
+ /**
48
+ * @notice Test multi-facet interaction workflow
49
+ */
50
+ function test_MultiFacetWorkflow() public {
51
+ // TODO: Implement your multi-facet workflow test
52
+ // Example:
53
+ // 1. User1 calls function on Facet A
54
+ // 2. Verify state change
55
+ // 3. User2 calls function on Facet B
56
+ // 4. Verify combined state
57
+
58
+ vm.startPrank(user1);
59
+ // Your test logic here
60
+ vm.stopPrank();
61
+
62
+ assertTrue(true, "Replace with actual integration test");
63
+ }
64
+
65
+ /**
66
+ * @notice Test cross-facet state management
67
+ */
68
+ function test_CrossFacetState() public {
69
+ // TODO: Test that state is properly shared/isolated between facets
70
+
71
+ assertTrue(true, "Replace with actual state test");
72
+ }
73
+
74
+ /**
75
+ * @notice Test Diamond upgrade scenario (if applicable)
76
+ */
77
+ function test_DiamondUpgrade() public {
78
+ // TODO: Test facet addition/replacement/removal
79
+ // This requires diamondCut functionality
80
+
81
+ vm.startPrank(deployer);
82
+ // Your upgrade logic here
83
+ vm.stopPrank();
84
+
85
+ assertTrue(true, "Replace with actual upgrade test");
86
+ }
87
+ }
@@ -0,0 +1,65 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import "forge-std/Test.sol";
5
+ import "forge-std/console.sol";
6
+ import "@diamondslab/diamonds-hardhat-foundry/contracts/DiamondForgeHelpers.sol";
7
+ import "../helpers/DiamondDeployment.sol";
8
+
9
+ /**
10
+ * @title ExampleUnitTest
11
+ * @notice Example unit test for Diamond contract
12
+ * @dev This is a template - customize for your specific Diamond implementation
13
+ */
14
+ contract ExampleUnitTest is Test {
15
+ using DiamondForgeHelpers for address;
16
+
17
+ address diamond;
18
+ address deployer;
19
+
20
+ function setUp() public {
21
+ // Load Diamond deployment data
22
+ diamond = DiamondDeployment.diamond();
23
+ deployer = DiamondDeployment.deployer();
24
+
25
+ console.log("Diamond deployed at:", diamond);
26
+ console.log("Deployed by:", deployer);
27
+
28
+ // Validate Diamond deployment
29
+ DiamondForgeHelpers.assertValidDiamond(diamond);
30
+ }
31
+
32
+ /**
33
+ * @notice Test that Diamond was deployed successfully
34
+ */
35
+ function test_DiamondDeployed() public view {
36
+ // Check that Diamond address is not zero
37
+ assertNotEq(diamond, address(0), "Diamond address should not be zero");
38
+
39
+ // Check that Diamond has code
40
+ uint256 codeSize;
41
+ assembly {
42
+ codeSize := extcodesize(diamond)
43
+ }
44
+ assertGt(codeSize, 0, "Diamond should have code deployed");
45
+ }
46
+
47
+ /**
48
+ * @notice Test that deployer address is set correctly
49
+ */
50
+ function test_DeployerSet() public view {
51
+ assertNotEq(deployer, address(0), "Deployer address should not be zero");
52
+ }
53
+
54
+ /**
55
+ * @notice Example test - customize for your Diamond's functionality
56
+ */
57
+ function test_ExampleFunctionality() public {
58
+ // TODO: Add your Diamond-specific tests here
59
+ // Example:
60
+ // MyDiamond(diamond).someFunction();
61
+ // assertEq(result, expectedValue);
62
+
63
+ assertTrue(true, "Replace this with actual test");
64
+ }
65
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diamondslab/diamonds-hardhat-foundry",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Hardhat plugin that integrates Foundry testing with Diamond proxy contracts, providing deployment helpers and fuzzing support",
5
5
  "repository": {
6
6
  "type": "git",
@@ -179,6 +179,16 @@ export class HelperGenerator {
179
179
  source += " */\n";
180
180
  source += "library DiamondDeployment {\n";
181
181
 
182
+ // Diamond name
183
+ source += ` /// @notice Name of the Diamond contract\n`;
184
+ source += ` /// @dev Used for identifying the Diamond in tests\n`;
185
+ source += ` string constant DIAMOND_NAME = "${diamondName}";\n\n`;
186
+
187
+ // Diamond ABI path
188
+ source += ` /// @notice Path to the Diamond ABI file\n`;
189
+ source += ` /// @dev Used by DiamondFuzzBase to load ABI for testing\n`;
190
+ source += ` string constant DIAMOND_ABI_PATH = "./diamond-abi/${diamondName}.json";\n\n`;
191
+
182
192
  // Diamond address
183
193
  source += ` /// @notice Address of the deployed ${diamondName} contract\n`;
184
194
  source += ` /// @dev This is the main Diamond proxy address\n`;
@@ -212,6 +222,22 @@ export class HelperGenerator {
212
222
  source += " // Helper Functions\n";
213
223
  source += " // ========================================\n\n";
214
224
 
225
+ source += " /**\n";
226
+ source += " * @notice Get the Diamond name\n";
227
+ source += " * @return The name of the Diamond contract\n";
228
+ source += " */\n";
229
+ source += " function getDiamondName() internal pure returns (string memory) {\n";
230
+ source += " return DIAMOND_NAME;\n";
231
+ source += " }\n\n";
232
+
233
+ source += " /**\n";
234
+ source += " * @notice Get the path to the Diamond ABI file\n";
235
+ source += " * @return The path to the Diamond ABI JSON file\n";
236
+ source += " */\n";
237
+ source += " function getDiamondABIPath() internal pure returns (string memory) {\n";
238
+ source += " return DIAMOND_ABI_PATH;\n";
239
+ source += " }\n\n";
240
+
215
241
  source += " /**\n";
216
242
  source += " * @notice Get the Diamond contract address\n";
217
243
  source += " * @return The address of the deployed Diamond proxy\n";