Platform: Code4rena
Start Date: 06/12/2022
Pot Size: $36,500 USDC
Total HM: 16
Participants: 119
Period: 3 days
Judge: berndartmueller
Total Solo HM: 2
Id: 189
League: ETH
Rank: 73/119
Findings: 1
Award: $31.16
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xSmartContract
Also found by: 0x1f8b, 0x4non, 0xA5DF, 0xNazgul, 0xRobocop, 0xfuje, Bnke0x0, HollaDieWaldfee, Lambda, RaymondFam, TomJ, _Adam, adriro, ajtra, carrotsmuggler, cccz, danyams, gasperpre, hansfriese, helios, immeas, joestakey, ladboy233, nameruse, obront, oyc_109, rvierdiiev, saian, sakshamguruji, seyni, slvDev, yixxas, zaskoh
31.1555 USDC - $31.16
 
Use of _mint is discouraged and recommended to use _safeMint whenever possible by OpenZeppelin. This is because _mint cannot check whether the receiving address know how to handle ERC721 tokens.
In the function shown at below PoC, ERC721 token is sent to msg.sender with the _mint method. If this msg.sender is a contract and is not aware of incoming ERC721 tokens, the sent token can be locked up in the contract forever.
function mint(address to, uint256 tokenId) public virtual onlyRole(MINTER_ROLE) { _mint(to, tokenId); }
for (uint48 x = sale_.currentId + 1; x <= newId; x++) { nft.mint(msg.sender, x); }
for (uint24 x = temp.currentId + 1; x <= newId; x++) { nft.mint(msg.sender, x); }
for (uint256 x = temp.currentId + 1; x <= newId; x++) { nft.mint(msg.sender, x); }
I recommend to call the _safeMint() method instead of _mint().
 
I recommend adding check of 0-address for input validation of critical address parameters. Not doing so might lead to non-functional contract and have to redeploy the contract, when it is updated to 0-address accidentally.
Total of 6 instances found.
Escher721Factory.sol:constructor(): escher
address
https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/Escher721Factory.sol#L17-L18
Escher721Factory.sol:createContract(): _uri
address
https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/Escher721Factory.sol#L35
Escher.sol:addCreator(): _account
address
https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/Escher.sol#L28
LPDAFactory.sol:setFeeReceiver(): fees
address
https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/minters/LPDAFactory.sol#L46-L47
OpenEditionFactory.sol:setFeeReceiver(): fees
address
https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/minters/OpenEditionFactory.sol#L42-L43
FixedPriceFactory.sol:setFeeReceiver(): fees
address
https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/minters/FixedPriceFactory.sol#L42-L43
Add 0-address check for above addresses.
 
It is best practice to lock your pragma instead of using floating pragma. The use of floating pragma has a risk of accidentally get deployed using latest complier which may have higher risk of undiscovered bugs. Reference: https://consensys.github.io/smart-contract-best-practices/development-recommendations/solidity-specific/locking-pragmas/
Total of 12 instances found.
./LPDAFactory.sol:2:pragma solidity ^0.8.17; ./FixedPriceFactory.sol:2:pragma solidity ^0.8.17; ./Escher.sol:2:pragma solidity ^0.8.17; ./OpenEdition.sol:2:pragma solidity ^0.8.17; ./Unique.sol:2:pragma solidity ^0.8.17; ./OpenEditionFactory.sol:2:pragma solidity ^0.8.17; ./Generative.sol:2:pragma solidity ^0.8.17; ./Base.sol:2:pragma solidity ^0.8.17; ./LPDA.sol:2:pragma solidity ^0.8.17; ./FixedPrice.sol:2:pragma solidity ^0.8.17; ./Escher721Factory.sol:2:pragma solidity ^0.8.17; ./Escher721.sol:2:pragma solidity ^0.8.17;
I suggest to lock your pragma and aviod using floating pragma.
// bad pragma solidity ^0.8.10; // good pragma solidity 0.8.10;
 
Following NatSpec has incorrect comments.
NatSpec on Line 84 of FixedPrice.sol is not relevant. Delete this line. https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/minters/FixedPrice.sol#L84
84: /// @notice cancel a fixed price sale 85: /// @notice the price of the sale 86: function getPrice() public view returns (uint256) { 87: return sale.price; 88: }
 
There is an unnecessary contract inheritance.
File: FixedPrice.sol 10:contract FixedPrice is Initializable, OwnableUpgradeable, ISale {
File: OwnableUpgradeable.sol 21:abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
 
It is best practice to define magic numbers to constant rather than just using as a magic number. This improves code readability and maintainability.
./OpenEdition.sol:92: ISaleFactory(factory).feeReceiver().transfer(address(this).balance / 20); ./LPDA.sol:84: uint256 fee = totalSale / 20; ./FixedPrice.sol:109: ISaleFactory(factory).feeReceiver().transfer(address(this).balance / 20);
Define magic numbers to constant.
 
#0 - c4-judge
2023-01-04T10:32:55Z
berndartmueller marked the issue as grade-b