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: 87/198
Findings: 2
Award: $28.24
🌟 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
19.1525 USDC - $19.15
Context:
for (uint256 i = 0; i < length; i++) { _createClaimUnchecked(_recipients[i], _startTimestamps[i], _endTimestamps[i], _cliffReleaseTimestamps[i], _releaseIntervalsSecs[i], _linearVestAmounts[i], _cliffAmounts[i]); }
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L353
Description:
Either explicitly or just due to normal operation, the number of iterations in a loop can grow beyond the block gas limit, which can cause the complete contract to be stalled at a certain point.
Context:
pragma solidity ^0.8.14;
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/token/VariableSupplyERC20Token.sol#L2
Recommendation:
https://swcregistry.io/docs/SWC-103
Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
Context:
Description:
Public functions can be declared external if they are not called by the contract.
Recommendation:
Declare these functions as external instead of public.
Context:
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/token/FullPremintERC20Token.sol
function mint(address account, uint256 amount) public onlyAdmin {
function isAdmin(address _addressToCheck) external view returns (bool) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/AccessProtected.sol#L29
/** @notice Emitted when a founder adds a vesting schedule. */ event ClaimCreated(address indexed _recipient, Claim _claim);
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L56
/** @notice Emitted when someone withdraws a vested amount */ event Claimed(address indexed _recipient, uint112 _withdrawalAmount);
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L61
event ClaimRevoked(address indexed _recipient, uint112 _numTokensWithheld, uint256 revocationTimestamp, Claim _claim);
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L66
/** @notice Emitted when a claim is revoked */ event ClaimRevoked(address indexed _recipient, uint112 _numTokensWithheld, uint256 revocationTimestamp, Claim _claim);
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L74
/** @notice Construct the contract, taking the ERC20 token to be vested as the parameter. @dev The owner can set the contract in question when creating the contract. */ constructor(IERC20 _tokenAddress) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L77
/** @notice Basic getter for a claim. @dev Could be using public claims var, but this is cleaner in terms of naming. (getClaim(address) as opposed to claims(address)). @param _recipient - the address for which we fetch the claim. */ function getClaim(address _recipient) external view returns (Claim memory) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L86
/** @notice This modifier requires that an user has a claim attached. @dev To determine this, we check that a claim: * - is active * - start timestamp is nonzero. * These are sufficient conditions because we only ever set startTimestamp in * createClaim, and we never change it. Therefore, startTimestamp will be set * IFF a claim has been created. In addition to that, we need to check * a claim is active (since this is has_*Active*_Claim) */ modifier hasActiveClaim(address _recipient) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L95
/** @notice Modifier which is opposite hasActiveClaim @dev Requires that all fields are unset */ modifier hasNoClaim(address _recipient) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L119
/** @notice Pure function to calculate the vested amount from a given _claim, at a reference timestamp @param _claim The claim in question @param _referenceTs Timestamp for which we're calculating */ function _baseVestedAmount(Claim memory _claim, uint40 _referenceTs) internal pure returns (uint112) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L142
/** @notice Calculate the amount vested for a given _recipient at a reference timestamp. @param _recipient - The address for whom we're calculating @param _referenceTs - The timestamp at which we want to calculate the vested amount. @dev Simply call the _baseVestedAmount for the claim in question */ function vestedAmount(address _recipient, uint40 _referenceTs) public view returns (uint112) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L190
/** @notice Calculate the total vested at the end of the schedule, by simply feeding in the end timestamp to the function above. @dev This fn is somewhat superfluous, should probably be removed. @param _recipient - The address for whom we're calculating */ function finalVestedAmount(address _recipient) public view returns (uint112) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L201
/** @notice Calculates how much can we claim, by subtracting the already withdrawn amount from the vestedAmount at this moment. @param _recipient - The address for whom we're calculating */ function claimableAmount(address _recipient) external view returns (uint112) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L211
/** @notice Return all the addresses that have vesting schedules attached. */ function allVestingRecipients() external view returns (address[] memory) { return vestingRecipients; }
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L220
/** @notice Get the total number of vesting recipients. */ function numVestingRecipients() external view returns (uint256) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L227
/** @notice Allow an Owner to revoke a claim that is already active. @dev The requirement is that a claim exists and that it's active. */ function revokeClaim(address _recipient) external onlyAdmin hasActiveClaim(_recipient) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L414
🌟 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
Context:
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L433
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L161
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L179
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L301
Recommendation:
Change X += Y (X -= Y) to X = X + Y (X = X - Y).
Context:
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L148
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L353
Description:
Default value of uint is 0. It's unnecessary and costs more gas to initialize uint variavles to 0.
Recommendation:
Change uint112 vestAmt = 0; to uint112 vestAmt
Change uint256 i = 0; to uint256 i;
Context:
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/token/FullPremintERC20Token.sol#L11
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L256
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L257
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L263
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L272
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L273
Description:
uint256, uint112, uint96, uint40 type will never be less than 0.
Recommendation:
Change >0 to !=0.
Context:
for (uint256 i = 0; i < length; i++) {
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L353
Recommendation:
Change i++ to ++i.
Context:
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L167
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L170
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L377
https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/VTVLVesting.sol#L429
Description:
Some gas can be saved by using an unchecked {} block if an overflow/underflow isn't possible because of a previous require() or if-statement.
Recommendation:
Place the arithmetic operations in an unchecked block.