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: 132/168
Findings: 1
Award: $60.77
🌟 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.7743 USDC - $60.77
During the audit, 3 low and 5 non-critical issues were found.
â„– | Title | Risk Rating | Instance Count |
---|---|---|---|
L-1 | Storage variables can be packed tightly | Low | 2 |
L-2 | Large number of items may cause out-of-gas error | Low | 4 |
L-3 | Empty function bodies | Low | 3 |
NC-1 | Public functions can be external | Non-Critical | 18 |
NC-2 | Order of Functions | Non-Critical | 13 |
NC-3 | Scientific notation may be used | Non-Critical | 1 |
NC-4 | Missing NatSpec | Non-Critical | 10 |
NC-5 | Inconsistent use of named return variables | Non-Critical |
According to docs, multiple, contiguous items that need less than 32 bytes are packed into a single storage slot if possible. It might be beneficial to use reduced-size types if you are dealing with storage values because the compiler will pack multiple elements into one storage slot, and thus, combine multiple reads or writes into a single operation.
uint16 proposalThresholdBps; uint16 quorumThresholdBps; Treasury treasury; uint48 votingDelay; uint48 votingPeriod;
uint96 totalSupply; IBaseMetadata metadataRenderer; uint8 numFounders; uint8 totalOwnership;
Consider changing order of variables to:
Treasury treasury; //PACKED uint16 proposalThresholdBps; uint16 quorumThresholdBps; uint48 votingDelay; uint48 votingPeriod;
IBaseMetadata metadataRenderer; //PACKED uint96 totalSupply; uint8 numFounders; uint8 totalOwnership;
Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully: Due to the block gas limit, transactions can only consume a certain amount of gas. Either explicitly or just due to normal operation, the number of iterations in a loop can grow beyond the block gas limit, which can cause the complete contract to be stalled at a certain point.
for (uint256 i = 0; i < numTargets; ++i) {
for (uint256 i = 0; i < numNewProperties; ++i) {
for (uint256 i = 0; i < numNewItems; ++i) {
for (uint256 i; i < numFounders; ++i) {
Restrict the maximum number of items in loop.
function tokenURI(uint256 _tokenId) public view virtual returns (string memory) {}
function contractURI() public view virtual returns (string memory) {}
function _authorizeUpgrade(address _newImpl) internal override onlyOwner {}
If functions are not called by the contract where they are defined, they can be declared external.
function onERC721Received(
function onERC1155Received(
function onERC1155BatchReceived(
function tokenURI(uint256 _tokenId) public view virtual returns (string memory) {}
function contractURI() public view virtual returns (string memory) {}
function balanceOf(address _owner) public view returns (uint256) {
function ownerOf(uint256 _tokenId) public view returns (address) {
function getVotes(address _account) public view returns (uint256) {
function getPastVotes(address _account, uint256 _timestamp) public view returns (uint256) {
function DOMAIN_SEPARATOR() public view returns (bytes32) {
function owner() public view returns (address) {
function pendingOwner() public view returns (address) {
function transferOwnership(address _newOwner) public onlyOwner {
function safeTransferOwnership(address _newOwner) public onlyOwner {
function acceptOwnership() public onlyPendingOwner {
function cancelOwnershipTransfer() public onlyOwner {
function tokenURI(uint256 _tokenId) public view override(IToken, ERC721) returns (string memory) {
function contractURI() public view override(IToken, ERC721) returns (string memory) {
Make public functions external, where possible.
According to Style Guide, ordering helps readers identify which functions they can call and to find the constructor and fallback definitions easier.
Functions should be grouped according to their visibility and ordered:
Reorder functions where possible.
For readability, it is better to use scientific notation.
success := call(50000, _to, _amount, 0, 0, 0, 0)
Replace 50000
with 50e4
.
NatSpec is missing for 10 functions in 2 contracts.
Add NatSpec for all functions.
Some functions return named variables, others return explicit values.
For example:
/// @notice The minimum percentage an incoming bid must raise the highest bid function minBidIncrement() external view returns (uint256); /// @notice Updates the time duration of each auction /// @param duration The new time duration function setDuration(uint256 duration) external;
#0 - GalloDaSballo
2022-09-15T23:12:42Z
Some good ideas
#1 - GalloDaSballo
2022-09-27T13:43:08Z
3R 1NC