Platform: Code4rena
Start Date: 03/05/2022
Pot Size: $30,000 USDC
Total HM: 6
Participants: 93
Period: 3 days
Judge: gzeon
Id: 118
League: ETH
Rank: 19/93
Findings: 3
Award: $588.54
๐ Selected for report: 0
๐ Solo Findings: 0
๐ Selected for report: pedroais
Also found by: AuditsAreUS, BowTiedWardens, GimelSec, IllIllI, WatchPug, defsec, leastwood
https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsMinter.sol#L145 https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsMinter.sol#L275 https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsMinter.sol#L441 https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsMinter.sol#L564 https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsMinter.sol#L571
In Dutch Auction phase, the current price is determined in currentDaPrice()
, It uses daStartTime
, daPriceCurveLength
and daDropInterval
to calculate the current price. However these variables can be changed during the phase unconditionally, which means that the price can be manipulated by the owner.
The owner can change these variables unconditionally
function setDaStartTime(uint256 _newTime) public onlyOwner { daStartTime = _newTime; }
function setDaPriceCurveLength(uint256 _newTime) public onlyOwner { daPriceCurveLength = _newTime; }
function setDaDropInterval(uint256 _newTime) public onlyOwner { daDropInterval = _newTime; }
vim
These variables shouldnโt be changed after the phase started. So just add a check in these setter
function setDaPriceCurveLength(uint256 _newTime) public onlyOwner { require(!daStarted(), 'Auction has started'); daPriceCurveLength = _newTime; }
#0 - gzeoneth
2022-06-18T18:01:17Z
Duplicate of #38
๐ Selected for report: defsec
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0x52, 0xDjango, 0xf15ers, 0xkatana, 0xliumin, AuditsAreUS, BowTiedWardens, CertoraInc, Cr4ckM3, Funen, GimelSec, Hawkeye, IllIllI, Kulk0, M0ndoHEHE, MaratCerby, Picodes, Ruhum, TerrierLover, TrungOre, VAD37, WatchPug, berndartmueller, broccolirob, catchup, cccz, cryptphi, csanuragjain, delfin454000, dirk_y, eccentricexit, ellahi, fatherOfBlocks, gzeon, hake, hansfriese, hickuphh3, horsefacts, hubble, hyh, ilan, joestakey, kebabsec, kenta, kenzo, leastwood, m9800, marximimus, minhquanym, oyc_109, p4st13r4, pauliax, pedroais, peritoflores, plotchy, rajatbeladiya, reassor, rfa, robee, rotcivegaf, samruna, shenwilly, shung, simon135, sorrynotsorry, sseefried, teddav, throttle, tintin, unforgiven, z3s
30.2807 USDC - $30.28
We list 2 low-critical findings:
weth
Floating pragma may cause unexpected compilation time behaviour and introduce unintended bugs.
https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsGuild.sol#L1 https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsMinter.sol#L1
Don't use ^
, lock pragma to ensure compiler version. e.g. pragma solidity 0.8.0;
weth
There is a specific weth
address on blockchain, itโs better to use a constant for avoiding typo or phishing address when setWethAddress
, which will also lead to _refundAddress
failing.
https://github.com/code-423n4/2022-05-runes/blob/main/contracts/ForgottenRunesWarriorsMinter.sol#L54
Use a constant rather than using setWethAddress
.
๐ Selected for report: BowTiedWardens
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xProf, 0xc0ffEE, 0xf15ers, 0xkatana, 0xliumin, ACai, AlleyCat, CertoraInc, Cityscape, Cr4ckM3, DavidGialdi, Dinddle, FSchmoede, Funen, GimelSec, Hawkeye, IllIllI, Kulk0, M0ndoHEHE, MaratCerby, MiloTruck, Picodes, RoiEvenHaim, Tadashi, TerrierLover, TrungOre, VAD37, WatchPug, antonttc, catchup, defsec, delfin454000, dirk_y, eccentricexit, ellahi, fatherOfBlocks, gzeon, hake, hansfriese, hickuphh3, horsefacts, ilan, joestakey, kebabsec, kenta, kenzo, marximimus, minhquanym, noobie, oyc_109, p4st13r4, pauliax, rajatbeladiya, reassor, rfa, robee, rotcivegaf, saian, samruna, shenwilly, shung, simon135, slywaters, sorrynotsorry, throttle, unforgiven, z3s
15.491 USDC - $15.49
The for loop has no overflow risk of i
. Use an unchecked block to save gas.
ForgottenRunesWarriorsMinter.sol 162: for (uint256 i = 0; i < numWarriors; i++) { 220: for (uint256 i = 0; i < numWarriors; i++) { 259: for (uint256 i = 0; i < count; i++) { 355: for (uint256 i = startIdx; i < endIdx + 1; i++) {
Use unchecked
blocks to avoid overflow checks, or use ++i
rather than i++
if you don't use unchecked blocks.
for (uint256 i = 0; i < length; ) { ... unchecked { ++i; } }
XXX += 1
to save gasForgottenRunesWarriorsGuild.sol 104: numMinted += 1; ForgottenRunesWarriorsMinter.sol 248: numClaimed += 1;
Use ++numMinted
and ++numClaimed
to save gas.