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: 58/198
Findings: 3
Award: $52.43
🌟 Selected for report: 1
🚀 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
maxSupply
is used to limit the totalSupply
after initial supply but here mint()
will continue to mint even if mintableSupply
passed.
initialSupply
= 100 and maxSupply
= 200mint()
with 200 tokens amount, mintableSupply
will be 0 and it will mint 200 tokensmint()
with 500 tokens amount,
Manual Analysis
_mint()
only if mintableSupply > 0
if(mintableSupply > 0) { require(account != address(0), "INVALID_ADDRESS"); mintableSupply -= amount; _mint(account, amount); }
#0 - 0xean
2022-09-23T23:54:28Z
dupe of #3
🌟 Selected for report: rajatbeladiya
Also found by: 0x4non, CertoraInc, Chom, JLevick, JohnSmith, KIntern_NA, Ruhum, RustyRabbit, ak1, berndartmueller, imare, joestakey, obront, rbserver, rotcivegaf, supernova
32.8268 USDC - $32.83
https://github.com/code-423n4/2022-09-vtvl/blob/f68b7f3e61dad0d873b5b5a1e8126b839afeab5f/contracts/VTVLVesting.sol#L418-L437 https://github.com/code-423n4/2022-09-vtvl/blob/f68b7f3e61dad0d873b5b5a1e8126b839afeab5f/contracts/VTVLVesting.sol#L245-L253 https://github.com/code-423n4/2022-09-vtvl/blob/f68b7f3e61dad0d873b5b5a1e8126b839afeab5f/contracts/VTVLVesting.sol#L123-L140
if admin revoked any recipient’s claim, admin can not create claim for the same recipient because startTimestamp
is not updated to initial value on revoke claim.
There will be a need to create a claim again for any reason like, 1. mistakenly revoked claim 2. Wrong info provided to claim 3. new vesting period starts, etc.
evokeClaim()
, claim’s isActive will be false, but startTimestamp
will be remain as it ishasNoClaim()
which is checked for claim should not active and it checks for require(_claim.startTimestamp == 0, "CLAIM_ALREADY_EXISTS");
Manual Analysis
Update startTimestamp to 0
on revokeClaim()
#0 - 0xean
2022-09-24T18:37:21Z
Downgrading to low severity. While true why wouldn't the employee just use a different address? There is no residual benefit to using the old address (unless it was a smart contract, which the warden doesn't mention as part of their POC). The sponsor may want to fix this, since the fix is simple, but it poses very little risk and certainly no direct loss of funds.
#1 - 0xean
2022-09-24T18:37:58Z
closing as dupe of #141 - wardens QA report.
#2 - 0xean
2022-09-25T13:44:42Z
Spent a bit more time thinking about this one and do think that it qualifies as M severity since it does affect the availability of the protocol in a number of ways. Going to go ahead and revise to M and fix all the dupes.
#3 - lawrencehui
2022-10-07T00:19:38Z
The vesting contract is designed to be created and used in a one-off manner and the revoke function is to prevent any mistakes that made upon creation (wrong address / amount / timestamp etc.). In practical sense, if a claim (or the recipient address) is revoked, one (the admin) can always create a new vesting contract with the correct claim parameters.
I therefore think that it is by design that the address is only able be claimable once per vesting contract, in all circumstance, the admin can re-create a new vesting contract to mitigate this issue and therefore this is a low risk / non-critical issue.
#4 - 0xean
2022-10-07T22:54:58Z
I don't think the tactic of deploying a new contract is the correct one here simply to be able to set up vesting for one botched person or someone whose vesting token amount changes for example. I am going to stick with the M severity on this one, but do appreciate the response and thoughts on possible mitigations.
#5 - aktech297
2022-10-16T03:41:46Z
I have explained one of the real use case scenario where this protocol will fail to serve many. Refer the issue https://github.com/code-423n4/2022-09-vtvl-findings/issues/384. It is not always contract address or EOA which will decide the identity of a person. Each one will have unique ID. That id is gonna used in all the places.
🌟 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.8577 USDC - $18.86
Unused imported Ownable contract
Unlocked pragma
recommend to use locked pragma because unlocked pragma uses, meaning compiler will use the specified version or above. It's good practice to use specific solidity version to know compiler bug fixes and optimisations were enabled at the time of compiling the contract.
Storage could be changed to memory
withdrawAdmin() function could be declared as external