Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

circlelooper - tokenRecipient mapping maps invalid baseTokenId to founder info #248

Closed
sherlock-admin opened this issue Dec 1, 2023 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A valid High severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented Dec 1, 2023

circlelooper

high

tokenRecipient mapping maps invalid baseTokenId to founder info

Summary

tokenRecipient mapping maps invalid baseTokenId to founder info.

Vulnerability Detail

tokenRecipient mapping maps baseTokenId to founder info.

When Token contract is initialized, founder info is added to tokenRecipient by calling _addFounders().

baseTokenId is set as key to founder info, and it is returned by _getNextTokenId():

    function _getNextTokenId(uint256 _tokenId) internal view returns (uint256) {
        unchecked {
            while (tokenRecipient[_tokenId].wallet != address(0)) {
                _tokenId = (++_tokenId) % 100;
            }


            return _tokenId;
        }
    }

Initially, baseTokenId is the same as reservedUntilTokenId, if its founder info is not set, then the same value will be used as key to map founder info:

                    tokenRecipient[baseTokenId] = newFounder;

When mints a token, baseTokenId is calculated as below:

        uint256 baseTokenId = _tokenId % 100;

If tokenRecipient[baseTokenId].wallet points to founder's wallet, then the token will be set to the founder.

            _mint(tokenRecipient[baseTokenId].wallet, _tokenId);

Consider the following scenario:

  1. reservedUntilTokenId is 100, then baseTokenId is 100
  2. tokenRecipient[_tokenId].wallet is address(0), then tokenRecipient[100] is set to founder info
  3. When mints a token, because baseTokenId = _tokenId % 100, it will never be 100, so tokenRecipient[100] can never be matched, the founder info is thus never be get, no token will be sent to founder.

Impact

No token will be sent to founder.

Code Snippet

https://github.com/sherlock-audit/2023-09-nounsbuilder/blob/main/nouns-protocol/src/token/Token.sol#L265

Tool used

Manual Review

Recommendation

Please consider to set baseTokenId to be less than 100 while calculating:

    function _getNextTokenId(uint256 _tokenId) internal view returns (uint256) {
        unchecked {
            while (tokenRecipient[_tokenId].wallet != address(0)) {
                _tokenId = (++_tokenId) % 100;
            }

+           if (_tokenId >= 100) {
+               _tokenId = _tokenId % 100;
+           }
            return _tokenId;
        }
    }

Duplicate of #42

@github-actions github-actions bot closed this as completed Dec 6, 2023
@github-actions github-actions bot added High A valid High severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Dec 6, 2023
@sherlock-admin2 sherlock-admin2 changed the title Large Ruby Sidewinder - tokenRecipient mapping maps invalid baseTokenId to founder info circlelooper - tokenRecipient mapping maps invalid baseTokenId to founder info Dec 13, 2023
@sherlock-admin2 sherlock-admin2 added the Reward A payout will be made for this issue label Dec 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A valid High severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

2 participants