Platform: Code4rena
Start Date: 04/11/2021
Pot Size: $50,000 USDC
Total HM: 20
Participants: 28
Period: 7 days
Judge: 0xean
Total Solo HM: 11
Id: 51
League: ETH
Rank: 16/28
Findings: 3
Award: $683.86
🌟 Selected for report: 3
🚀 Solo Findings: 0
529.9131 USDC - $529.91
nathaniel
The timelocks for any beneficiary are unbounded, and can be vested by someone who is not the beneficiary. When the array becomes significantly big enough, the vestments will no longer be claimable for the beneficiary.
The vest()
function in Vesting.sol does not check the beneficiary, hence anyone can vest for anyone else, pushing a new timelock to the timelocks[_beneficiary]
.
The _claimableAmount()
function (used by claim()
function), then loops through the timelocks[_beneficiary]
to determine the amount to be claimed.
A malicious actor can easy repeatedly call the vest()
function with minute amounts to make the array large enough, such that when it comes to claiming, it will exceed the gas limit and revert, rendering the vestment for the beneficiary unclaimable.
The malicious actor could do this to each beneficiary, locking up all the vestments.
https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L81 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L195 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L148
Manual code review
require(beneficiary == msg.sender)
🌟 Selected for report: TomFrenchBlockchain
Also found by: PranavG, Reigada, WatchPug, jah, nathaniel, pants, pauliax, pmerkleplant
nathaniel
Constructor only set initTime
variable can be made immutable reducing gas costs.
#0 - chickenpie347
2022-01-03T22:40:35Z
Duplicate of #3
nathaniel
Unchanging variables can be made constant. e.g
unixYear, investors_supply, airdrop_supply
https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L30 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/InvestorDistribution.sol#L33 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/AirdropDistribution.sol#L462
#0 - chickenpie347
2022-01-03T22:39:53Z
Duplicate of #88
12.1196 USDC - $12.12
nathaniel
There exists both an available_supply
public function and _available_supply
private function with exactly the same code. Delete _available_supply
and in place use available_supply
function to reduce contract size and deployment gas cost. Alternatively, make available_supply an external function.
#0 - chickenpie347
2022-01-03T22:42:54Z
Duplicate of #96
4.4176 USDC - $4.42
nathaniel
Functions include `updateEmission(), dev_rugpull(), setAdmin(), revoke()
https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/InvestorDistribution.sol#L185 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/InvestorDistribution.sol#L203 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/InvestorDistribution.sol#L212 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L104
130.8427 USDC - $130.84
nathaniel
Inconsistency between the claim()
function and claimExact()
function, in that claimExact
does not check the claimable amount. In the scenario where claimable = 0, and investors[msg.sender].claimed != 0
then it will attempt to underflow.
If _amount
is 0, then it could potentially reach the vestLock.vest()
function, where it will then revert with the inaccurate message "amount must be positive" which doesn't reflect the underlying issue.
https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/InvestorDistribution.sol#L145 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/InvestorDistribution.sol#L121 https://github.com/code-423n4/2021-11-bootfinance/blob/main/vesting/contracts/Vesting.sol#L75
manual review
Add require(claimable > 0)