Platform: Code4rena
Start Date: 20/09/2022
Pot Size: $30,000 USDC
Total HM: 12
Participants: 198
Period: 3 days
Judge: 0xean
Total Solo HM: 2
Id: 164
League: ETH
Rank: 156/198
Findings: 2
Award: $9.83
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Czar102
Also found by: 0xDecorativePineapple, 0xNazgul, 0xSky, 0xbepresent, 0xmatt, Atarpara, Bahurum, DimitarDimitrov, Franfran, GimelSec, JGcarv, JLevick, Junnon, OptimismSec, Rolezn, Ruhum, Soosh, Tomo, Trust, __141345__, adriro, ajtra, bin2chen, cRat1st0s, cccz, cryptonue, d3e4, innertia, jag, joestakey, neumo, obront, pashov, pauliax, pcarranzav, peanuts, rajatbeladiya, rbserver, reassor, seyni, wagmi, zzykxx, zzzitron
0.7375 USDC - $0.74
Assume VariableSupplyERC20Token deploy with limited supply. This token mint doesn't allow after the max supply at deployment time but admin can be mint unlimited supply.
Consider the following scenarios:
admin deploy contract with token max supply 50 token and initial supply 0. As per logic token supply should not be increase 50. Now admin minted 50 token via mint function then mintableSupply set 0. Now admin can mint unlimited token because of mintableSupply is 0.
Manual Review
create new bool variable for the check contract allow unlimted or limited supply and set into constructor. change the mint function according bool variable.
function mint(address _account ,uint256 _amount ) public onlyAdmin{ require(account != address(0), "INVALID_ADDRESS"); if(isUnlimted) { _mint(_account,_amount); }else { require(amount <= mintableSupply, "INVALID_AMOUNT"); mintableSupply -= amount; _mint(account, amount); } }
#0 - 0xean
2022-09-23T23:55:05Z
dupe of #3
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x040, 0x1f8b, 0x4non, 0x85102, 0xA5DF, 0xDanielC, 0xNazgul, 0xSmartContract, 0xbepresent, 0xc0ffEE, 0xsam, 2997ms, AkshaySrivastav, Amithuddar, Atarpara, Aymen0909, B2, Bnke0x0, CertoraInc, Chom, ChristianKuri, CodingNameKiki, Deivitto, Diana, DimitarDimitrov, Diraco, Funen, JC, JLevick, JohnSmith, Junnon, KIntern_NA, Lambda, MasterCookie, Matin, Noah3o6, Ocean_Sky, OptimismSec, RaymondFam, Respx, ReyAdmirado, RockingMiles, Rohan16, Rolezn, Ruhum, Saintcode_, Satyam_Sharma, Sm4rty, SnowMan, SooYa, Sta1400, StevenL, Tadashi, Tagir2003, TomJ, Tomio, Tomo, V_B, Waze, WilliamAmbrozic, Yiko, __141345__, a12jmx, adriro, ajtra, ak1, async, aysha, beardofginger, bobirichman, brgltd, bulej93, c3phas, carrotsmuggler, caventa, ch0bu, cryptostellar5, cryptphi, csanuragjain, d3e4, delfin454000, dharma09, djxploit, durianSausage, eighty, emrekocak, erictee, exd0tpy, fatherOfBlocks, francoHacker, gianganhnguyen, gogo, got_targ, hxzy, ignacio, ikbkln, imare, indijanc, jag, jpserrat, karanctf, ladboy233, leosathya, lucacez, lukris02, m9800, malinariy, martin, medikko, mics, millersplanet, mrpathfindr, nalus, natzuu, neko_nyaa, oyc_109, pauliax, peanuts, pedroais, peiw, pfapostol, prasantgupta52, rbserver, ret2basic, rokinot, rotcivegaf, rvierdiiev, sach1r0, samruna, seyni, slowmoses, subtle77, supernova, tgolding55, tibthecat, tnevler, w0Lfrum, yaemsobak, zishansami
9.086 USDC - $9.09
As per ethereum yellow paper paid 2900 for an SSTORE operation when the storage value’s zeroness remains unchanged or is set to zero
File: VTVLVesting.sol Line-27
uint112 public numTokensReservedForVesting = 0;
Convert memory type to calldata for avoid unnecessary copy into memory
File: VTVLVesting.sol Line-334
The code would go from:
function createClaimsBatch( address[] memory _recipients, uint40[] memory _startTimestamps, uint40[] memory _endTimestamps, uint40[] memory _cliffReleaseTimestamps, uint40[] memory _releaseIntervalsSecs, uint112[] memory _linearVestAmounts, uint112[] memory _cliffAmounts) external onlyAdmin {}
To
function createClaimsBatch( address[] calldata _recipients, uint40[] calldata _startTimestamps, uint40[] calldata _endTimestamps, uint40[] calldata _cliffReleaseTimestamps, uint40[] calldata _releaseIntervalsSecs, uint112[] calldata _linearVestAmounts, uint112[] calldata _cliffAmounts) external onlyAdmin {}
In Solidity 0.8+, there’s a default overflow check on unsigned integers. It’s possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline.
File: VTVLVesting.sol Line-353
The code would go from:
for (uint256 i=0; i < length; ++i) { // ... }
to
for (uint256 i; i < length;) { // ... unchecked{ ++i; } }
File : VariableSupplyERC20Token.sol Line-27
In VariableSupplyERC20Token constructor requirement condition can be packed into one condition for the save deploytime gas cost and tiny bytecode size
The code would go from:
require(initialSupply_ > 0 || maxSupply_ > 0, "INVALID_AMOUNT");
To
require((initialSupply | maxSupply_) != 0, "INVALID_AMOUNT");
!= 0 costs less gas compared to > 0 for unsigned integers in require statements with the optimizer enabled (6 gas)
Instance Inclued :
File : VTVLVesting.sol Line-107 Line-256 Line-257 Line-263 Line-272-273 Line-449
File : VariableSupplyERC20Token.sol Line-27