DealManager could store different counterPartyValues from those in the agreement
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:
The counterparty calls
signContractForin CyberAgreementRegistry directly with one set ofpartyValues.The counterparty then calls
signAndFinalizeDealin DealManager with a different set ofpartyValues.
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: