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: 20/36
Findings: 2
Award: $1,677.35
🌟 Selected for report: 7
🚀 Solo Findings: 0
🌟 Selected for report: 0x1f8b
805.8152 USDC - $805.82
0x1f8b
Free flashloans for governance.
It's possible for governance to call a flashloan, pay the fee, and after it call claimFees
, by this way, he always will have a free flashloan service.
Manual review
Dificult to solve without distribute fees around the users
🌟 Selected for report: hyh
Also found by: 0x1f8b, Meta0xNull
0x1f8b
Lack of inputs during deployment could produce a re-deploy with human errors.
The unique variable validated was feePercent, but all the address must be checked to be != address(0) and _startTime + _streamDuration must be less than the current block.
Source reference: https://github.com/code-423n4/2021-11-streaming/blob/56d81204a00fc949d29ddd277169690318b36821/Streaming/src/Locke.sol#L264-L274
Manual review
Validate the input params, the address must be != address(0)
#0 - 0xean
2022-01-16T14:04:58Z
dupe of #68
🌟 Selected for report: 0x1f8b
0x1f8b
Optimize code.
Name and symbol must be inmutable https://github.com/code-423n4/2021-11-streaming/blob/56d81204a00fc949d29ddd277169690318b36821/Streaming/src/LockeERC20.sol#L21-L23.
Manual review
Set name and symbol as inmutable
#0 - 0xean
2022-01-16T14:02:36Z
marking as gas optimization
0x1f8b
Gas optimization.
In the line https://github.com/code-423n4/2021-11-streaming/blob/56d81204a00fc949d29ddd277169690318b36821/Streaming/src/Locke.sol#L711 it was multiply by 10 and then divided by 10.000, it's better to do only a div by 1.000, because the result will be the same.
Manual review
Change the line to: uint112 feeAmt = amount / 1000; // 10bps fee
#0 - 0xean
2022-01-16T14:41:17Z
dupe of #188
🌟 Selected for report: 0x1f8b
100.2104 USDC - $100.21
0x1f8b
Lower gas consumition.
The variable decimals it's inmutable, but his value it's always the same, it's better to use const in order to avoid the storage access consumition. https://github.com/code-423n4/2021-11-streaming/blob/56d81204a00fc949d29ddd277169690318b36821/Streaming/src/LockeERC20.sol#L25
Manual review
Use const for decimals
#0 - brockelmore
2021-12-02T16:24:02Z
The real solution is to inherit the deposit token's decimals
🌟 Selected for report: 0x1f8b
100.2104 USDC - $100.21
0x1f8b
Remove not used code is good for optimize the deployment and jumps.
state variable emergency_gov and externallyEmergencyGoverned and emergency_governed modifiers are not used, it's better to remove them from the code, or start to use this feature.
Manual review
Remove dead code
#0 - brockelmore
2021-12-01T17:22:38Z
It is a tradeoff between this specific contract and future contracts of the protocol. While it is deadcode now, the intent is that ancillary contracts will need it. For deployment we will remove the dead code though 👍
🌟 Selected for report: 0x1f8b
0x1f8b
Used wrong type during construction.
In the method fundStream of Locke contract, we can se that three cast was done, in order to get the balance with balanceOf
and do the transferFrom
. This can be avoided if we store the variable as ERC20.
Manual review
Store rewardToken as ERC20
🌟 Selected for report: 0x1f8b
0x1f8b
Empty blocks was found, it's good to remove them in order to spend less gas and improve the codding style.
The methods stake and withdraw has an empty block in the last condition, it's better to remove it in order to improve the codding style and gas expenses.
Source reference:
Manual review
Remove empty blocks
🌟 Selected for report: 0x1f8b
100.2104 USDC - $100.21
0x1f8b
Gas optimization.
In the method exit of Locke contract, ts.tokens was stored in a local variable, amount, and then this variable was used for call withdraw method, is better to call directly like withdraw(ts.tokens)
Source reference:
Manual review.
Remove the amount variable.
45.0947 USDC - $45.09
0x1f8b
Unneded checks.
In the flashloan method of Stream contract there are a mistake in the last requires:
if (token == depositToken) { depositTokenFlashloanFeeAmount += feeAmt; require(preDepositTokenBalance + feeAmt <= postDepositTokenBalance, "f1"); require(preRewardTokenBalance <= postRewardTokenBalance, "f2"); } else { rewardTokenFeeAmount += feeAmt; require(preDepositTokenBalance <= postDepositTokenBalance, "f3"); require(preRewardTokenBalance + feeAmt <= postRewardTokenBalance, "f4"); }
It check the balances from depositToken when it was rewardToken, and from rewardToken when it's depositToken, these checks are not required because only one transfer was done.
Source reference:
Manual review
Remove checks from the other token
#0 - brockelmore
2021-12-02T16:18:09Z
duplicate #50