Skip to content

fix(RedactCore): reject zero address in deployConfidentialERC20#53

Open
amathxbt wants to merge 1 commit intoFhenixProtocol:masterfrom
amathxbt:fix/deploy-confidential-erc20-zero-address
Open

fix(RedactCore): reject zero address in deployConfidentialERC20#53
amathxbt wants to merge 1 commit intoFhenixProtocol:masterfrom
amathxbt:fix/deploy-confidential-erc20-zero-address

Conversation

@amathxbt
Copy link
Copy Markdown

@amathxbt amathxbt commented May 3, 2026

Summary

deployConfidentialERC20 is a permissionless factory function — anyone can call it. It currently checks only that the token is not WETH and has not already been deployed, but it does not check that erc20 != address(0).

Bug

function deployConfidentialERC20(IERC20 erc20) public returns (address) {
    if (address(erc20) == address(wETH)) revert InvalidWETH();
    if (_confidentialERC20Map.contains(address(erc20))) revert AlreadyDeployed();
    // ↑ No zero-address check! address(0) passes both guards.

    bytes memory initData = abi.encodeCall(ConfidentialERC20.initialize, (erc20));
    ERC1967Proxy proxy = new ERC1967Proxy(confidentialERC20Implementation, initData);
    // ConfidentialERC20.initialize does not revert for address(0) —
    // IERC20Metadata(address(0)).name() would revert, but _isFHERC20(address(0))
    // catches that and returns false, so initialize proceeds.

    _confidentialERC20Map.set(address(erc20), address(proxy));
    // ← address(0) is now permanently registered in the EnumerableMap.
    ...
}

Impact:

  • The address(0) slot in _confidentialERC20Map is permanently poisoned — it cannot be removed.
  • getConfidentialERC20(address(0)) returns a non-zero address, creating a potential false-positive in any code that uses zero-address as a sentinel.
  • The AlreadyDeployed guard then prevents anyone from attempting to fix it with a second call.

Fix

Add if (address(erc20) == address(0)) revert InvalidERC20(); as the first check in the function.

dployConfidentialERC20 is permissionlessly callable by anyone. Without a
zero-address check, a caller can pass address(0) as the ERC20 token,
which successfully deploys a ConfidentialERC20 proxy (ConfidentialERC20
.initialize only checks that the token is not itself an FHERC20) and
registers the mapping entry address(0) → proxy. This permanently
occupies the zero-address slot in EnumerableMap and can never be
removed, and any future code that checks whether address(0) has a
confidential wrapper would receive a non-zero result, causing silent
misbehaviour. Add a revert with the new InvalidERC20 error.
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 3, 2026

@amathxbt is attempting to deploy a commit to the Fhenix Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant