Platform: Code4rena
Start Date: 17/03/2023
Pot Size: $36,500 USDC
Total HM: 10
Participants: 98
Period: 3 days
Judge: leastwood
Total Solo HM: 5
Id: 223
League: ETH
Rank: 39/98
Findings: 2
Award: $42.70
🌟 Selected for report: 0
🚀 Solo Findings: 0
19.9329 USDC - $19.93
The buy
function generates new trays and stores them in the tiles
mapping based on the value of lastHash
. Since the value of lastHash
is publicly accessible and can be predicted, an attacker could potentially front-run other users to mint specific trays.
An attacker could monitor the value of lastHash
and calculate the trays that will be generated. If they find a valuable tray, they can front-run other users by submitting a transaction with a higher gas price to ensure they mint that specific tray before others. This would give them an unfair advantage in obtaining valuable trays, undermining the fairness of the system.
Manual review
To mitigate the potential front-running attacks in the buy
function, a commit-reveal scheme can be implemented. This scheme adds a layer of unpredictability to the tray generation process, making it more difficult for an attacker to front-run other users. Here's a high-level overview of how to implement the commit-reveal scheme:
mapping(address => bytes32) public commitments;
function commit(bytes32 _commitment) external { commitments[msg.sender] = _commitment; }
Here, _commitment
is the hash of a secret value (chosen by the user) concatenated with a random nonce. This commitment is stored in the commitments
mapping.
buy
function to accept a secret value and a nonce as parameters:function buy(uint256 _amount, uint256 _secret, uint256 _nonce) external { ... }
buy
function, verify that the commitment is valid before generating trays:bytes32 expectedCommitment = keccak256(abi.encodePacked(_secret, _nonce)); require(commitments[msg.sender] == expectedCommitment, "Invalid commitment");
lastHash = keccak256(abi.encode(lastHash, _secret)); trayTiledata[j] = _drawing(uint256(lastHash));
. 6. Clear the user's commitment after successfully generating trays:
commitments[msg.sender] = bytes32(0);
This commit-reveal scheme requires users to first commit their intent to buy trays, and then reveal their secret value and nonce when actually buying the trays. The secret value is used as an additional input to the tray generation process, making it more difficult for attackers to predict and front-run specific trays
#0 - c4-judge
2023-03-28T18:46:48Z
0xleastwood marked the issue as duplicate of #121
#1 - c4-judge
2023-04-11T19:54:06Z
0xleastwood marked the issue as satisfactory
#2 - c4-judge
2023-04-11T19:55:01Z
0xleastwood marked the issue as selected for report
#3 - c4-judge
2023-04-11T20:03:29Z
0xleastwood marked the issue as duplicate of #121
#4 - c4-judge
2023-04-11T20:03:45Z
0xleastwood marked the issue as not selected for report
#5 - c4-judge
2023-04-12T00:55:03Z
0xleastwood marked the issue as duplicate of #130
#6 - 0xleastwood
2023-04-12T00:59:35Z
This solution doesn't make a lot of sense because users could still predict the hash by altering the secret and nonce. It would therefore be possible to control the tray data.
#7 - c4-judge
2023-04-12T00:59:41Z
0xleastwood marked the issue as partial-25