Assessment reports>cyberRaise>Low findings>DealManager could store different ,counterPartyValues, from those in the agreement
Category: Business Logic

DealManager could store different counterPartyValues from those in the agreement

Low Impact
Low Severity
Medium Likelihood

Description

The signAndFinalizeDeal function in DealManager skips calling signContractFor when the signer has already signed in the registry:

function signAndFinalizeDeal(
    address signer,
    bytes32 agreementId,
    string[] memory partyValues,
    bytes memory signature,
    bool _fillUnallocated,
    string memory name,
    string memory secret
) public {
    // [...]
    if(!ICyberAgreementRegistry(LexScrowStorage.getDealRegistry())
       .hasSigned(agreementId, signer)) {
        ICyberAgreementRegistry(LexScrowStorage.getDealRegistry())
            .signContractFor(signer, agreementId, partyValues, 
                        signature, _fillUnallocated, secret);
    }
    updateEscrow(agreementId, msg.sender, name);
    if(!conditionCheck(agreementId)) revert AgreementConditionsNotMet();
    handleCounterPartyPayment(agreementId);
    finalizeDeal(agreementId);
}

This logic allows the counterparty to create inconsistent counterPartyValues between DealManager and CyberAgreementRegistry when a deal leaves counterPartyValues unset. The attack proceeds as follows:

  1. The counterparty calls signContractFor in CyberAgreementRegistry directly with one set of partyValues.

  2. The counterparty then calls signAndFinalizeDeal in DealManager with a different set of partyValues.

Because signAndFinalizeDeal skips calling signContractFor when the signer has already signed in the registry, the function proceeds to update its local storage with the new partyValues without revalidation. This creates a state divergence; the partyValues stored in DealManager differ from those stored in CyberAgreementRegistry, leaving the two contracts with inconsistent records of counterPartyValues for the same agreement.

Impact

The on-chain registry and DealManager can disagree on the counterPartyValues. Downstream systems relying on counterPartyValues in DealManager will read manipulated data, enabling misreporting or bypassing business logic that expects consistency with the registry.

Recommendations

When signAndFinalizeDeal detects an existing signer, fetch the signer's partyValues from CyberAgreementRegistry and enforce equality before finalizing.

Remediation

This issue has been acknowledged by MetaLex, and fixes were implemented in the following commits:

Zellic © 2025Back to top ↑