Skip to content

[Defender Sunset] No migration path for CREATE2 deterministic deployments via hardhat-upgrades #1224

@SantiagoHoyos21

Description

@SantiagoHoyos21

Summary

Defender sunsets July 1, 2026. The official migration guide covers only Monitor and Relayer there is no migration guidance, no open-source replacement, and no announced plan for the Deploy module, specifically for teams using @openzeppelin/hardhat-upgrades with Defender as the CREATE2 backend for deterministic deployments across multiple EVM chains.

This is a critical gap. The plugin's CREATE2 support is architecturally coupled to Defender's backend. Without it, there is no way to perform deterministic cross-chain deployments using the current hardhat-upgrades API.


My Current Setup

// hardhat.config.ts
import "@openzeppelin/hardhat-upgrades";

const config: HardhatUserConfig = {
  // 15+ EVM networks (Ethereum, Polygon, Optimism, Arbitrum, Base, Avalanche, Celo, BNB, Ink, + testnets)
  defender: {
    apiKey: DEFENDER_API_KEY as string,
    apiSecret: DEFENDER_API_SECRET as string,
  },
};

I rely on these methods with a salt parameter for deterministic addresses across all chains:

  • hardhat.defender.deployContract() — Non-upgradeable contracts via CREATE2
  • hardhat.defender.deployProxy() — Upgradeable proxies (TransparentUpgradeableProxy) via CREATE2
  • hardhat.defender.deployImplementation() — Implementation contracts via CREATE2

Having the same contract address on every chain is a core architectural requirement.


The Problem

  1. No open-source replacement for Deploy. The sunset FAQ lists preserved capabilities as "transaction relaying, real-time alerts, automation." Deployment is not mentioned. Neither OpenZeppelin Relayer nor Monitor handles contract deployment.

  2. hardhat-upgrades CREATE2 only works through Defender. The plugin's only alternative is ethers.js signer deployments, which use the CREATE opcode, nonce-dependent and not deterministic across chains. After July 2026, the CREATE2 path simply stops working.

  3. Hardhat Upgrades v4 alpha (4.0.0-alpha.0) does not address this. No mention of Defender, CREATE2, or any alternative deployment backend.

  4. Switching to a third-party CREATE2 factory breaks address consistency. Defender uses its own internal factory contract (likely Safe's CreateCall based on documented function signatures). The CREATE2 address formula is keccak256(0xff ++ factory_address ++ salt ++ keccak256(init_code)), meaning the factory address is part of the derived address. If I migrate to any other CREATE2 factory (Arachnid's deployer, Safe SingletonFactory, CreateX, or a custom contract), even using the exact same salt and bytecode, all resulting addresses will be different because the factory address changed. This means:

    • New deployments would produce addresses inconsistent with my existing contracts already deployed via Defender
    • There is no way to achieve continuity without knowing and reusing the exact same factory Defender uses internally
    • The factory address is managed server-side and not publicly documented

Questions for the OpenZeppelin Team

  1. Is there a planned open-source replacement for Defender's Deploy module? Specifically for CREATE2 deterministic deployments. If so, what's the timeline?

  2. Will hardhat-upgrades support CREATE2 without Defender? For example, by allowing a configurable CREATE2 factory contract as a deployment backend.

  3. What is the exact CREATE2 factory contract address that Defender uses on each network? This is critical for teams that need to verify existing addresses or build migration scripts that preserve address consistency.

  4. What is the recommended migration path today for teams using deployProxy(), deployContract(), and deployImplementation() with salt across 15+ chains, who cannot modify contract code?


Workarounds Identified (none are drop-in replacements)

Approach Issue
Arachnid's deployer (0x4e59...56C) Different factory address → different derived addresses. No hardhat-upgrades integration. Fails on chains rejecting pre-EIP-155 txs.
Safe SingletonFactory (0x914d...3d7) Different factory address → different derived addresses. No hardhat-upgrades integration.
CreateX (0xba5E...5Ed) Different factory address → different derived addresses. Has xdeployer plugin but no manifest integration.
Manual deploy + forceImport() Significant refactor. Still produces different addresses unless using Defender's exact factory.

All workarounds share the same fundamental problem: using a different factory contract than Defender's means losing address determinism continuity with existing deployments. None integrate with hardhat-upgrades' proxy tracking, upgrade safety checks, or deployment manifest.


Expected Outcome

One of:

  • An open-source tool or updated hardhat-upgrades plugin that supports CREATE2 via configurable factory contracts without Defender
  • Documentation of the exact factory contracts and bytecode handling Defender uses, so teams can build migration scripts preserving address consistency
  • A clear timeline for when this will be addressed

The Deploy module is sunsetting with no replacement and no migration guide, leaving teams with a hard deadline and no official path forward for one of Defender's most critical features.

Any help would be appreciated! Thank you in advance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions