Platform: Code4rena
Start Date: 08/01/2024
Pot Size: $83,600 USDC
Total HM: 23
Participants: 116
Period: 10 days
Judge: 0xean
Total Solo HM: 1
Id: 317
League: ETH
Rank: 86/116
Findings: 1
Award: $12.58
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xA5DF
Also found by: 0xmystery, 7ashraf, AkshaySrivastav, CipherSleuths, NentoR, SBSecurity, Tendency, ZanyBonzy, ZdravkoHr, dd0x7e8, hals, haxatron, invitedtea, jasonxiale, juancito, kaden, krikolkk, ladboy233, oakcobalt, peanuts, petro_1912, pkqs90, plasmablocks, ravikiranweb3, rbserver, rokinot, souilos
12.582 USDC - $12.58
The Solidity 0.8.20+ compiler defaults to the Shanghai EVM version, which brings in the PUSH0
opcode. However, not all Layer 2 solutions have adopted PUSH0
, leading to potential deployment issues on those networks. To circumvent this, developers can opt for an earlier EVM version when compiling their contracts, as detailed in the Foundry Book guidelines.
pragma solidity ^0.8.20;
When utilizing Solidity version 0.8.20 or higher for EVM smart contracts, it is advisable to be mindful of the EVM compiler version.
payable
ModifierThe deploy()
function in the Create2Deployer
contract is marked as payable
, which means that the function is allowed to receive Ether along with the call.
Here's the relevant part of the code:
function deploy( bytes32 salt, bytes memory initCode ) external payable returns (address deploymentAddress) { // Function body... }
The payable
modifier on the deploy()
function may not be necessary. This could be an issue if there is no intention for the deploy()
function to handle Ether or if the contract does not require Ether to be sent to it for any other reason. In this context, the payable
modifier could be a potential vulnerability because it allows anyone to send Ether to the contract without a clear mechanism to withdraw it, possibly leading to a situation where Ether is locked in the contract forever.
If the deploy()
function is not meant to forward Ether to the contract, the payable
modifier should be removed to prevent the accidental sending of Ether to the Create2Deployer
contract.
Here is how the function signature would look without the payable
modifier:
function deploy( bytes32 salt, bytes memory initCode ) external returns (address deploymentAddress) { // Function body... }
Removing the payable
modifier ensures that no Ether can be sent to the deploy()
function. If Ether is sent to a non-payable function, the transaction will be rejected, and the Ether will remain with the sender. This helps prevent the accidental loss of funds and ensures that the contract behavior is clear and explicit.
Stop
ContractThe Stop
contract defines two functions, stopRent
and stopRentBatch
, for stopping rental orders individually or in batches. However, there's a discrepancy in how the Events.RentalOrderStopped
event is emitted in these two functions regarding the order hash data emitted.
stopRent
):When stopping a single rental order, the stopRent
function emits the RentalOrderStopped
event using the seaportOrderHash
directly from the order
parameter:
function stopRent(RentalOrder calldata order) external { // ... (omitted for brevity) _emitRentalOrderStopped(order.seaportOrderHash, msg.sender); }
stopRentBatch
):In contrast, when stopping a batch of rental orders, the stopRentBatch
function emits the RentalOrderStopped
event using a hash derived from the order data, _deriveRentalOrderHash(orders[i])
, for each order in the batch:
function stopRentBatch(RentalOrder[] calldata orders) external { // ... (omitted for brevity) for (uint256 i = 0; i < orders.length; ++i) { // ... (omitted for brevity) orderHashes[i] = _deriveRentalOrderHash(orders[i]); // ... (omitted for brevity) _emitRentalOrderStopped(orderHashes[i], msg.sender); } }
The inconsistency lies in the source of the order hash used in the event emission:
stopRent
, the seaportOrderHash
is used, which suggests that it is the original hash of the order as it was created or recognized by the system.stopRentBatch
, _deriveRentalOrderHash(orders[i])
computes a new hash for each order based on its contents, rather than using an existing seaportOrderHash
.This discrepancy could lead to potential confusion or inconsistencies in tracking and handling events off-chain. If an external system or service relies on these events for processing or analytics, the difference in emitted values might cause issues such as:
The contract should standardize the data emitted in events to ensure consistency. If seaportOrderHash
is the canonical identifier for orders, it should be used in both single and batch operations.
#0 - 141345
2024-01-22T13:54:48Z
208 dd0x7e8 l r nc 0 0 3
L 1 n L 2 n L 3 n
#1 - c4-judge
2024-01-26T18:01:48Z
0xean marked the issue as grade-c
#2 - c4-judge
2024-01-27T20:32:08Z
0xean marked the issue as grade-b