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

KupiaSec - The first founder will lose 1% ownership if reservedUntilTokenId >= 100. #165

Closed
sherlock-admin2 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-admin2
Copy link
Contributor

sherlock-admin2 commented Dec 1, 2023

KupiaSec

high

The first founder will lose 1% ownership if reservedUntilTokenId >= 100.

Summary

The first founder will lose 1% ownership if reservedUntilTokenId >= 100.

Vulnerability Detail

While adding founders in _addFounders(), baseTokenId starts from reservedUntilTokenId.

File: nouns-protocol\src\token\Token.sol
161:                 uint256 baseTokenId = reservedUntilTokenId; //@audit doesn't work when >= 100
162: 
163:                 // For each token to vest:
164:                 for (uint256 j; j < founderPct; ++j) {
165:                     // Get the available token id
166:                     baseTokenId = _getNextTokenId(baseTokenId);
167: 
168:                     // Store the founder as the recipient
169:                     tokenRecipient[baseTokenId] = newFounder;
170: 
171:                     emit MintScheduled(baseTokenId, founderId, newFounder);
172: 
173:                     // Update the base token id
174:                     baseTokenId = (baseTokenId + schedule) % 100;
175:                 }

So if reservedUntilTokenId is equal to or greater than 100, the first founder will be a recipient of baseTokenId which is greater than 99.

But tokenRecipient is useful only for [0, 99] and it means the first founder loses 1% ownership.

Here is a coded POC which can be added to Token.t.sol.

    function testLoseOwnershipWithBigReserveId() public {
        uint256 reservedUntilTokenId = 100;
        deployAltMock(reservedUntilTokenId);

        uint256 expectedTotalOwnership = token.totalFounderOwnership();

        Founder memory thisFounder;

        uint actualTotalOwnership;
        for (uint256 i; i <= 99; ++i) {
            thisFounder = token.getScheduledRecipient(i);
            actualTotalOwnership += thisFounder.wallet != address(0) ? 1: 0;
        }

        assertEq(expectedTotalOwnership, actualTotalOwnership + 1);
    }

As we can see from the test, actualTotalOwnership is less than the expected value.

Impact

The first founder will lose 1% ownership if reservedUntilTokenId >= 100.

Code Snippet

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

Tool used

Manual Review

Recommendation

baseTokenId should be set like this.

    uint256 baseTokenId = reservedUntilTokenId % 100;

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-admin sherlock-admin changed the title Plain Caramel Porcupine - The first founder will lose 1% ownership if reservedUntilTokenId >= 100. KupiaSec - The first founder will lose 1% ownership if reservedUntilTokenId >= 100. Dec 13, 2023
@sherlock-admin sherlock-admin 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