Platform: Code4rena
Start Date: 19/08/2021
Pot Size: $30,000 USDC
Total HM: 5
Participants: 11
Period: 7 days
Judge: 0xean
Total Solo HM: 4
Id: 26
League: ETH
Rank: 10/11
Findings: 1
Award: $0.00
🌟 Selected for report: 2
🚀 Solo Findings: 0
🌟 Selected for report: PierrickGT
0 USDC - $0.00
PierrickGT
We can avoid 3 sload by storing card[winningOutcome]
in a private variable.
We can also avoid 4 sload by storing msgSender()
in a private variable.
We can also simplify the _winningsToTransfer
calculation.
card[winningOutcome]
:
msgSender()
:
_winningsToTransfer
:
Manual analysis
card[winningOutcome]
:
Card storage _cardWinningOutcome = card[winningOutcome];
L574: _cardWinningOutcome.rentCollectedPerCard) *
msgSender()
:
address _msgSender = msgSender();
L578: (rentCollectedPerUserPerCard[_msgSender][winningOutcome] *
_payout(_msgSender, _winningsToTransfer); emit LogWinningsPaid(_msgSender, _winningsToTransfer);
card[winningOutcome]
and msgSender()
:
L564: if (_cardWinningOutcome.longestOwner == _msgSender && winnerCut > 0) {
L585: uint256 _winnersTimeHeld = _cardWinningOutcome.timeHeld[_msgSender];
card[winningOutcome]
and _winningsToTransfer
:
L587 to L589: _winningsToTransfer += (_numerator / _cardWinningOutcome.totalTimeHeld);
#0 - Splidge
2021-08-26T13:10:45Z
I'm not so sure that the recommended fixes to card[_winningOutcome]
would have any benefit, we can't store a Card
type in memory as it contains a mapping. Card storage _cardWinningOutcome = card[winningOutcome];
will only create a pointer to storage so you are still doing storage reads each time you use it. This is my assumption and I'll certainly get around to confirming when I have a chance.
I can make the changes to msgSender()
and _winningsToTransfer
though.
#1 - Splidge
2021-09-02T15:53:23Z
Using _msgSender
instead of msgSender()
implemented here
#2 - Splidge
2021-09-02T15:55:24Z
Using _winningOutcome
instead of winningOutcome
implemented here
🌟 Selected for report: PierrickGT
0 USDC - $0.00
PierrickGT
We can avoid one sload by storing card[_card].longestOwner
in a private variable.
Manual analysis
Store card[_card].longestOwner
in a private variable to avoid one sload.
address _cardLongestOwner = card[_card].longestOwner; if (_user == _cardLongestOwner) { _transferCard(ownerOf(_card), _cardLongestOwner, _card); } else { leaderboard.claimNFT(_user, _card); factory.mintCopyOfNFT(_user, _card); }
#0 - Splidge
2021-08-26T13:14:07Z
Duplicate of #6
#1 - 0xean
2021-09-02T13:15:34Z
Not a duplicate, same optimization, different location in the code.