Nouns Builder contest - easy_peasy's results

A permissionless, governed protocol to deploy nouns-style DAOs complete with treasury, generative collections, and governance mechanisms.

General Information

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

Nouns Builder

Findings Distribution

Researcher Performance

Rank: 145/168

Findings: 2

Award: $51.02

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

5.6134 USDC - $5.61

Labels

bug
duplicate
2 (Med Risk)

External Links

A mistyped parenthesis or unnecessary arithmetic was called in Token.sol at line 118:

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L118

The line is the following:

(baseTokenId += schedule) % 100;

The developer might have meant baseTokenId += (schedule % 100); in which case this is a low finding.

In case baseTokenId += schedule; is enough, this report can be considered as a gas optimization report.

#0 - GalloDaSballo

2022-09-26T21:32:00Z

TODO Raise

#1 - GalloDaSballo

2022-09-27T14:17:45Z

Dup of #269

Token._getNextTokenId is ineffficient

In file Token.sol the function _getNextTokenId(_tokenId) is very inefficient.

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L130

The function is called an already nested loop so this function makes the loop a 3 level nested loop.

The function call can be seen at line 110:

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/token/Token.sol#L110

Recommendation

Since he tokenIds seem incremental the contract should save the next available tokenId in a storage variable. If any of the Ids realease under the "next available token Id" it should be stored in a storage array. The contract can later choose to fill those gaps up first or to just choose the "next available tokenId"

Pseudo code for recommendation

    function _getNextTokenId() internal view returns (uint256) {
            return nextAvailableTokenId++;
    }

With storing the gaps for lower, released Ids:

mapping(uint256 => uint256) private availableIds; //
uint256 private  nextUnusedAvailableIndex; // contains the next Id that has useful data
uint256 private  nextAvailableIndex; // contains the size of _availableIds
uint256 private nextAvailableTokenId; // contains the new next available token

function _getNextTokenId() internal view returns (uint256) {
            if (nextAvailableIndex > nextUnusedAvailableIndex) {
                        return availableIds[nextUnusedAvailableIndex];
            }
            return nextAvailableTokenId++;
}

// deletes a tokenId that is below the nextAvailableTokenId
function _deleteTokenId(uint256 _tokenId) internal {
            require(_tokenId < nextAvailableTokenId);
            availableIds[nextAvailableIndex++] = _tokenId;
}

Please note that nextUnusedAvailableIndex should be incremented after reusing the index.

For easier readibility I did not cache storage variables in the example implementation of these functions but in the production ready implementation they should be cached.

Non cached variable was used in Auction.

auction was cached to local memory variable _auction but in line 172 the global, storage variable was used using unnecessary gas.

https://github.com/code-423n4/2022-09-nouns-builder/blob/main/src/auction/Auction.sol#L172

#0 - GalloDaSballo

2022-09-26T15:58:10Z

100 gas from SLOAD, optimization of function is not complete and breaks the current functionality

#1 - GalloDaSballo

2022-09-26T15:58:21Z

Adding 1 for effort

#2 - GalloDaSballo

2022-09-26T15:58:23Z

101

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter