Platform: Code4rena
Start Date: 08/11/2022
Pot Size: $60,500 USDC
Total HM: 6
Participants: 72
Period: 5 days
Judge: Picodes
Total Solo HM: 2
Id: 178
League: ETH
Rank: 19/72
Findings: 3
Award: $268.50
🌟 Selected for report: 0
🚀 Solo Findings: 0
151.3257 USDC - $151.33
https://github.com/code-423n4/2022-11-looksrare/blob/e3b2c053f722b0ca2dce3a3eb06f64859b8b7a6f/contracts/lowLevelCallers/LowLevelETH.sol#L32-L38 https://github.com/code-423n4/2022-11-looksrare/blob/e3b2c053f722b0ca2dce3a3eb06f64859b8b7a6f/contracts/lowLevelCallers/LowLevelETH.sol#L54-L60 https://github.com/code-423n4/2022-11-looksrare/blob/e3b2c053f722b0ca2dce3a3eb06f64859b8b7a6f/contracts/lowLevelCallers/LowLevelETH.sol#L43 https://github.com/code-423n4/2022-11-looksrare/blob/e3b2c053f722b0ca2dce3a3eb06f64859b8b7a6f/contracts/lowLevelCallers/LowLevelETH.sol#L54 https://github.com/code-423n4/2022-11-looksrare/blob/e3b2c053f722b0ca2dce3a3eb06f64859b8b7a6f/contracts/LooksRareAggregator.sol#L109 https://github.com/code-423n4/2022-11-looksrare/blob/e3b2c053f722b0ca2dce3a3eb06f64859b8b7a6f/contracts/LooksRareAggregator.sol#L51-L57
This means that the caller won't receive ETH but the transaction will continue, this could specially affects to function LookRareAggregator.execute
, which use _returnETHIfAny(address)
function, leading to originator lose of funds or mess up its state variables.
Originator is a smart cotnract which will revert if it current balance is greater than 10. Originator contract has a function which calls LookRareAggregator.execute
(for instance execute) and after that update a counter for current trades, which afect its accountability, then:
LooksRareAggregator.execute
, it result that some ETH is remaining after the trades_returnETHIfAny(originator)
is called, when this function tries to send ETH this last call is reverted, but it continue the _returnETHIfAny
executionLooksRareAggregator.execute
execution finishedOriginator smart contract accountability was mess up for using LooksRareAgregator contract.
Manual review
Add next line at the end of each function
if (!status) revert ETHTransferFail();
#0 - c4-judge
2022-11-21T11:12:49Z
Picodes marked the issue as duplicate of #241
#1 - c4-judge
2022-12-16T13:58:41Z
Picodes marked the issue as satisfactory
🌟 Selected for report: RaymondFam
Also found by: 0x1f8b, 0x52, 0xSmartContract, 0xc0ffEE, 0xhacksmithh, 8olidity, Awesome, BClabs, Bnke0x0, Chom, Deivitto, Hashlock, IllIllI, Josiah, KingNFT, Nyx, R2, ReyAdmirado, Rolezn, SamGMK, Sathish9098, SinceJuly, V_B, Vadis, Waze, a12jmx, adriro, ajtra, aphak5010, bearonbike, bin, brgltd, carlitox477, carrotsmuggler, cccz, ch0bu, chaduke, datapunk, delfin454000, erictee, fatherOfBlocks, fs0c, horsefacts, jayphbee, ktg, ladboy233, pashov, perseverancesuccess, rbserver, ret2basic, tnevler, zaskoh
36.3434 USDC - $36.34
If _erc20EnabledLooksRareAggregator = address(0)
, setERC20EnabledLooksRareAggregator
won't revert, and it will emit nonsense event ERC20EnabledLooksRareAggregatorSet
. This function should check that _erc20EnabledLooksRareAggregator != address(0)
If proxy function was already added, then addFunction
will emit a nonsense event. The function should check that _proxyFunctionSelectors[proxy][selector]
is false
.
If proxy function was not already added, then removeFunction
will emit a nonsense event. The function should check that _proxyFunctionSelectors[proxy][selector]
is true
.
If current values of _proxyFeeData[proxy]
are sent, then the function will emit a nonsense event. This function should check that _proxyFeeData[proxy].bp != bp && _proxyFeeData[proxy].recipient != recipient;
It should be checked that _aggregator != address(0)
, if _aggregator == address(0)
it will be needed to redeploy.
It should be checked that _aggregator != address(0)
and _marketplace != address(0)
, if _aggregator == address(0)
or _marketplace == address(0)
it will be needed to redeploy.
It should be checked that _aggregator != address(0)
and _marketplace != address(0)
, if _aggregator == address(0)
or _marketplace == address(0)
it will be needed to redeploy.
The problem has similarities with one reported in OlympusDao contest. The problem is the ERC721 and ERC1155 contract length lack of check. These function in the whole interaction of the present contract does not present major issues, however if they are intended to be used by other contracts it may well present several high issues.
#0 - c4-judge
2022-11-21T19:26:31Z
Picodes marked the issue as grade-b
#1 - c4-sponsor
2022-11-23T18:00:48Z
0xhiroshi requested judge review
#2 - 0xhiroshi
2022-11-23T18:00:58Z
we will check the contract length for token transfers, but the rest are invalid
80.8321 USDC - $80.83
This implies changing the contract to
abstract contract ReentrancyGuard is IReentrancyGuard { uint256 private _status; constructor() {} /** * @notice Modifier to wrap functions to prevent reentrancy calls */ modifier nonReentrant() { if (_status == 1) revert ReentrancyFail(); _status = 1; _; _status = 0; } }
This state variable is accessed 4 times. This can be reduced to two by caching its value.
function cancelOwnershipTransfer() external onlyOwner { _ownershipStatus = ownershipStatus if (_ownershipStatus == Status.NoOngoingTransfer) revert NoOngoingTransferInProgress(); if (_ownershipStatus == Status.TransferInProgress) { delete potentialOwner; } else if (_ownershipStatus == Status.RenouncementInProgress) { delete earliestOwnershipRenouncementTime; } delete ownershipStatus; emit CancelOwnershipTransfer(); }
Last owner
access can be avoided by replacing this line for emit NewOwner(msg.sender);
Giving modifier onlyOwner, we can assure thatmsg.sender = owner
. This means that we can avoid last owner
access by replacing this line for emit InitiateOwnershipTransfer(msg.sender, newPotentialOwner);
We can avoid one access to state variable earliestOwnershipRenouncementTime
by replacing these lines for:
uint256 _earliestOwnershipRenouncementTime = block.timestamp + delay; earliestOwnershipRenouncementTime = _earliestOwnershipRenouncementTime emit InitiateOwnershipRenouncement(_earliestOwnershipRenouncementTime);
These lines can be replaced to avoid double _proxyFeeData[proxy]
access for:
FeeData newFeeData = {bp: bp, recipient: recipient }; _proxyFeeData[proxy] = newFeeData;
#0 - c4-judge
2022-11-21T18:33:21Z
Picodes marked the issue as grade-b
#1 - 0xhiroshi
2022-11-23T20:41:47Z
ReentrancyGuard can save gas during deployment if status manages only values 0 and 1 - invalid, it's actually more expensive during transactions
OwnableTwoSteps#cancelOwnershipTransfer can save gas by caching ownershipStatus state variable - valid
OwnableTwoSteps#confirmOwnershipTransfer can omit one state variable access - valid
OwnableTwoSteps#initiateOwnershipTransfer can omit one state variable access - valid
OwnableTwoSteps#initiateOwnershipRenouncement can omit one state variable access - Turns out this is more expensive according to gas snapshot
LooksRareAgregator#setFee can avoid double state variable access - invalid
#2 - c4-sponsor
2022-11-23T20:41:55Z
0xhiroshi requested judge review