Platform: Code4rena
Start Date: 18/10/2022
Pot Size: $50,000 USDC
Total HM: 13
Participants: 67
Period: 5 days
Judge: Picodes
Total Solo HM: 7
Id: 172
League: ETH
Rank: 65/67
Findings: 1
Award: $25.96
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Jeiwan
Also found by: 0x1f8b, 0x4non, 0x5rings, 0xSmartContract, Awesome, Aymen0909, Bnke0x0, CodingNameKiki, Diana, DimSon, JC, JrNet, LeoS, RaymondFam, ReyAdmirado, Saintcode_, Shinchan, __141345__, berndartmueller, bharg4v, brgltd, carlitox477, ch0bu, chaduke, cryptostellar5, emrekocak, gogo, lukris02, martin, mcwildy, sakman, trustindistrust, zishansami
25.9629 USDC - $25.96
Serial No. | Issue Name | Instances |
---|---|---|
G-1 | Strict inequalities (>) are more expensive than non-strict ones (>=) | 2 |
G-2 | x += y costs more gas than x = x + y for state variables | 7 |
G-3 | Use calldata instead of memory in external functions | 3 |
G-4 | Using bools for storage incurs overhead | 3 |
G-5 | Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead | 7 |
G-6 | Use assembly to check for address(0) | 11 |
Total instances found in this contest: 33 | Among all files in scope
Strict inequalities (>) are more expensive than non-strict ones (>=). This is due to some supplementary checks (ISZERO, 3 gas. I suggest using >= instead of > to avoid some opcodes here:
contracts/JBTiered721Delegate.sol:551: _data.metadata.length > 36 && contracts/JBTiered721DelegateStore.sol:965: _storedTier.contributionFloor > _bestContributionFloor &&
https://code4rena.com/reports/2022-04-badger-citadel/#g-31--is-cheaper-than
contracts/JBTiered721DelegateStore.sol:354: supply += _storedTier.initialQuantity - _storedTier.remainingQuantity; contracts/JBTiered721DelegateStore.sol:409: units += _balance * _storedTierOf[_nft][_i].votingUnits; contracts/JBTiered721DelegateStore.sol:506: balance += tierBalanceOf[_nft][_owner][_i]; contracts/JBTiered721DelegateStore.sol:534: weight += _storedTierOf[_nft][tierIdOfToken(_tokenIds[_i])].contributionFloor; contracts/JBTiered721DelegateStore.sol:563: weight += contracts/JBTiered721DelegateStore.sol:827: numberOfReservesMintedFor[msg.sender][_tierId] += _count; contracts/libraries/JBIpfsDecoder.sol:52: carry += uint256(digits[j]) * 256;
https://github.com/code-423n4/2022-05-backd-findings/issues/108
Use calldata instead of memory in external functions to save gas.
contracts/JBTiered721Delegate.sol:386: function setBaseUri(string memory _baseUri) external override onlyOwner { contracts/JBTiered721DelegateStore.sol:1016: ) external override returns (uint256[] memory tokenIds, uint256 leftoverAmount) { contracts/JBTiered721DelegateStore.sol:1091: function recordBurn(uint256[] memory _tokenIds) external override {
// Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled.
Refer Here 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
contracts/JBTiered721Delegate.sol:543: bool _expectMintFromExtraFunds; contracts/JBTiered721Delegate.sol:546: bool _dontOverspend; contracts/JBTiered721Delegate.sol:555: bool _dontMint;
https://code4rena.com/reports/2022-06-notional-coop#8-using-bools-for-storage-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.11/internals/layout_in_storage.html Use a larger size then downcast where needed
contracts/JBTiered721DelegateStore.sol:689: contributionFloor: uint80(_tierToAdd.contributionFloor), contracts/JBTiered721DelegateStore.sol:690: lockedUntil: uint48(_tierToAdd.lockedUntil), contracts/JBTiered721DelegateStore.sol:691: remainingQuantity: uint40(_tierToAdd.initialQuantity), contracts/JBTiered721DelegateStore.sol:692: initialQuantity: uint40(_tierToAdd.initialQuantity), contracts/JBTiered721DelegateStore.sol:693: votingUnits: uint16(_tierToAdd.votingUnits), contracts/JBTiered721DelegateStore.sol:694: reservedRate: uint16(_tierToAdd.reservedRate), contracts/libraries/JBIpfsDecoder.sol:48: uint8 digitlength = 1;
Saves 6 gas per instance if using assembly to check for address(0)
e.g.
assembly { if iszero(_addr) { mstore(0x00, 'zero address') revert(0x00, 0x20) } }
contracts/JBTiered721Delegate.sol:105: if (_storedFirstOwner != address(0)) return _storedFirstOwner; contracts/JBTiered721Delegate.sol:146: if (address(_resolver) != address(0)) return _resolver.getUri(_tokenId); contracts/JBTiered721Delegate.sol:729: if (_from != address(0)) { contracts/JBTiered721Delegate.sol:736: _to != address(0) && contracts/JBTiered721DelegateStore.sol:609: if (_storedReservedTokenBeneficiaryOfTier != address(0)) contracts/JBTiered721DelegateStore.sol:700: _tierToAdd.reservedTokenBeneficiary != address(0) && contracts/JBTiered721DelegateStore.sol:872: if (_from != address(0)) contracts/JBTiered721DelegateStore.sol:877: if (_to != address(0)) { contracts/JB721TieredGovernance.sol:282: if (_from != address(0)) { contracts/JB721TieredGovernance.sol:291: if (_to != address(0)) { contracts/JBTiered721DelegateDeployer.sol:99: if (_deployTiered721DelegateData.owner != address(0))
#0 - c4-judge
2022-11-05T09:33:50Z
Picodes marked the issue as grade-b