CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-hardhat-deploy

Hardhat plugin providing comprehensive deployment system for Ethereum smart contracts with replicable deployments and enhanced testing capabilities.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

diamond-deployment.mddocs/

Diamond Deployment

Full EIP-2535 diamond pattern implementation with automatic facet management, upgrade detection, and deterministic deployment support.

Capabilities

Diamond Deploy Function

Deploy diamond contracts with facet management and automatic upgrade handling.

/**
 * Deploy a diamond contract with specified facets
 * @param name - Diamond deployment name
 * @param options - Diamond deployment configuration
 * @returns Promise resolving to deployment result
 */
diamond: {
  deploy(name: string, options: DiamondOptions): Promise<DeployResult>;
}

interface DiamondOptions extends TxOptions {
  /** Owner address for the diamond */
  owner?: Address;
  /** Array of facets to deploy/configure */
  facets: DiamondFacets;
  /** Custom diamond contract to use as base */
  diamondContract?: string | ArtifactData;
  /** Diamond constructor arguments */
  diamondContractArgs?: any[];
  /** Include default DiamondCutFacet */
  defaultCutFacet?: boolean;
  /** Include default OwnershipFacet */
  defaultOwnershipFacet?: boolean;
  /** Include default DiamondLoupeFacet */
  defaultLoupeFacet?: boolean;
  /** Initialization execution after deployment */
  execute?: {
    contract?:
      | string
      | { name: string; artifact: string | ArtifactData; args?: any[] };
    methodName: string;
    args: any[];
  };
  /** Exclude specific selectors from facets */
  excludeSelectors?: {
    [facetName: string]: string[];
  };
  /** Salt for deterministic diamond deployment */
  deterministicSalt?: string;
  /** Constructor arguments for all facets */
  facetsArgs?: any[];
  /** Libraries for linking */
  libraries?: Libraries;
  /** Additional data for tracking */
  linkedData?: any;
  /** Upgrade tracking index */
  upgradeIndex?: number;
}

Usage Examples:

import { deployments, getNamedAccounts } from "hardhat";

// Basic diamond deployment
const { deployer } = await getNamedAccounts();
await deployments.diamond.deploy("GameDiamond", {
  from: deployer,
  owner: deployer,
  facets: [
    "PlayerFacet",
    "InventoryFacet",
    "BattleFacet",
  ],
});

// Diamond with custom facet configurations
await deployments.diamond.deploy("AdvancedDiamond", {
  from: deployer,
  owner: deployer,
  facets: [
    {
      name: "CustomPlayerFacet",
      contract: "PlayerFacetV2",
      args: ["player", "init", "args"],
    },
    {
      name: "InventoryFacet",
      deterministic: true,
    },
    "BattleFacet", // Simple string facet
  ],
  execute: {
    methodName: "initialize",
    args: ["diamond", "initialization"],
  },
});

// Diamond with excluded selectors
await deployments.diamond.deploy("SelectiveDiamond", {
  from: deployer,
  owner: deployer,
  facets: ["ComprehensiveFacet"],
  excludeSelectors: {
    ComprehensiveFacet: ["deprecatedFunction()", "internalFunction()"],
  },
});

Facet Configuration

Configure individual facets with specific deployment options and arguments.

type DiamondFacets = Array<string | FacetOptions>;

interface FacetOptions {
  /** Custom name for the facet deployment */
  name?: string;
  /** Contract artifact name or data */
  contract?: string | ArtifactData;
  /** Constructor arguments for this facet */
  args?: any[];
  /** Additional data for this facet */
  linkedData?: any;
  /** Libraries for this facet */
  libraries?: Libraries;
  /** Enable deterministic deployment */
  deterministic?: boolean | string;
}

Usage Examples:

// Mixed facet configuration
await deployments.diamond.deploy("FlexibleDiamond", {
  from: deployer,
  owner: deployer,
  facets: [
    // Simple string facet
    "CoreFacet",
    
    // Facet with custom configuration
    {
      name: "ConfigurableFacet",
      contract: "AdvancedFacet",
      args: ["custom", "constructor", "args"],
      deterministic: true,
    },
    
    // Facet with libraries
    {
      name: "LibraryFacet",
      contract: "FacetWithLibrary",
      libraries: {
        MathLib: "0x1234567890123456789012345678901234567890",
      },
    },
    
    // Facet with custom artifact
    {
      name: "CustomFacet",
      contract: {
        abi: [...], // Custom ABI
        bytecode: "0x...", // Custom bytecode
      },
      args: [],
    },
  ],
});

