Skip to content

Public raw-ciphertext transfers bypass ciphertext validation #126

@this-vishalsingh

Description

@this-vishalsingh

Context: contracts/experimental/token/FHERC20/FHERC20.sol
Severity: INFO

Description

The contract exposes underscore-prefixed functions _transferEncrypted and _transferFromEncrypted as public and they accept euint128 directly. Unlike the inEuint128-based entrypoints (transferEncrypted/transferFromEncrypted), passing euint128 bypasses FHE.asEuint128(inEuint128) verification of user-supplied ciphertext bytes (which is intended to validate ciphertext correctness and security zone).

If the underlying FHE runtime does not strictly bind ciphertext handles to the calling contract and validate them on every operation, an attacker could pass crafted/foreign ciphertext handles to influence comparisons (lte/gte) and arithmetic in unexpected ways (e.g., forcing transfers of unintended amounts or causing runtime reverts). Even if the runtime is robust, leaving these as public increases the attack surface and makes it easier to accidentally integrate the unsafe entrypoints.

If an attacker calls _transferFromEncrypted directly with a malformed euint128 handle, potentially triggering a precompile revert during FHE operations and breaking higher-level batching/multicall workflows that include FHERC20 interactions.

function _transferFromEncrypted(address from, address to, euint128 value) public virtual returns (euint128) {
    euint128 val = value;
    euint128 spent = _spendAllowance(from, msg.sender, val);
    return _transferImpl(from, to, spent);
}

// Transfers an amount from the message sender address to the `to` address.
function _transferEncrypted(address to, euint128 amount) public returns (euint128) {
    return _transferImpl(msg.sender, to, amount);
}

Recommendation

Make _transferEncrypted and _transferFromEncrypted internal (or private) and keep only the inEuint128-validated public entrypoints.
If external raw-ciphertext entrypoints are required, explicitly validate the ciphertext (e.g., by requiring inEuint128 input) and document supported security zones.
Impacted Code (L66-L111):

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