Platform: Code4rena
Start Date: 12/08/2022
Pot Size: $35,000 USDC
Total HM: 10
Participants: 126
Period: 3 days
Judge: Justin Goro
Total Solo HM: 3
Id: 154
League: ETH
Rank: 81/126
Findings: 2
Award: $44.84
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: oyc_109
Also found by: 0x1f8b, 0x52, 0xDjango, 0xLovesleep, 0xNazgul, 0xNineDec, 0xbepresent, 0xmatt, 0xsolstars, Aymen0909, Bahurum, Bnke0x0, CertoraInc, Chom, CodingNameKiki, DecorativePineapple, Deivitto, Dravee, ElKu, Funen, GalloDaSballo, IllIllI, JC, JohnSmith, Junnon, KIntern_NA, Lambda, LeoS, MiloTruck, Noah3o6, PaludoX0, RedOneN, Respx, ReyAdmirado, Rohan16, RoiEvenHaim, Rolezn, Ruhum, Sm4rty, TomJ, Vexjon, Waze, Yiko, __141345__, a12jmx, ajtra, ak1, apostle0x01, asutorufos, auditor0517, bin2chen, bobirichman, brgltd, bulej93, byndooa, c3phas, cRat1st0s, cryptphi, csanuragjain, d3e4, defsec, delfin454000, djxploit, durianSausage, ellahi, erictee, exd0tpy, fatherOfBlocks, gogo, jonatascm, ladboy233, medikko, mics, natzuu, neumo, p_crypt0, paribus, pfapostol, rbserver, reassor, ret2basic, robee, rokinot, rvierdiiev, sach1r0, saneryee, seyni, sikorico, simon135, sseefried, wagmi, wastewa
29.8925 USDC - $29.89
ERC20 operations can be unsafe due to different implementations and vulnerabilities in the standard.
It is therefore recommended to always either use OpenZeppelin's SafeERC20 library or at least to wrap each operation in a require statement.
To circumvent ERC20's approve
functions race-condition vulnerability use OpenZeppelin's SafeERC20 library's safe{Increase|Decrease}Allowance
functions.
contracts/mocks/MockSmartWallet.sol::20 => fdt.approve(ve, amount); contracts/mocks/MockSmartWallet.sol::25 => fdt.approve(ve, amount);
Avoid floating pragmas for non-library contracts.
While floating pragmas make sense for libraries to allow them to be included with multiple different versions of applications, it may be a security risk for application implementations.
A known vulnerable compiler version may accidentally be selected or security tools might fall-back to an older compiler version ending up checking a different EVM compilation that is ultimately deployed on the blockchain.
It is recommended to pin to a concrete compiler version.
contracts/VotingEscrow.sol::2 => pragma solidity ^0.8.3; contracts/features/Blocklist.sol::2 => pragma solidity ^0.8.3; contracts/interfaces/IBlocklist.sol::2 => pragma solidity ^0.8.3; contracts/interfaces/IERC20.sol::2 => pragma solidity ^0.8.3; contracts/interfaces/IVotingEscrow.sol::2 => pragma solidity ^0.8.3; contracts/mocks/MockERC20.sol::7 => pragma solidity ^0.8.0; contracts/mocks/MockSmartWallet.sol::2 => pragma solidity ^0.8.3;
🌟 Selected for report: IllIllI
Also found by: 0x040, 0x1f8b, 0xDjango, 0xHarry, 0xLovesleep, 0xNazgul, 0xNineDec, 0xSmartContract, 0xackermann, 0xbepresent, 2997ms, Amithuddar, Aymen0909, Bnke0x0, CRYP70, CertoraInc, Chom, CodingNameKiki, Deivitto, Dravee, ElKu, Fitraldys, Funen, GalloDaSballo, JC, JohnSmith, Junnon, LeoS, Metatron, MiloTruck, Noah3o6, NoamYakov, PaludoX0, RedOneN, Respx, ReyAdmirado, Rohan16, Rolezn, Ruhum, Sm4rty, SooYa, SpaceCake, TomJ, Tomio, Waze, Yiko, __141345__, a12jmx, ajtra, ak1, apostle0x01, asutorufos, bobirichman, brgltd, bulej93, c3phas, cRat1st0s, carlitox477, chrisdior4, csanuragjain, d3e4, defsec, delfin454000, djxploit, durianSausage, ellahi, erictee, fatherOfBlocks, gerdusx, gogo, ignacio, jag, ladboy233, m_Rassska, medikko, mics, natzuu, newfork01, oyc_109, paribus, pfapostol, rbserver, reassor, ret2basic, robee, rokinot, rvierdiiev, sach1r0, saian, sashik_eth, sikorico, simon135
14.9459 USDC - $14.95
Uninitialized variables are assigned with the types default value.
Explicitly initializing a variable with it's default value costs unnecesary gas.
contracts/VotingEscrow.sol::298 => uint256 blockSlope = 0; // dblock/dt contracts/VotingEscrow.sol::309 => for (uint256 i = 0; i < 255; i++) { contracts/VotingEscrow.sol::714 => uint256 min = 0; contracts/VotingEscrow.sol::717 => for (uint256 i = 0; i < 128; i++) { contracts/VotingEscrow.sol::737 => uint256 min = 0; contracts/VotingEscrow.sol::739 => for (uint256 i = 0; i < 128; i++) { contracts/VotingEscrow.sol::793 => uint256 dBlock = 0; contracts/VotingEscrow.sol::794 => uint256 dTime = 0; contracts/VotingEscrow.sol::834 => for (uint256 i = 0; i < 255; i++) { contracts/VotingEscrow.sol::889 => uint256 dTime = 0;
When dealing with unsigned integer types, comparisons with != 0
are cheaper then with > 0
.
contracts/VotingEscrow.sol::412 => require(_value > 0, "Only non zero amount"); contracts/VotingEscrow.sol::448 => require(_value > 0, "Only non zero amount"); contracts/VotingEscrow.sol::449 => require(locked_.amount > 0, "No lock"); contracts/VotingEscrow.sol::469 => require(locked_.amount > 0, "Delegatee has no lock"); contracts/VotingEscrow.sol::502 => require(locked_.amount > 0, "No lock"); contracts/VotingEscrow.sol::529 => require(locked_.amount > 0, "No lock"); contracts/VotingEscrow.sol::564 => require(locked_.amount > 0, "No lock"); contracts/VotingEscrow.sol::587 => require(toLocked.amount > 0, "Delegatee has no lock"); contracts/VotingEscrow.sol::635 => require(locked_.amount > 0, "No lock");
A division/multiplication by any number x being a power of 2 can be calculated by shifting log2(x) to the right/left.
While the DIV opcode uses 5 gas, the SHR opcode only uses 3 gas. Furthermore, Solidity's division operation also includes a division-by-0 prevention which is bypassed using shifting.
contracts/VotingEscrow.sol::719 => uint256 mid = (min + max + 1) / 2; contracts/VotingEscrow.sol::743 => uint256 mid = (min + max + 1) / 2;