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: 36/55
Findings: 2
Award: $80.25
🌟 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
51.2645 USDC - $51.26
Since if there was no false
in it. It would be better to adding false
for "Reverts if no locks expired" so in this case down below :
File : MyStrategy.sol Line. 223
LOCKER.getReward(address(this));
can be changed to :
LOCKER.getReward(address(this), false);
Manual Review
Harvest event that every strategy MUST have. Since Event is an inheritable member of a contract. An event is emitted, it stores the arguments passed in transaction logs. These logs are stored on blockchain and are accessible using address of the contract till the contract is present on the blockchain.
File : MyStrategy.sol Line. 219
The require function should be used to check return values from calls to external contracts or to guarantee that valid conditions, such as inputs or contract state variables, are satisfied.
1.) File : MyStrategy.sol Line. 57
assert(IVault(_vault).token() == address(AURA));
return
On this case it can be shorter by just call return protected;
instead of return protectedTokens;
.
Manual Review
Code architecture, incentives, and error handling/reporting questions/issues. It should be resolved before deployment
1.) File : MyStrategy.sol Line. 85
///@dev Should we check if the amount requested is more than what we can return on withdrawal?
2.) File : MyStrategy.sol Line. 91
///@dev Should we processExpiredLocks during reinvest?
3.) File : MyStrategy.sol Line. 135
/// @dev Does this function require `tend` to be called?
4.) File : MyStrategy.sol Line. 284
// TODO: Hardcode claim.account = address(this)?
File : MyStrategy.sol Line.205
require(max >= _amount.mul(9_980).div(MAX_BPS), "Withdrawal Safety Check"); // 20 BP of slippage
There are many external risks so the suggestion was it should be consider making the contracts pausable, so if in the case of an unexpected event, the admin can pause transfers.
Manual Review
##POC https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/Pausable.sol
Consider making contracts Pausable
#0 - GalloDaSballo
2022-06-19T00:31:36Z
Not sure why unlocking and claiming rewards should mix
Disagree, we moved the event to the Vault: https://github.com/Badger-Finance/badger-vaults-1.5/blob/5abb584f93d564dea039a6b6a00a0cca11dd2b42/contracts/Vault.sol#L126
Disagree it's the one case where it's fine
Changing the name of the variable? Ah ok the Warden thinks we're using Yearn V2 code, this is incorrect per the code provided in the Context Readme
Rest i pretty much disagree
28.9852 USDC - $28.99
When tend
with no-op it could be this function below just doesn't do anything. It can be deleted instead for saving more gas
// Example tend is a no-op which returns the values, could also just revert function _tend() internal override returns (TokenAmount[] memory tended) { revert("no op"); }
Every reason string takes at least 32 bytes. Use short reason strings that fits in 32 bytes or it will become more expensive.
Manual Review
contracts/MyStrategy.sol#L186 "You have to wait for unlock or have to manually rebalance out of it"
#0 - GalloDaSballo
2022-06-19T00:26:33Z
Personally a reverting tend is more fun and is more compatible when you work with 20 other people