// Deterministic facet deployment
await deployments.diamond.deploy("DeterministicDiamond", {
  from: deployer,
  owner: deployer,
  deterministicSalt: "0x1234567890123456789012345678901234567890123456789012345678901234",
  facets: [
    {
      name: "FacetA",
      deterministic: "0x1111111111111111111111111111111111111111111111111111111111111111",
    },
    {
      name: "FacetB",
      deterministic: true, // Uses default salt
    },
  ],
});

Diamond Upgrades

Automatic facet upgrade detection and diamond cut execution.

Usage Examples:

// Upgrade tracking
await deployments.diamond.deploy("UpgradeableDiamond", {
  from: deployer,
  owner: deployer,
  upgradeIndex: 2, // Only upgrade if current version < 2
  facets: [
    "FacetV1",
    "FacetV2", // New facet for upgrade
  ],
});

// Post-upgrade execution
await deployments.diamond.deploy("InitializableDiamond", {
  from: deployer,
  owner: deployer,
  facets: ["DataFacet", "LogicFacet"],
  execute: {
    contract: {
      name: "DiamondInit",
      artifact: "InitializationContract",
      args: ["init", "contract", "args"],
    },
    methodName: "init",
    args: ["post", "upgrade", "data"],
  },
});

// Custom diamond base contract
await deployments.diamond.deploy("CustomBaseDiamond", {
  from: deployer,
  owner: deployer,
  diamondContract: "MyCustomDiamond",
  diamondContractArgs: ["{owner}", "{facetCuts}", "{init}"],
  facets: ["MyFacet"],
});

Facet Management

Control default facets and selector exclusions.

Usage Examples:

// Minimal diamond (no default facets)
await deployments.diamond.deploy("MinimalDiamond", {
  from: deployer,
  owner: deployer,
  defaultCutFacet: false,
  defaultOwnershipFacet: false,
  defaultLoupeFacet: true, // Keep only loupe for introspection
  facets: ["BusinessLogicFacet"],
});

// Diamond with selector exclusions
await deployments.diamond.deploy("FilteredDiamond", {
  from: deployer,
  owner: deployer,
  facets: [
    "MultiFunctionFacet",
    "AnotherFacet",
  ],
  excludeSelectors: {
    MultiFunctionFacet: [
      "dangerousFunction()",
      "deprecatedFunction(uint256)",
    ],
    AnotherFacet: [
      "internalHelper()",
    ],
  },
});

// Global facet arguments
await deployments.diamond.deploy("UniformDiamond", {
  from: deployer,
  owner: deployer,
  facetsArgs: ["shared", "constructor", "args"], // Used by all facets
  facets: [
    "FacetA", // Will use facetsArgs
    "FacetB", // Will use facetsArgs
    {
      name: "FacetC",
      args: ["custom", "args"], // Overrides facetsArgs
    },
  ],
});

Types

interface DiamondOptions extends TxOptions {
  owner?: Address;
  facets: DiamondFacets;
  diamondContract?: string | ArtifactData;
  diamondContractArgs?: any[];
  defaultCutFacet?: boolean;
  defaultOwnershipFacet?: boolean;
  execute?: {
    contract?:
      | string
      | { name: string; artifact: string | ArtifactData; args?: any[] };
    methodName: string;
    args: any[];
  };
  excludeSelectors?: {
    [facetName: string]: string[];
  };
  deterministicSalt?: string;
  facetsArgs?: any[];
  libraries?: Libraries;
  linkedData?: any;
  upgradeIndex?: number;
}

type DiamondFacets = Array<string | FacetOptions>;

interface FacetOptions {
  name?: string;
  contract?: string | ArtifactData;
  args?: any[];
  linkedData?: any;
  libraries?: Libraries;
  deterministic?: boolean | string;
}

interface Facet {
  facetAddress: string;
  functionSelectors: string[];
}

interface FacetCut extends Facet {
  action: FacetCutAction;
}

enum FacetCutAction {
  Add,
  Replace,
  Remove,
}

interface TxOptions extends CallOptions {
  from: string;
  log?: boolean;
  autoMine?: boolean;
  estimatedGasLimit?: string | number | BigNumber;
  estimateGasExtra?: string | number | BigNumber;
  waitConfirmations?: number;
}

type Libraries = { [libraryName: string]: Address };
type Address = string;
type ABI = any[];

docs

contract-interaction.md

core-deployment.md

deployment-management.md

diamond-deployment.md

index.md

named-accounts.md

proxy-deployment.md

test-fixtures.md

verification.md

tile.json