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: 130/198
Findings: 2
Award: $27.95
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: AkshaySrivastav
Also found by: 0v3rf10w, 0x040, 0x1f8b, 0x4non, 0x5rings, 0x85102, 0xA5DF, 0xDecorativePineapple, 0xNazgul, 0xSky, 0xSmartContract, 0xbepresent, 0xf15ers, 0xmatt, 2997ms, Aeros, Aymen0909, B2, Bahurum, Bnke0x0, CertoraInc, Chom, ChristianKuri, CodingNameKiki, Deivitto, Diana, Diraco, Dravee, ElKu, Funen, IllIllI, JC, JLevick, JohnSmith, JohnnyTime, KIntern_NA, Lambda, Margaret, MasterCookie, OptimismSec, RaymondFam, Respx, ReyAdmirado, RockingMiles, Rohan16, Rolezn, Ruhum, RustyRabbit, Sm4rty, SooYa, StevenL, TomJ, Tomo, V_B, Waze, Yiko, __141345__, a12jmx, ajtra, ak1, async, ayeslick, aysha, berndartmueller, bin2chen, bobirichman, brgltd, bulej93, c3phas, carrotsmuggler, cccz, ch13fd357r0y3r, chatch, cryptostellar5, cryptphi, csanuragjain, d3e4, datapunk, delfin454000, dic0de, djxploit, durianSausage, eighty, erictee, exd0tpy, fatherOfBlocks, gogo, got_targ, hansfriese, ignacio, ikbkln, indijanc, innertia, joestakey, karanctf, ladboy233, leosathya, lukris02, martin, medikko, millersplanet, nalus, natzuu, neko_nyaa, neumo, obront, oyc_109, pcarranzav, peanuts, pedr02b2, pedroais, peiw, peritoflores, prasantgupta52, rajatbeladiya, rbserver, reassor, ret2basic, rokinot, romand, rotcivegaf, rvierdiiev, sach1r0, seyni, sikorico, slowmoses, sorrynotsorry, supernova, tibthecat, tnevler, ubermensch, yongskiws, zzykxx, zzzitron
18.8574 USDC - $18.86
VTVLVesting.sol:266: // Potential TODO: sanity check, if _linearVestAmount == 0, should we perhaps force that start and end ts are the same?
VTVLVesting.sol:83: tokenAddress = _tokenAddress;
VTVLVesting.sol:206: function finalVestedAmount(address _recipient) public view returns (uint112) { VTVLVesting.sol:398: function withdrawAdmin(uint112 _amountRequested) public onlyAdmin {
10e18
) rather than exponentiation (e.g. 10**18
)token/FullPremintERC20Token.sol:9: // uint constant _initialSupply = 100 * (10**18); test/TestERC20Token.sol:7: // uint constant _initialSupply = 100 * (10**18); test/TestERC20Token.sol:9: uint256 supplyToMint = initialSupply_ * (10 ** decimals());
🌟 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.0896 USDC - $9.09
VTVLVesting.sol:353: for (uint256 i = 0; i < length; i++) {
require()
statements that use &&
saves gasIf you're using the Optimizer at 200, instead of using the &&
operator in a single require statement to check multiple conditions, I suggest using multiple require statements with 1 condition per require statement:
VTVLVesting.sol:343: uint256 length = _recipients.length; VTVLVesting.sol:344: require(_startTimestamps.length == length && VTVLVesting.sol:345: _endTimestamps.length == length && VTVLVesting.sol:346: _cliffReleaseTimestamps.length == length && VTVLVesting.sol:347: _releaseIntervalsSecs.length == length && VTVLVesting.sol:348: _linearVestAmounts.length == length && VTVLVesting.sol:349: _cliffAmounts.length == length,
uints are 0
by default.removeing this will reduce contract size and save a bit of gas.VTVLVesting.sol:148: uint112 vestAmt = 0; VTVLVesting.sol:353: for (uint256 i = 0; i < length; i++) {
public
functions not called by the contract should be declared external
insteadVTVLVesting.sol:398: function withdrawAdmin(uint112 _amountRequested) public onlyAdmin {
VTVLVesting.sol:111: require(_claim.isActive == true, "NO_ACTIVE_CLAIM"); VTVLVesting.sol:129: require(_claim.startTimestamp == 0, "CLAIM_ALREADY_EXISTS"); VTVLVesting.sol:264: require((_endTimestamp - _startTimestamp) % _releaseIntervalSecs == 0, "INVALID_INTERVAL_LENGTH"); VTVLVesting.sol:276: _cliffReleaseTimestamp == 0 && VTVLVesting.sol:277: _cliffAmount == 0
!= 0
instead of > 0
in HolyPaladinToken.soltoken/VariableSupplyERC20Token.sol:27: require(initialSupply_ > 0 || maxSupply_ > 0, "INVALID_AMOUNT"); token/VariableSupplyERC20Token.sol:31: if(initialSupply_ > 0) { token/VariableSupplyERC20Token.sol:40: if(mintableSupply > 0) { token/FullPremintERC20Token.sol:11: require(supply_ > 0, "NO_ZERO_MINT"); VTVLVesting.sol:107: require(_claim.startTimestamp > 0, "NO_ACTIVE_CLAIM"); VTVLVesting.sol:256: require(_linearVestAmount + _cliffAmount > 0, "INVALID_VESTED_AMOUNT"); // Actually only one of linearvested/cliff amount must be 0, not necessarily both VTVLVesting.sol:257: require(_startTimestamp > 0, "INVALID_START_TIMESTAMP"); VTVLVesting.sol:263: require(_releaseIntervalSecs > 0, "INVALID_RELEASE_INTERVAL"); VTVLVesting.sol:272: _cliffReleaseTimestamp > 0 && VTVLVesting.sol:273: _cliffAmount > 0 && VTVLVesting.sol:449: require(bal > 0, "INSUFFICIENT_BALANCE");
costs more gas than
<x> = <x> + <y>`token/VariableSupplyERC20Token.sol:43: mintableSupply -= amount; VTVLVesting.sol:161: vestAmt += _claim.cliffAmount; VTVLVesting.sol:179: vestAmt += linearVestAmount; VTVLVesting.sol:301: numTokensReservedForVesting += allocatedAmount; // track the allocated amount VTVLVesting.sol:381: usrClaim.amountWithdrawn += amountRemaining; VTVLVesting.sol:383: numTokensReservedForVesting -= amountRemaining; VTVLVesting.sol:433: numTokensReservedForVesting -= amountRemaining; // Reduces the allocation
new admin
is already a admin
or the one to be removed
is alreadyremoved or non exist
this will save gas by avoiding rewrite of same data
AccessProtected.sol:39: function setAdmin(address admin, bool isEnabled) public onlyAdmin { AccessProtected.sol:40: require(admin != address(0), "INVALID_ADDRESS"); AccessProtected.sol:41: _admins[admin] = isEnabled; AccessProtected.sol:42: emit AdminAccessSet(admin, isEnabled); AccessProtected.sol:43: }