Platform: Code4rena
Start Date: 06/03/2023
Pot Size: $36,500 USDC
Total HM: 8
Participants: 93
Period: 3 days
Judge: cccz
Total Solo HM: 3
Id: 218
League: ETH
Rank: 61/93
Findings: 1
Award: $21.70
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0x1f8b, 0xAgro, 0xSmartContract, 0xfuje, 0xkazim, 0xnev, Aymen0909, Bason, Cyfrin, DadeKuma, LethL, Madalad, MohammedRizwan, Rolezn, SAAJ, SunSec, Udsen, Yukti_Chinta, ast3ros, bin2chen, brgltd, bshramin, btk, bugradar, catellatech, cryptostellar5, descharre, dontonka, erictee, fatherOfBlocks, georgits, glcanvas, hl_, horsefacts, igingu, juancito, lukris02, martin, nadin, nomoi, peanuts, pipoca, sakshamguruji, seeu, slvDev, tnevler, zaskoh
21.7018 USDC - $21.70
Issue
Total: 07 issues
There are many addresses and constants used in the system. It is recommended to put the most used ones in one file (for example constants.sol, use inheritance to access these values):
This will help with readability and easier maintenance for future changes. constants.sol Use and import this file in contracts that require access to these values. This is just a suggestion, in some use cases this may result in higher gas usage in the distribution
https://github.com/ethereum/solidity/blob/develop/Changelog.md
Description: Solidity code is also cleaner in another way that might not be noticeable: the struct Point. We were importing it previously with global import but not using it. The Point struct polluted the source code with an unnecessary object we were not using because we did not need it. This was breaking the rule of modularity and modular programming: only import what you need Specific imports with curly braces allow us to apply this rule better. Recommendation: import {contract1 , contract2} from "filename.sol"; A good example from the ArtGobblers project;
import {Owned} from "solmate/auth/Owned.sol"; import {ERC721} from "solmate/tokens/ERC721.sol"; import {LibString} from "solmate/utils/LibString.sol"; import {MerkleProofLib} from "solmate/utils/MerkleProofLib.sol"; import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol"; import {ERC1155, ERC1155TokenReceiver} from "solmate/tokens/ERC1155.sol"; import {toWadUnsafe, toDaysWadUnsafe} from "solmate/utils/SignedWadMath.sol";
It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). It is clearly stated in the Solidity official documentation. In complex projects such as Defi, the interpretation of all functions and their arguments and returns is important for code readability and auditability. https://docs.soliditylang.org/en/v0.8.15/natspec-format.html Recommendation: NatSpec comments should be increased in contracts
Description: Events help non-contract tools to track changes, and events prevent users from being surprised by changes Recommendation: Add Event-Emit File: src/staking/StakedTokenLock.sol
24: function deposit(uint256 amount) external override onlyOwner { 37: function withdraw(uint256 amount) external override onlyOwner { 50: function getReward() external override {
Assert should not be used except for tests, require should be used Prior to Solidity 0.8.0, pressing a confirm consumes the remainder of the process’s available gas instead of returning it, as request()/revert() did. assert() and reqire(); The big difference between the two is that the assert()function when false, uses up all the remaining gas and reverts all the changes made. Meanwhile, a require() function when false, also reverts back all the changes made to the contract but does refund all the remaining gas fees we offered to pay.This is the most common Solidity function used by developers for debugging and error handling. Assertion() should be avoided even after solidity version 0.8.0, because its documentation states “The Assert function generates an error of type Panic(uint256). Code that works properly should never Panic, even on invalid external input. If this happens, you need to fix it in your contract. there’s a mistake”. File: src/LotterySetup.sol
147: assert(initialPot > 0);
File: src/Lottery.sol
155: emit ClaimedRewards(beneficiary, claimedAmount, rewardType);
Issue
Total: 02 issues
https://www.paradigm.xyz/2021/08/the-dangers-of-surprising-code Use Openzeppelin or Solmate Re-Entrancy pattern. Here is a example of a re-entrancy guard File: src/staking/Staking.sol
79: function withdraw(uint256 amount) public override {
_mint() is discouraged (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4d8d2ed9798cc3383912a23b5e8d5cb602f7d4b/contracts/token/ERC721/ERC721.sol#L271) in favor of _safeMint() which ensures that the recipient is either an EOA or implements IERC721Receiver. Both OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/d4d8d2ed9798cc3383912a23b5e8d5cb602f7d4b/contracts/token/ERC721/ERC721.sol#L238-L250) and solmate (https://github.com/transmissions11/solmate/blob/4eaf6b68202e36f67cab379768ac6be304c8ebde/src/tokens/ERC721.sol#L180) have versions of this function File: src/staking/Staking.sol
74: _mint(msg.sender, amount);
Total: 01 issues
Description: I recommend using header for Solidity code layout and readability https://github.com/transmissions11/headers
/*////////////////////////////////////////////////////////////// TESTING 123 //////////////////////////////////////////////////////////////*/
#0 - thereksfour
2023-03-12T08:42:54Z
1L 2INFO 6 NC
#1 - c4-judge
2023-03-12T08:42:59Z
thereksfour marked the issue as grade-c
#2 - c4-judge
2023-03-12T11:41:21Z
thereksfour marked the issue as grade-b
#3 - c4-sponsor
2023-03-14T10:12:20Z
0xluckydev marked the issue as sponsor confirmed
#4 - 0xluckydev
2023-03-14T10:12:37Z
Less important, but confirmed