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

Constant chain id lead to replay attack in several librairies

Description

Several libraries use C.getChainId() to retrieve the chain ID, which is a constant variable, and create a non-replayable signature. This mechanism is employed to create permit functions, which allows a user to execute a transaction on behalf of another user. Including the chain ID in this signature prevents a user from replaying the sametransaction on other chains.

The issue here is that this variable is a constant and will require an update to change it. Deploying on other chains would not pose a problem, but since Beanstalk is a protocol expected to endure, there is a possibility of a chain fork. This means that the entire chain, including the smart contracts, would be duplicated. In such a case, the constant would remain the same until the protocol updates the C contract on the new chain. This would leave a considerable window of time for an attacker to replay all the transactions generated for the permit functions and the tractor, if those transactions have not yet passed their deadline.

LibTractor :

function _domainSeparatorV4() internal view returns (bytes32) {
return
keccak256(
abi.encode(
BLUEPRINT_TYPE_HASH,
TRACTOR_HASHED_NAME,
TRACTOR_HASHED_VERSION,
C.getChainId(),
address(this)
)
);
}

LibSiloPermit:

function _buildDomainSeparator(
bytes32 typeHash,
bytes32 name,
bytes32 version
) internal view returns (bytes32) {
return keccak256(abi.encode(typeHash, name, version, C.getChainId(), address(this)));
}

LibTokenPermit:

function _buildDomainSeparator(
bytes32 typeHash,
bytes32 name,
bytes32 version
) internal view returns (bytes32) {
return keccak256(abi.encode(typeHash, name, version, C.getChainId(), address(this)));
}

Risk

Likelyhood: Low

  • If the deployment chain is forked.

  • Affect all the transaction that have not yet passed their deadline.

Impact: High

  • Replay attack on permit functions: theft of tokens

  • Replay attack on tractor: numerous possible impacts depending on the transaction created, such as theft of tokens, simultaneous execution of all transactions to attempt to depeg, etc.

Recommended Mitigation

Use block.chainid instead of storing a constant variable.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

Replay attack in case of hard fork - Hardcoded chainId 712

Support

FAQs

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