DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: medium
Valid

Improper implementation of `BLUEPRINT_TYPE_HASH` can lead to issues when verifying requisitions

Summary

The BLUEPRINT_TYPE_HASHis not properly encoded according to EIP-712 standard and will lead to integration issues when EIP compliant signers try to access various blueprint requisition functions.

Vulnerability Details

In LibTractor.sol, the BLUEPRINT_TYPE_HASH is declared. Important to notice the encoding of bytes operatorData as its third parameter.

bytes32 public constant BLUEPRINT_TYPE_HASH =
keccak256(
"Blueprint(address publisher,bytes data,bytes operatorData,uint256 maxNonce,uint256 startTime,uint256 endTime)"
);

This is incorrect as the BLUEPRINT_TYPE_HASH exists as an EIP-712 hash of the Blueprint struct, and the third parameter is the bytes32[] operatorPasteInstrs which is of a significantly different type to the parameter encoded in the type hash.

struct Blueprint {
address publisher;
bytes data;
bytes32[] operatorPasteInstrs;
uint256 maxNonce;
uint256 startTime;
uint256 endTime;
}

As a result, when the blueprint hash is calculated, the returned has will be incorrect due to the use of incorrect typehashes and users/integrations that use "correct" typehashes that match the parameters of these functions will end up generating different signatures, causing them to revert when called.

function _getBlueprintHash(Blueprint calldata blueprint) internal view returns (bytes32) {
return
_hashTypedDataV4(
keccak256(
abi.encode(
BLUEPRINT_TYPE_HASH,
blueprint.publisher,
keccak256(blueprint.data),
keccak256(abi.encodePacked(blueprint.operatorPasteInstrs)),
blueprint.maxNonce,
blueprint.startTime,
blueprint.endTime
)
)
);
}

Impact

The hash is not EIP-712 compliant, hence transactions implementing EIP-712 signatures correctly will revert as their on-chain counterpart will be different.

It is being used in the verifyRequisition modifier in the TractorFacet.sol, which is used when publishing, cancelling and executing a tractor blueprint. Since this is basically the entire function of TractorFacet.sol, not being able to perform this makes the contract completely almost unusable, hence the high severity.

modifier verifyRequisition(LibTractor.Requisition calldata requisition) {
bytes32 blueprintHash = LibTractor._getBlueprintHash(requisition.blueprint);
require(blueprintHash == requisition.blueprintHash, "TractorFacet: invalid hash");
address signer = ECDSA.recover(
MessageHashUtils.toEthSignedMessageHash(requisition.blueprintHash),
requisition.signature
);
require(signer == requisition.blueprint.publisher, "TractorFacet: signer mismatch");
_;
}

Tools Used

Manual Review

Recommendations

Recommend changing the BLUEPRINT_TYPE_HASHto this.

bytes32 public constant BLUEPRINT_TYPE_HASH =
keccak256(
"Blueprint(address publisher,bytes data,bytes32[] operatorPasteInstrs,uint256 maxNonce,uint256 startTime,uint256 endTime)"
);
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

The declaration and use of `LibTractor::BLUEPRINT_TYPE_HASH` is inconsistent with the field name of the structure `struct Blueprint`

Appeal created

inh3l Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

The declaration and use of `LibTractor::BLUEPRINT_TYPE_HASH` is inconsistent with the field name of the structure `struct Blueprint`

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.