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: 74/168
Findings: 2
Award: $116.00
๐ Selected for report: 0
๐ Solo Findings: 0
๐ 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
60.7742 USDC - $60.77
Emmiting events is recommended each time when a state variable's value is being changed or just some critical event for the contract has occurred. It also helps off-chain monitoring of the contract's state.
There are 4 instances of this issue:
File: src/lib/token/ERC721.sol 47: function __ERC721_init(string memory _name, string memory _symbol) internal onlyInitializing {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721.sol
File: src/lib/utils/EIP712.sol 48: function __EIP712_init(string memory _name, string memory _version) internal onlyInitializing {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/EIP712.sol
File: src/lib/utils/Pausable.sol 39: function __Pausable_init(bool _initPause) internal onlyInitializing {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Pausable.sol
File: src/lib/utils/ReentrancyGuard.sol 34: function __ReentrancyGuard_init() internal onlyInitializing {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/ReentrancyGuard.sol
public
functions not called by the contract should be declared external
insteadCorrect error handling after external calls is impornant and may prevent potential vulnerabilities in code. Could not find anything specific that may open a direct attack vector, but there are multiple places in code where this may be applied.
There are 11 instances of this issue:
There are 14 instances of this issue:
File: src/governance/treasury/Treasury.sol 237: function onERC721Received( 247: function onERC1155Received( 258: function onERC1155BatchReceived(
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/treasury/Treasury.sol
File: src/lib/token/ERC721.sol 83: function balanceOf(address _owner) public view returns (uint256) { 91: function ownerOf(uint256 _tokenId) public view returns (address) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721.sol
File: src/lib/token/ERC721Votes.sol 45: function getVotes(address _account) public view returns (uint256) { 59: function getPastVotes(address _account, uint256 _timestamp) public view returns (uint256) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721Votes.sol
File: src/lib/utils/EIP712.sol 63: function DOMAIN_SEPARATOR() public view returns (bytes32) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/EIP712.sol
File: src/lib/utils/Ownable.sol 52: function owner() public view returns (address) { 57: function pendingOwner() public view returns (address) { 63: function transferOwnership(address _newOwner) public onlyOwner { 71: function safeTransferOwnership(address _newOwner) public onlyOwner { 78: function acceptOwnership() public onlyPendingOwner { 87: function cancelOwnershipTransfer() public onlyOwner {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Ownable.sol
receive()
/fallback()
functionsThere are 1 instances of this issue:
File: src/governance/treasury/Treasury.sol 269: receive() external payable {}
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/treasury/Treasury.sol
There are 13 instances of this issue:
File: src/lib/interfaces/IInitializable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IInitializable.sol
File: src/lib/interfaces/IPausable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IPausable.sol
File: src/lib/proxy/ERC1967Proxy.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/ERC1967Proxy.sol
File: src/lib/proxy/ERC1967Upgrade.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/ERC1967Upgrade.sol
File: src/lib/proxy/UUPS.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/UUPS.sol
File: src/lib/token/ERC721.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721.sol
File: src/lib/token/ERC721Votes.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721Votes.sol
File: src/lib/utils/EIP712.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/EIP712.sol
File: src/lib/utils/Initializable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Initializable.sol
File: src/lib/utils/Ownable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Ownable.sol
File: src/lib/utils/Pausable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Pausable.sol
File: src/lib/utils/ReentrancyGuard.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/ReentrancyGuard.sol
File: src/lib/utils/TokenReceiver.sol 2: pragma solidity ^0.8.0;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/TokenReceiver.sol
Check if input parameters of type address
equal address(0) and uints do not equal 0 - especially if they are strictly associated with important contract's state changes
There are 27 instances of this issue:
indexed
fieldsThere are 9 instances of this issue:
File: src/auction/IAuction.sol event AuctionBid(uint256 tokenId, address bidder, uint256 amount, bool extended, uint256 endTime) event AuctionSettled(uint256 tokenId, address winner, uint256 amount) event AuctionCreated(uint256 tokenId, uint256 startTime, uint256 endTime)
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/auction/IAuction.sol
File: src/governance/governor/IGovernor.sol event VoteCast(address voter, bytes32 proposalId, uint256 support, uint256 weight, string reason)
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/governor/IGovernor.sol
File: src/governance/treasury/ITreasury.sol event TransactionExecuted(bytes32 proposalId, address[] targets, uint256[] values, bytes[] payloads)
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/treasury/ITreasury.sol
File: src/lib/interfaces/IERC721.sol event ApprovalForAll(address indexed owner, address indexed operator, bool approved)
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IERC721.sol
File: src/lib/interfaces/IERC721Votes.sol event DelegateVotesChanged(address indexed delegate, uint256 prevTotalVotes, uint256 newTotalVotes)
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IERC721Votes.sol
File: src/manager/IManager.sol event DAODeployed(address token, address metadata, address auction, address treasury, address governor)
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/manager/IManager.sol
File: src/token/IToken.sol event MintScheduled(uint256 baseTokenId, uint256 founderId, Founder founder)
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/token/IToken.sol
#0 - GalloDaSballo
2022-09-26T21:37:20Z
Address(0) -> 1L
You clearly pasted this from somewhere, will penalize
๐ Selected for report: pfapostol
Also found by: 0x1f8b, 0x4non, 0x5rings, 0xA5DF, 0xSmartContract, 0xc0ffEE, 0xkatana, Aymen0909, Bnke0x0, CertoraInc, Chandr, CodingNameKiki, Cr4ckM3, Deivitto, DimSon, Franfran, JAGADESH, JC, Jeiwan, Lambda, LeoS, Matin, Metatron, Migue, MiloTruck, PPrieditis, PaludoX0, R2, RaymondFam, Respx, ReyAdmirado, Rolezn, Saintcode_, Samatak, SnowMan, StevenL, Tointer, TomJ, Tomo, WatchDogs, Waze, _Adam, __141345__, ajtra, asutorufos, ballx, brgltd, bulej93, c3phas, ch0bu, dharma09, djxploit, durianSausage, easy_peasy, fatherOfBlocks, gianganhnguyen, gogo, imare, leosathya, lucacez, martin, oyc_109, pauliax, peiw, prasantgupta52, ret2basic, rfa, robee, sikorico, simon135, tofunmi, volky, wagmi, zishansami
55.228 USDC - $55.23
payable
Marking a function as payable
reduces gas cost since the compiler does not have to check whether a payment was provided or not. This change will save around 21 gas per function call.
There are 26 instances of this issue:
File: src/auction/Auction.sol 244: function unpause() external onlyOwner { 263: function pause() external onlyOwner { 307: function setDuration(uint256 _duration) external onlyOwner { 315: function setReservePrice(uint256 _reservePrice) external onlyOwner { 323: function setTimeBuffer(uint256 _timeBuffer) external onlyOwner { 331: function setMinimumBidIncrement(uint256 _percentage) external onlyOwner { 374: function _authorizeUpgrade(address _newImpl) internal view override onlyOwner {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/auction/Auction.sol
File: src/governance/governor/Governor.sol 564: function updateVotingDelay(uint256 _newVotingDelay) external onlyOwner { 572: function updateVotingPeriod(uint256 _newVotingPeriod) external onlyOwner { 580: function updateProposalThresholdBps(uint256 _newProposalThresholdBps) external onlyOwner { 588: function updateQuorumThresholdBps(uint256 _newQuorumVotesBps) external onlyOwner { 596: function updateVetoer(address _newVetoer) external onlyOwner { 605: function burnVetoer() external onlyOwner { 618: function _authorizeUpgrade(address _newImpl) internal view override onlyOwner {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/governor/Governor.sol
File: src/governance/treasury/Treasury.sol 116: function queue(bytes32 _proposalId) external onlyOwner returns (uint256 eta) { 180: function cancel(bytes32 _proposalId) external onlyOwner {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/treasury/Treasury.sol
File: src/lib/utils/Ownable.sol 63: function transferOwnership(address _newOwner) public onlyOwner { 71: function safeTransferOwnership(address _newOwner) public onlyOwner { 87: function cancelOwnershipTransfer() public onlyOwner {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Ownable.sol
File: src/manager/Manager.sol 187: function registerUpgrade(address _baseImpl, address _upgradeImpl) external onlyOwner { 196: function removeUpgrade(address _baseImpl, address _upgradeImpl) external onlyOwner { 209: function _authorizeUpgrade(address _newImpl) internal override onlyOwner {}
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/manager/Manager.sol
File: src/token/metadata/MetadataRenderer.sol 347: function updateContractImage(string memory _newContractImage) external onlyOwner { 355: function updateRendererBase(string memory _newRendererBase) external onlyOwner { 363: function updateDescription(string memory _newDescription) external onlyOwner { 376: function _authorizeUpgrade(address _impl) internal view override onlyOwner {
immutable
& constant
for state variables that do not change their valueThere are 7 instances of this issue:
File: src/auction/storage/AuctionStorageV1.sol 12: Settings internal settings; 15: Token public token;
File: src/governance/governor/storage/GovernorStorageV1.sol 11: Settings internal settings;
File: src/governance/treasury/storage/TreasuryStorageV1.sol 11: Settings internal settings;
File: src/lib/proxy/UUPS.sol 43: function _authorizeUpgrade(address _newImpl) internal virtual;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/UUPS.sol
File: src/token/metadata/storage/MetadataRendererStorageV1.sol 11: Settings internal settings;
File: src/token/storage/TokenStorageV1.sol 11: Settings internal settings;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/token/storage/TokenStorageV1.sol
Use uint256(1)
and uint256(2)
for true
/false
to avoid a Gwarmaccess (100 gas) for the extra SLOAD, and to avoid Gsset (20000 gas) when changing from 'false' to 'true', after having been 'true' in the past
There are 2 instances of this issue:
File: src/lib/utils/Initializable.sol 20: bool internal _initializing;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Initializable.sol
File: src/lib/utils/Pausable.sol 15: bool internal _paused;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Pausable.sol
keccak256()
, should use immutable
rather than constant
It is expected that the value should be converted into a constant value at compile time. But actually the expression is re-calculated each time the constant is referenced.
There are 3 instances of this issue:
File: src/governance/governor/Governor.sol 27: bytes32 public constant VOTE_TYPEHASH = keccak256("Vote(address voter,uint256 proposalId,uint256 support,uint256 nonce,uint256 deadline)");
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/governor/Governor.sol
File: src/lib/token/ERC721Votes.sol 21: bytes32 internal constant DELEGATION_TYPEHASH = keccak256("Delegation(address from,address to,uint256 nonce,uint256 deadline)");
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721Votes.sol
File: src/lib/utils/EIP712.sol 19: bytes32 internal constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/EIP712.sol
++i
will cost less gas than i++
. The same change can be applied to i--
as well.This change would save up to 6 gas per instance/loop.
There are 2 instances of this issue:
File: src/token/Token.sol 91: uint256 founderId = settings.numFounders++; 154: tokenId = settings.totalSupply++;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/token/Token.sol
internal
and private
functions that are called only once should be inlined.The execution of a non-inlined function would cost up to 40 more gas because of two extra jump
s as well as some other instructions.
There are 3 instances of this issue:
File: src/token/metadata/MetadataRenderer.sol 250: function _generateSeed(uint256 _tokenId) private view returns (uint256) { 255: function _getItemImage(Item memory _item, string memory _propertyName) private view returns (string memory) {
File: src/token/Token.sol 177: function _isForFounder(uint256 _tokenId) private returns (bool) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/token/Token.sol
!= 0
on uints
costs less gas than > 0
.This change saves 3 gas per instance/loop
There are 1 instances of this issue:
File: src/lib/token/ERC721Votes.sol 203: if (_from != _to && _amount > 0) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721Votes.sol
constant
/non-immutable
variables to zero than to let the default of zero be appliedNot overwriting the default for stack variables saves 8 gas. Storage and memory variables have larger savings
There are 5 instances of this issue:
File: src/governance/treasury/Treasury.sol 162: for (uint256 i = 0; i < numTargets; ++i) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/treasury/Treasury.sol
File: src/token/metadata/MetadataRenderer.sol 119: for (uint256 i = 0; i < numNewProperties; ++i) { 133: for (uint256 i = 0; i < numNewItems; ++i) { 189: for (uint256 i = 0; i < numProperties; ++i) { 229: for (uint256 i = 0; i < numProperties; ++i) {
private
rather than public
for constants, saves gasIf needed, the values can be read from the verified contract source code, or if there are multiple values there can be a single getter function that returns a tuple of the values of all currently-public constants. Saves 3406-3606 gas in deployment gas due to the compiler not having to create non-payable getter functions for deployment calldata, not having to store the bytes of the value outside of where it's used, and not adding another entry to the method ID table
There are 1 instances of this issue:
File: src/governance/governor/Governor.sol 27: bytes32 public constant VOTE_TYPEHASH = keccak256("Vote(address voter,uint256 proposalId,uint256 support,uint256 nonce,uint256 deadline)");
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/governor/Governor.sol
++i
/i++
should be unchecked{++I}
/unchecked{I++}
in for
-loopsWhen an increment or any arithmetic operation is not possible to overflow it should be placed in unchecked{}
block. \This is because of the default compiler overflow and underflow safety checks since Solidity version 0.8.0. \In for-loops it saves around 30-40 gas per loop
There are 8 instances of this issue:
File: src/governance/treasury/Treasury.sol 162: for (uint256 i = 0; i < numTargets; ++i) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/treasury/Treasury.sol
File: src/token/metadata/MetadataRenderer.sol 119: for (uint256 i = 0; i < numNewProperties; ++i) { 133: for (uint256 i = 0; i < numNewItems; ++i) { 189: for (uint256 i = 0; i < numProperties; ++i) { 229: for (uint256 i = 0; i < numProperties; ++i) {
File: src/token/Token.sol 80: for (uint256 i; i < numFounders; ++i) { 108: for (uint256 j; j < founderPct; ++j) { 261: for (uint256 i; i < numFounders; ++i) founders[i] = founder[i];
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/token/Token.sol
uint
s/int
s smaller than 32 bytes (256 bits) incurs overhead'When using elements that are smaller than 32 bytes, your contractโs gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.' \ https://docs.soliditylang.org/en/v0.8.15/internals/layout_in_storage.html \ Use a larger size then downcast where needed
There are 25 instances of this issue:
File: src/auction/types/AuctionTypesV1.sol 18: uint8 minBidIncrement;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/auction/types/AuctionTypesV1.sol
File: src/governance/governor/Governor.sol 213: uint8 _v,
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/governor/Governor.sol
File: src/governance/governor/IGovernor.sol 181: uint8 v,
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/governor/IGovernor.sol
File: src/governance/governor/types/GovernorTypesV1.sol 21: uint16 proposalThresholdBps; 22: uint16 quorumThresholdBps; 44: uint32 timeCreated; 45: uint32 againstVotes; 46: uint32 forVotes; 47: uint32 abstainVotes; 48: uint32 voteStart; 49: uint32 voteEnd; 50: uint32 proposalThreshold; 51: uint32 quorumVotes;
File: src/governance/treasury/types/TreasuryTypesV1.sol 12: uint128 gracePeriod; 13: uint128 delay;
File: src/lib/interfaces/IERC721Votes.sol 36: uint64 timestamp; 72: uint8 v,
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IERC721Votes.sol
File: src/lib/token/ERC721Votes.sol 148: uint8 _v,
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721Votes.sol
File: src/lib/utils/Initializable.sol 17: uint8 internal _initialized; 55: modifier reinitializer(uint8 _version) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Initializable.sol
File: src/token/metadata/types/MetadataRendererTypesV1.sol 20: uint16 referenceSlot;
File: src/token/types/TokenTypesV1.sol 20: uint8 numFounders; 21: uint8 totalOwnership; 30: uint8 ownershipPct; 31: uint32 vestExpiry;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/token/types/TokenTypesV1.sol
calldata
instead of memory
for function parametersIf a reference type function parameter is read-only, it is cheaper in gas to use calldata instead of memory. Calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory. Try to use calldata as a data location because it will avoid copies and also makes sure that the data cannot be modified.
There are 24 instances of this issue:
File: src/governance/governor/Governor.sol 99: address[] memory _targets, 100: uint256[] memory _values, 101: bytes[] memory _calldatas, 117: address[] memory _targets, 118: uint256[] memory _values, 119: bytes[] memory _calldatas, 120: string memory _description 195: string memory _reason 252: string memory _reason
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/governor/Governor.sol
File: src/lib/proxy/ERC1967Upgrade.sol 35: bytes memory _data, 56: bytes memory _data,
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/ERC1967Upgrade.sol
File: src/lib/proxy/UUPS.sol 55: function upgradeToAndCall(address _newImpl, bytes memory _data) external payable onlyProxy {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/UUPS.sol
File: src/lib/token/ERC721.sol /// @audit Store `_name` in calldata. 47: function __ERC721_init(string memory _name, string memory _symbol) internal onlyInitializing { /// @audit Store `_symbol` in calldata. 47: function __ERC721_init(string memory _name, string memory _symbol) internal onlyInitializing {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721.sol
File: src/lib/utils/Address.sol /// @audit Store `_data` in calldata. 37: function functionDelegateCall(address _target, bytes memory _data) internal returns (bytes memory) { /// @audit Store `_returndata` in calldata. 46: function verifyCallResult(bool _success, bytes memory _returndata) internal pure returns (bytes memory) {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Address.sol
File: src/lib/utils/EIP712.sol /// @audit Store `_name` in calldata. 48: function __EIP712_init(string memory _name, string memory _version) internal onlyInitializing { /// @audit Store `_version` in calldata. 48: function __EIP712_init(string memory _name, string memory _version) internal onlyInitializing {
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/EIP712.sol
File: src/token/metadata/MetadataRenderer.sol /// @audit Store `_item` in calldata. 255: function _getItemImage(Item memory _item, string memory _propertyName) private view returns (string memory) { /// @audit Store `_propertyName` in calldata. 255: function _getItemImage(Item memory _item, string memory _propertyName) private view returns (string memory) { /// @audit Store `_jsonBlob` in calldata. 308: function _encodeAsJson(bytes memory _jsonBlob) private pure returns (string memory) { 347: function updateContractImage(string memory _newContractImage) external onlyOwner { 355: function updateRendererBase(string memory _newRendererBase) external onlyOwner { 363: function updateDescription(string memory _newDescription) external onlyOwner {
x <= y
with x < y + 1
, and x >= y
with x > y - 1
In the EVM, there is no opcode for >=
or <=
. When using greater than or equal, two operations are performed: >
and =
. Using strict comparison operators hence saves gas
There are 5 instances of this issue:
File: src/auction/Auction.sol 98: if (block.timestamp >= _auction.endTime) revert AUCTION_OVER();
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/auction/Auction.sol
File: src/governance/treasury/Treasury.sol 89: return timestamps[_proposalId] != 0 && block.timestamp >= timestamps[_proposalId];
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/governance/treasury/Treasury.sol
File: src/lib/token/ERC721Votes.sol 61: if (_timestamp >= block.timestamp) revert INVALID_TIMESTAMP(); 78: if (accountCheckpoints[lastCheckpoint].timestamp <= _timestamp) return accountCheckpoints[lastCheckpoint].votes;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721Votes.sol
File: src/lib/utils/Initializable.sol 56: if (_initializing || _initialized >= _version) revert ALREADY_INITIALIZED();
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Initializable.sol
Use a solidity version of at least 0.8.2 to get simple compiler automatic inlining Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value
There are 20 instances of this issue:
File: src/lib/interfaces/IEIP712.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IEIP712.sol
File: src/lib/interfaces/IERC1967Upgrade.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IERC1967Upgrade.sol
File: src/lib/interfaces/IERC721.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IERC721.sol
File: src/lib/interfaces/IERC721Votes.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IERC721Votes.sol
File: src/lib/interfaces/IInitializable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IInitializable.sol
File: src/lib/interfaces/IOwnable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IOwnable.sol
File: src/lib/interfaces/IPausable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/interfaces/IPausable.sol
File: src/lib/proxy/ERC1967Proxy.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/ERC1967Proxy.sol
File: src/lib/proxy/ERC1967Upgrade.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/ERC1967Upgrade.sol
File: src/lib/proxy/UUPS.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/proxy/UUPS.sol
File: src/lib/token/ERC721.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721.sol
File: src/lib/token/ERC721Votes.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/token/ERC721Votes.sol
File: src/lib/utils/Address.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Address.sol
File: src/lib/utils/EIP712.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/EIP712.sol
File: src/lib/utils/Initializable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Initializable.sol
File: src/lib/utils/Ownable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Ownable.sol
File: src/lib/utils/Pausable.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/Pausable.sol
File: src/lib/utils/ReentrancyGuard.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/ReentrancyGuard.sol
File: src/lib/utils/SafeCast.sol 2: pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/SafeCast.sol
File: src/lib/utils/TokenReceiver.sol 2: pragma solidity ^0.8.0;
https://github.com/code-423n4/2022-09-nouns-builder/tree/main/src/lib/utils/TokenReceiver.sol
#0 - GalloDaSballo
2022-09-18T16:43:46Z
Most of these optimizations are wrong and blanket statements which don't apply
#1 - GalloDaSballo
2022-09-26T16:03:42Z
1k gas mostly from memory calldata