Skip to content

Add _disableInitializers() to L2BTCRedeemerWormhole once hardhat-upgrades is bumped #954

@piotr-roslaniec

Description

@piotr-roslaniec

Context

PR #953 lands _disableInitializers() on L2WormholeGateway and L2TBTC but defers it on L2BTCRedeemerWormhole.sol. Adding the constructor pushes the creation bytecode past a size threshold that triggers a bug in @openzeppelin/hardhat-upgrades@1.22.0 / @openzeppelin/upgrades-core@1.20.0: the plugin's version-matching loop splices unrelated link references into our bytecode and corrupts the hex-validity check, breaking every deployProxy call in the test suite.

See inline `NOTE` in https://github.com/threshold-network/tbtc-v2/blob/feature/evm-l2-fee-waivers/solidity/contracts/cross-chain/wormhole/L2BTCRedeemerWormhole.sol for details.

Impact

Residual: an attacker can initialize the implementation contract directly and become its `owner`. The contracts use a transparent proxy, so user funds are unaffected; this only creates an orphan logic-contract shell that could cause phishing/confusion.

Fix

Once `@openzeppelin/hardhat-upgrades` is upgraded past the bug:

  1. Restore the constructor:
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }
  2. Re-add the `L2BTCRedeemerWormhole` describe block that was removed from solidity/test/cross-chain/wormhole/L2ImplementationInitializerLock.test.ts.
  3. Remove the `NOTE` block in the contract source.

The test suite in PR #953 already exercises the lock for the other two L2 contracts, so the regression coverage pattern is established.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions