You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
First Founder unable to mint token due to tokenId incorrectly set to reservedUntilTokenId
Summary
When adding founders during Token.sol initialization, the first founder will have his first tokenId set to reservedUntilTokenId. This has two consequences 1) the first founder cannot mint his first token using mintFromReserveTo, and 2) reservedUntilTokenId will incorrectly point to a reserved token.
Vulnerability Detail
By design, thereservedUntilTokenId should be the first tokenId that the DAO's auctions will use. If it was set to 100 then it means that tokenIds 0 to 99 are reserved.
/// @param _reservedUntilTokenId The tokenId that a DAO's auctions will start at
The error lies in the function _addFounders. Unlike subsequent tokens, this first reserved token does not go through % 100 and therefore is set to be equal to reservedUntilTokenId. E.g. if reservedUntilTokenId = 100, the first founder's first reserved token will be id 100.
function _addFounders() internal {
...
// @audit first founder's first tokenId set to reservedUntiltokenIduint256 baseTokenId = reservedUntilTokenId;
for (uint256 j; j < founderPct; ++j) {
// @audit tokenId is unchanged by _getNextTokenId since token is unassigned
baseTokenId =_getNextTokenId(baseTokenId);
tokenRecipient[baseTokenId] = newFounder;
emitMintScheduled(baseTokenId, founderId, newFounder);
// @audit only subsequent tokenIds have the % 100 treatment
baseTokenId = (baseTokenId + schedule) %100;
}
}
function _getNextTokenId(uint256_tokenId) internalviewreturns (uint256) {
unchecked {
while (tokenRecipient[_tokenId].wallet !=address(0)) {
_tokenId = (++_tokenId) %100;
}
return _tokenId;
}
}
Impact
The first founder is unable to mint his first token through mintFromReserveToas it would fail the check:
if (tokenId >= reservedUntilTokenId) revertTOKEN_NOT_RESERVED();
Consider this proof-of-concept:
Assume reservedUntilTokenId = 100
After adding founders, it is checked that tokenId 100 belongs to the first founder
If minter tries to mint tokenId 100 to founder, it will revert with "TOKEN_NOT_RESERVED"
Considering that the first founder is very likely an important person in the DAO, losing some ownership due to failure to mint a token is quite impactful. The likelihood is also high or even bound to occur due to the very first reserved tokenId being incorrectly set to reservedForTokenId.
sherlock-admin
changed the title
Bitter Crepe Rattlesnake - First Founder unable to mint token due to tokenId incorrectly set to reservedUntilTokenId
giraffe - First Founder unable to mint token due to tokenId incorrectly set to reservedUntilTokenId
Dec 13, 2023
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
giraffe
high
First Founder unable to mint token due to tokenId incorrectly set to reservedUntilTokenId
Summary
When adding founders during
Token.sol
initialization, the first founder will have his first tokenId set to reservedUntilTokenId. This has two consequences 1) the first founder cannot mint his first token usingmintFromReserveTo
, and 2) reservedUntilTokenId will incorrectly point to a reserved token.Vulnerability Detail
By design, the
reservedUntilTokenId
should be the first tokenId that the DAO's auctions will use. If it was set to 100 then it means that tokenIds 0 to 99 are reserved./// @param _reservedUntilTokenId The tokenId that a DAO's auctions will start at
The error lies in the function
_addFounders
. Unlike subsequent tokens, this first reserved token does not go through% 100
and therefore is set to be equal toreservedUntilTokenId
. E.g. ifreservedUntilTokenId = 100
, the first founder's first reserved token will be id100
.Impact
The first founder is unable to mint his first token through
mintFromReserveTo
as it would fail the check:Consider this proof-of-concept:
reservedUntilTokenId = 100
Add this foundry test to
Token.t.sol
Considering that the first founder is very likely an important person in the DAO, losing some ownership due to failure to mint a token is quite impactful. The likelihood is also high or even bound to occur due to the very first reserved tokenId being incorrectly set to
reservedForTokenId
.Code Snippet
https://github.com/sherlock-audit/2023-09-nounsbuilder/blob/main/nouns-protocol/src/token/Token.sol#L161
Tool used
Manual Review
Recommendation
Consider changing
_addFounders()
from:uint256 baseTokenId = reservedUntilTokenId;
to
`uint256 baseTokenId = reservedUntilTokenId % 100;
Duplicate of #42
The text was updated successfully, but these errors were encountered: