Platform: Code4rena
Start Date: 06/09/2022
Pot Size: $90,000 USDC
Total HM: 33
Participants: 168
Period: 9 days
Judge: GalloDaSballo
Total Solo HM: 10
Id: 157
League: ETH
Rank: 65/168
Findings: 4
Award: $162.01
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: zzzitron
Also found by: 0xSmartContract, ChristianKuri, ElKu, Lambda, MiloTruck, davidbrai, elad, hansfriese, immeas, ladboy233, scaraven, volky
Token.mint()
finds the unscheduled token and mints for the auction house.
But if the founders have 100% ownership, it can't select the unscheduled token id so it will revert.
As a result, there will be no tokens for the founders and the full system will be broken.
There is no requirement totalOwnership
should be less than 100 here.
So we can assume there is 1 founder that has 100 founderPct
.
Then from this logic, all base tokens from 0 to 99 will be scheduled for this founder.
Then Token.mint()
can't find the unscheduled id here and the founder won't have the minted tokens also because this function reverts always.
Even if we wait until the vest is expired here, there will be no founders in this case.
Solidity Visual Developer of VSCode
I think we should check totalOwnership < 100
here like below so that there is at least one token for the auction house.
if ((totalOwnership += uint8(founderPct)) >= 100) revert INVALID_FOUNDER_OWNERSHIP();
#0 - GalloDaSballo
2022-09-20T19:47:34Z
🌟 Selected for report: MEP
Also found by: 0xSky, CertoraInc, MiloTruck, PwnPatrol, R2, Tointer, V_B, __141345__, antonttc, azephiar, cccz, d3e4, datapunk, davidbrai, easy_peasy, hansfriese, minhtrng, neumo, pcarranzav, peritoflores, scaraven, teawaterwire, tonisives, unforgiven, wagmi, zkhorse, zzzitron
5.6134 USDC - $5.61
We assume all baseTokenIds
are less than 100 and increase by schedule
for equal distribution here.
But % 100
won't be applied after addition so some bastTokenIds
will be useless for founders because they are equal or greater than 100.
As a result, founders might have fewer tokens than they expect.
With the below code, baseTokenId
won't save the final result after % 100
.
File: 2022-09-nouns-builder\src\token\Token.sol 118: (baseTokenId += schedule) % 100;
Currently it's same as baseTokenId += schedule
.
Solidity Visual Developer of VSCode
We should modify like below.
baseTokenId = (baseTokenId + schedule) % 100;
#0 - GalloDaSballo
2022-09-20T13:00:47Z
🌟 Selected for report: MEP
Also found by: 0xSky, CertoraInc, MiloTruck, PwnPatrol, R2, Tointer, V_B, __141345__, antonttc, azephiar, cccz, d3e4, datapunk, davidbrai, easy_peasy, hansfriese, minhtrng, neumo, pcarranzav, peritoflores, scaraven, teawaterwire, tonisives, unforgiven, wagmi, zkhorse, zzzitron
5.6134 USDC - $5.61
As we can see from here, all baseTokenIds
should be less than 100.
But Token._getNextTokenId()
might return some invalid baseTokenId
so some founders would have less tokens than they expect.
Normally Token._getNextTokenId()
returns a valid baseTokenId
(less than 100) with small number of founders.
But there are some cases where it returns invalid token Ids.
founderPct
individually.F1
to F9
have 1 founderPct
.F10
has 10 founderPct
.F11
to F31
have 1 founderPct
.F32
has 3 founderPct
.F1
to F9
will have 0 ~ 8 baseTokenId
.F10
will have 9, 19, 29, ..., 99 baseTokenId
.F11
to F31
will have 10 ~ 32 baseTokenId
except for 19, 29
.F32
will have 33, 66, 100
as 99
is scheduled already.So F32
should have 3 scheduled tokens but he has only 2.
Solidity Visual Developer of VSCode
I think we can modify Token._getNextTokenId()
like below.
function _getNextTokenId(uint256 _tokenId) internal view returns (uint256) { unchecked { while (tokenRecipient[_tokenId].wallet != address(0)) _tokenId = (_tokenId + 1) % 100; return _tokenId; } }
This while loop
won't be infinite because the total number of scheduled tokens <= 100.
#0 - GalloDaSballo
2022-09-19T21:17:59Z
By definition, this requries the condition of the "unintuitive founders setup", that said LG would have preferred a POC to make sure it's correct beyond any doubt
#1 - GalloDaSballo
2022-09-20T13:00:56Z
https://github.com/code-423n4/2022-09-nouns-builder/blob/7e9fddbbacdd7d7812e912a369cfd862ee67dc03/src/token/metadata/MetadataRenderer.sol#L91 https://github.com/code-423n4/2022-09-nouns-builder/blob/7e9fddbbacdd7d7812e912a369cfd862ee67dc03/src/token/metadata/MetadataRenderer.sol#L194
MetadataRenderer.addProperties()
should check if numProperties < 16
.
When the number of properties >= 16, onMinted()
function will revert here so tokens can't be minted at all.
tokenAttributes
here, this array is declared as uint16[16]
.onMinted()
will revert with 16 or more properties.Solidity Visual Developer of VSCode
Recommend adding this require()
here.
require(numStoredProperties + numNewProperties < 16, "should be less than 16");
#0 - GalloDaSballo
2022-09-20T18:43:42Z
🌟 Selected for report: Lambda
Also found by: 0x1337, 0x1f8b, 0x4non, 0x85102, 0xA5DF, 0xNazgul, 0xSmartContract, 0xbepresent, 0xc0ffEE, 8olidity, Aymen0909, B2, Bnke0x0, CRYP70, Captainkay, CertoraInc, Ch_301, Chom, ChristianKuri, CodingNameKiki, Deivitto, Diana, DimitarDimitrov, ElKu, EthLedger, Franfran, Funen, GimelSec, JansenC, Jeiwan, Jujic, Lead_Belly, MEP, MasterCookie, MiloTruck, Noah3o6, PPrieditis, PaludoX0, Picodes, PwnPatrol, R2, Randyyy, RaymondFam, Respx, ReyAdmirado, Rolezn, Samatak, Tointer, Tomo, V_B, Waze, _Adam, __141345__, a12jmx, ak1, asutorufos, azephiar, ballx, bharg4v, bin2chen, bobirichman, brgltd, bulej93, c3phas, cccz, ch0bu, cloudjunky, cryptonue, cryptostellar5, cryptphi, csanuragjain, d3e4, datapunk, davidbrai, delfin454000, dharma09, dic0de, dipp, djxploit, eierina, erictee, fatherOfBlocks, gogo, hansfriese, hyh, imare, indijanc, izhuer, jonatascm, ladboy233, leosathya, lucacez, lukris02, m9800, martin, minhtrng, ne0n, neumo, oyc_109, p_crypt0, pashov, pauliax, pcarranzav, pedr02b2, peritoflores, pfapostol, rbserver, ret2basic, robee, rvierdiiev, sach1r0, sahar, scaraven, sikorico, simon135, slowmoses, sorrynotsorry, tnevler, tonisives, volky, yixxas, zkhorse, zzzitron
72.5396 USDC - $72.54
Each event should use three indexed fields if there are three or more fields.
#0 - GalloDaSballo
2022-09-27T00:17:28Z
L
R
Disputing events without specific instance of variable to index
1L 1R