Platform: Code4rena
Start Date: 15/06/2022
Pot Size: $30,000 USDC
Total HM: 5
Participants: 55
Period: 3 days
Judge: Jack the Pug
Id: 138
League: ETH
Rank: 18/55
Findings: 2
Award: $188.08
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0xDjango, 0xFar5eer, 0xNazgul, 0xNineDec, 242, Chom, Czar102, Funen, GimelSec, Meera, Picodes, Sm4rty, Tadashi, TerrierLover, Waze, _Adam, a12jmx, asutorufos, codexploder, cryptphi, defsec, gzeon, hyh, joestakey, minhquanym, oyc_109, reassor, robee, saian, sorrynotsorry, unforgiven, zzzitron
102.4813 USDC - $102.48
Low
Missing checks for zero addresses might lead to loss of funds, failed transactions and can break the protocol functionality.
MyStrategy.sol
:
newBribesProcessor
- https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L98Manual Review / VSCode
It is recommended to add zero address checks for listed parameters.
Low
Contract is missing emitting events for critical functions. Lack of events makes it difficult for off-chain applications to monitor the protocol.
MyStrategy.sol
:
setWithdrawalSafetyCheck
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L86setProcessLocksOnReinvest
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L92setBribesProcessor
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L98sweepRewardToken
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L107_harvest
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L219claimBribesFromHiddenHand
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L288reinvest
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L353manualSendAuraToVault
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L379_sendBadgerToTree
function event - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L428Manual Review / VSCode
It is recommended to add missing events to listed functions.
Non-Critical
Events should index addresses which helps off-chain applications in monitoring the protocol.
MyStrategy.sol
:
token
address - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L51Manual Review / VSCode
It is recommended to add indexing to address
type parameters.
Non-Critical
Function safeApprove
has been deprecated in favor of safeIncreaseAllowance()
and safeDecreaseAllowance()
.
MyStrategy.sol:65: AURA.safeApprove(address(LOCKER), type(uint256).max); MyStrategy.sol:67: AURABAL.safeApprove(address(BALANCER_VAULT), type(uint256).max); MyStrategy.sol:68: WETH.safeApprove(address(BALANCER_VAULT), type(uint256).max);
Manual Review / VSCode
It is recommended to consider using safeIncreaseAllowance()
and safeDecreaseAllowance()
functions instead of safeApprove
.
Non-Critical
Contract is missing natspec comments which makes code more difficult to read and prone to errors.
MyStrategy.sol
:
@param _vault
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L53-L56@param delegate
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L78-L79@param newWithdrawalSafetyCheck
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L86@param newProcessLocksOnReinvest
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L92@param newBribesProcessor
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L98@param token
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L107@param tokens[]
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L116@param _amount
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L171@return string
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L125-L126@return string
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L130-L131@return bool
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L135-L136@return balance
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L140-L141@return rewards[]
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L149@return protectedTokens
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L158-L161@param _amount
, @return _amount
comments - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L192-L194@return harvested
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L219@param hiddenHandDistributor
, _claims
comments - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L288@return toDeposit
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L353@param token
, @param amount
comments - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L421@param amount
comment - https://github.com/Badger-Finance/vested-aura/blob/d504684e4f9b56660a9e6c6dfb839dcebac3c174/contracts/MyStrategy.sol#L428Manual Review / VSCode
It is recommended to add missing natspec comments.
#0 - GalloDaSballo
2022-06-19T01:33:42Z
I'm pretty confident you don't need to natspec things when they are obvious.
As a wise programmer would say: The best comment is the one you don't need to write
#1 - lucyoa
2022-06-30T20:50:25Z
natspec will let you generate documentation easily
and since we are quoting, let me drop one too :) "Documentation is like sex: when it is good, it is very, very good; and when it is bad, it is better than nothing."
85.5954 USDC - $85.60
Contract is implemeting sweepRewardToken
that is protected against reentrancy attacks with reentrancy guard. The issue is that the function sweepRewardToken
can be executed in the loop through sweepRewards
function which makes costly reentrancy guard changes with every iteration and invocation of sweepRewardToken
.
Manual Review / VSCode
It is recommended to consider making sweepRewardToken
an internal function (removing nonReentrant
) and adding nonReentrant
to sweepRewards
that will be used also for sweeping one token with (single element in tokens
array).
Function MyStrategy.claimBribesFromHiddenHand
is iterating over the array of claims to handle reward transfers. First it calculates balances for ether and tokens and then uses math calculation to understand how much of those should be sent via _handleRewardTransfer
. The issue with this approach is that since the contract does not allow withdrawing ether
the value of address(this).balance
should always be 0
(otherwise ether will get locked) thus it is better just to use address(this).balance
without spending gas on calculating the difference.
Manual Review / VSCode
It is recommended to skip calculations for ether
difference and always pass to _handleRewardTransfer
value of all ether in the contract - address(this).balance
.
Caching the array length outside a loop saves reading it on each iteration, as long as the array's length is not changed during the loop.
MyStrategy.sol:300: for (uint256 i = 0; i < _claims.length; i++) { MyStrategy.sol:317: for (uint256 i = 0; i < _claims.length; i++) {
Manual Review / VSCode
It is recommended to cache the array length outside of for loop.
Shortening revert error messages to fit in 32 bytes will decrease gas costs for deployment and gas costs when the revert condition has been met.
MyStrategy.sol:184: require( MyStrategy.sol:185: balanceOfPool() == 0 && LOCKER.balanceOf(address(this)) == 0, MyStrategy.sol:186: "You have to wait for unlock or have to manually rebalance out of it" MyStrategy.sol:187: );
Manual Review / VSCode
It is recommended to decrease revert messages to maximum 32 bytes.
++i
or --i
costs less gas compared to i++
, i += 1
, i--
or i -= 1
for unsigned integer as pre-increment/pre-decrement is cheaper (about 5 gas per iteration).
118: for(uint i = 0; i < length; i++){ 300: for (uint256 i = 0; i < _claims.length; i++) { 317: for (uint256 i = 0; i < _claims.length; i++) {
Manual Review / VSCode
It is recommended to use ++i
or --i
instead of i++
, i += 1
, i--
or i -= 1
to increment value of an unsigned integer variable.
If a variable is not set/initialized, it is assumed to have the default value (0
for uint, false
for bool, address(0)
for addresses). Explicitly initializing it with its default value is an anti-pattern and waste of gas.
MyStrategy.sol:118: for(uint i = 0; i < length; i++){ MyStrategy.sol:300: for (uint256 i = 0; i < _claims.length; i++) { MyStrategy.sol:317: for (uint256 i = 0; i < _claims.length; i++) {
Manual Review / VSCode
It is recommended to remove explicit initializations with default values.
When dealing with unsigned integer types, comparisons with != 0
are cheaper than with > 0
.
MyStrategy.sol:230: if (auraBalEarned > 0) { MyStrategy.sol:279: if (harvested[0].amount > 0) { MyStrategy.sol:323: if (difference > 0) { MyStrategy.sol:330: if (difference > 0) { MyStrategy.sol:387: upkeepNeeded = unlockable > 0;
Manual Review / VSCode
It is recommended to use != 0
instead of > 0
.
#0 - GalloDaSballo
2022-06-19T01:32:45Z
Probably the highest gas savings
rest I ack