Assessment reports>SSI Protocol>Low findings>Lack of domain separation allows signature replay
Category: Coding Mistakes

Lack of domain separation allows signature replay

Low Impact
Medium Severity
Low Likelihood

Description

The checkOrderInfo of a Swap contract is used to check the validity of an order by verifying it was signed by its maker address. To prevent replay, the order hash is stored in the Swap contract, and an order is not accepted if its hash has been already validated. The signature is verified with the function SignatureChecker.isValidSignatureNow from the OpenZepplin library:

function checkOrderInfo(OrderInfo memory orderInfo) public view returns (uint) {
    if (block.timestamp >= orderInfo.order.deadline) {
        return 1;
    }
    bytes32 orderHash = keccak256(abi.encode(orderInfo.order));
    if (orderHash != orderInfo.orderHash) {
        return 2;
    }
    if (!SignatureChecker.isValidSignatureNow(orderInfo.order.maker, orderHash, orderInfo.orderSign)) {
        return 3;
    }
    if (orderHashs.contains(orderHash)) {
        return 4;
    }
    // ...

This function checks if a hash was properly signed by the given address. However, the hash does not include any domain separation. Thus, the same signature can be replayed to other Swap contracts and the order will be seen as valid.

Impact

The AssetFactory contract stores the swap associated to each asset token. If two different asset tokens have different Swap contracts, then an order signature can be replayed to the addMintRequest function and will be seen as valid. The Swap can also be changed with the setSwap function. For a new Swap, all previous orders could be replayed as well. The two swap requests for two different assets will be placed even if a single order was validated.

Another less critical problem is also a lack of domain separation between Swap and USSI signatures. Swap verifies the Order structure and the USSI verifies the HedgeOrder struct. Fortunately, the two structures are different and one signature cannot be replayed to another contract. However, it is a good practice to have domain separation, to avoid reusing one signature from a contract to another.

Recommendations

The hash should include the Swap contract address to prevent this replay, like in EIP-712.

Remediation

Zellic © 2025Back to top ↑