Platform: Code4rena
Start Date: 30/11/2021
Pot Size: $100,000 USDC
Total HM: 15
Participants: 36
Period: 7 days
Judge: 0xean
Total Solo HM: 4
Id: 62
League: ETH
Rank: 22/36
Findings: 2
Award: $1,340.61
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: harleythedog
Also found by: WatchPug, csanuragjain, gpersoon, hubble
317.2172 USDC - $317.22
hubble
Value of unstreamed public variable is not correct after stream depositor withdraws an amount before end of the stream.
File :Locke.sol Contract / Function : Stream / withdraw Line : 469 totalVirtualBalance -= virtualBal; depositTokenAmount -= amount;
Manual review
Add a line to update the value of unstreamed like below
File :Locke.sol Contract / Function : Stream / withdraw Line : 469
totalVirtualBalance -= virtualBal; depositTokenAmount -= amount; unstreamed -= amount;
#0 - 0xean
2022-01-16T00:27:33Z
dupe of #118
hubble
There needs to be consistency in checking the feePercent value in StreamFactory.updateFeeParams() versus Stream.constructor()
The check for feePercent in Stream.constructor() is redundant, however if required to be checked, then the max value to be checked should be consistent with the value in StreamFactory.updateFeeParams()
File :Locke.sol Contract / Function : StreamFactory / updateFeeParams() Line : 851 function updateFeeParams(GovernableFeeParams memory newFeeParams) public governed { require(newFeeParams.feePercent <= MAX_FEE_PERCENT, "fee");
Contract / Function : Stream / constructor() Line : 285 // limit feePercent require(feePercent < 10000, "fee");
Manual review
Option 1: Remove the check for feePercent if redundnat in Stream.cosntructor()
Option 2: define the same constant MAX_FEE_PERCENT in Stream contract storage uint16 constant MAX_FEE_PERCENT = 500; // 500/10000 == 5%
and udpate the value to check against in Stream.constructor() // limit feePercent require(feePercent <= MAX_FEE_PERCENT, "fee");
#0 - brockelmore
2022-01-05T17:34:49Z
duplicate #246
🌟 Selected for report: hubble
805.8152 USDC - $805.82
hubble
After endRewardLock, when all receipt token holders claim their rewardTokens, there may still be some balance(or dust) rewardTokens left, which will be NON-claimable by anyone. The mismatch in balance is because of the reward calculation accuracy, and virtualBalances used.
File :Locke.sol Contract / Function : Stream / earned Line : 469 function earned(TokenStream storage ts, uint256 currCumRewardPerToken) internal view returns (uint112) {
Contract / Function : Stream / rewardPerToken Line : 343 function rewardPerToken() public view returns (uint256) {
Manual review
Similar to function claimFees, the governance contract of the factory can send the balance(dust) rewardTokens to the stream Creator after checking all the users ts.rewards == 0
#0 - brockelmore
2022-01-05T17:34:08Z
this issue lacks detail - if its a dust issue, we are fine with it