Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: high
Invalid

Front-Running can lead to Denial of Service in offer creation

Relevant GitHub Links

https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L67-L69
https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L83

Summary

The linear incrementation of offerId in PreMarkets.createOffer() with offerId = offerId + 1 exposes a vulnerability where a malicious user can front-run and capture the intended offerId before the legitimate user. This results in the legitimate offer creation being reverted, effectively blocking the intended offer.

Vulnerability Details

PreMarkets.createOffer() simply determines offerId by incrementing it sequentially, ignoring offer params and the sender;

/// @dev generate address for maker, offer, stock.
address makerAddr = GenerateAddress.generateMakerAddress(offerId);
address offerAddr = GenerateAddress.generateOfferAddress(offerId);
address stockAddr = GenerateAddress.generateStockAddress(offerId);
if (makerInfoMap[makerAddr].authority != address(0x0)) {
revert MakerAlreadyExist();
}
if (offerInfoMap[offerAddr].authority != address(0x0)) {
revert OfferAlreadyExist();
}
if (stockInfoMap[stockAddr].authority != address(0x0)) {
revert StockAlreadyExist();
}
offerId = offerId + 1;

The functions in the GenerateAddress library generate specific addresses based solely on the offerId;

/// @dev Generate address for maker address with id
function generateMakerAddress(uint256 _id) internal pure returns (address) {
return address(uint160(uint256(keccak256(abi.encode(_id, "maker")))));
}
/// @dev Generate address for offer address with id
function generateOfferAddress(uint256 _id) internal pure returns (address) {
return address(uint160(uint256(keccak256(abi.encode(_id, "offer")))));
}
/// @dev Generate address for stock address with id
function generateStockAddress(uint256 _id) internal pure returns (address) {
return address(uint160(uint256(keccak256(abi.encode(_id, "stock")))));
}

For this reason, createOffer is vulnerable to frontrunning and since the parameters are not taken into account, the attacker does not have to make the same offer. Thus, the attack is not costly.

Impact

A malicious actor can block legitimate users from creating offers, leading to potential Denial of Service (DoS) attacks and market manipulation by controlling which offers are available, ultimately causing a loss of user trust in the platform's fairness.

Tools Used

Foundry

Recommendations

If we create the offerId using offer parameters, we would need to fundamentally change the system, and it could still be vulnerable to DoS attacks using the same parameters. Instead, a simpler solution would be to consider using msg.sender in addition to the _id for address generation in the GenerateAddress library (e.g., by hashing or directly using the sender address). This way, even if another user front-runs the transaction, the addresses will not match.

Updates

Lead Judging Commences

0xnevi Lead Judge
about 1 year ago
0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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