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: 15/198
Findings: 3
Award: $416.87
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Trust
Also found by: 0xSky, CertoraInc, KIntern_NA, bin2chen, hansfriese, neko_nyaa, neumo, rokinot, wastewa
388.9184 USDC - $388.92
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L176
Rewards of high value will be unable to be withdrawn since claimableAmount()
will revert.
In line 176, if we assume there's a claim of a token with 18
decimals and a vesting of 1 year, which is a realistic vesting period that can be observed for deployed and battle tested protocols like Curve, a period that is translated to 31_536_000 seconds, then the operation _claim.linearVestAmount * truncatedCurrentVestingDurationSecs
will overflow if there's a claim of at least (2^112) - 1 / (1e18 * 31_536_000)
tokens, which is 164 million tokens.
This high vesting amount may be achieved if there's a token allocation for the team/investors, which often can be observed to take 10~30% of the total supply. The problem becomes more exarcebated for tokens with high supplies, as claims will be larger in nominal terms and thus easier to reach the 112 bits cap. For example, a cryptocurrency like JPEG'd which has total supply of 69 billion, would overflow with the equivalent of 91 thousand dollars in tokens (current price as the time of this writing is $0.00055676 USD).
Code reading, Remix
Change the line to
uint112 linearVestAmount = truncatedCurrentVestingDurationSecs * (_claim.linearVestAmount / finalVestingDurationSecs);
For tokens with 18 decimals (which is industry standard), the division above will only round down to zero for very small amounts and high vesting periods, if we use our example of one year vesting again, then _claim.linearVestAmount
would have to be lower than finalVestingDurationSecs, equivalent to 3.1536e-11
tokens. The variable truncatedCurrentVestingDurationSecs
already guarantees there will be no rounding errors.
#0 - 0xean
2022-09-24T19:17:48Z
dupe of #95
🌟 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
An administrator can revoke it's own power calling setAdmin()
with it's own address and boolean as false. This will leave unallocated tokens and tokens accidentally sent to the contract stuck forever, since it will be impossible to set a new administrator.
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/AccessProtected.sol#L39-L43
Consider reverting the setAdmin transaction if there's only one administrator set. It's worthy noting this may also be considered a feature rather than a bug.
#0 - 0xean
2022-09-25T21:26:07Z
dupe of #469
🌟 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
require
statements with and
conditionals should be separated into different require
statements, consuming less gas.https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L344-L351
require()
statements.There are 17 instances in VTVLVesting.sol and 2 in AccessProtected.sol