Platform: Code4rena
Start Date: 21/06/2022
Pot Size: $50,000 USDC
Total HM: 31
Participants: 99
Period: 5 days
Judges: moose-code, JasoonS, denhampreen
Total Solo HM: 17
Id: 139
League: ETH
Rank: 56/99
Findings: 2
Award: $79.87
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1337, 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 0xc0ffEE, 0xf15ers, 0xmint, Bnke0x0, BowTiedWardens, Chom, ElKu, FudgyDRS, Funen, GalloDaSballo, GimelSec, JC, Kaiziron, Lambda, Limbooo, Metatron, MiloTruck, Noah3o6, Picodes, PumpkingWok, PwnedNoMore, Sm4rty, StErMi, TomJ, TrungOre, UnusualTurtle, Waze, _Adam, aga7hokakological, ak1, antonttc, berndartmueller, cccz, cryptphi, csanuragjain, defsec, delfin454000, dipp, elprofesor, exd0tpy, fatherOfBlocks, hake, hansfriese, hubble, joestakey, kenta, ladboy233, mics, oyc_109, pashov, pedr02b2, reassor, robee, samruna, scaraven, shung, sikorico, simon135, sseefried, tchkvsky, unforgiven, zzzitron
53.1558 USDC - $53.16
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/Staking.sol#L246
function setTimeLeftToRequestWithdrawal(uint256 _timestamp) external onlyOwner { timeLeftToRequestWithdrawal = _timestamp; }
we can emit a event like other function did.
emit LogSetTimeLeftToRequestWithdrawl(uint256 ts);
🌟 Selected for report: BowTiedWardens
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 0xmint, 8olidity, ACai, Bnke0x0, Chom, ElKu, Fabble, Fitraldys, FudgyDRS, Funen, GalloDaSballo, GimelSec, IllIllI, JC, Kaiziron, Lambda, Limbooo, MiloTruck, Noah3o6, Nyamcil, Picodes, PwnedNoMore, Randyyy, RedOneN, Sm4rty, StErMi, TomJ, Tomio, TrungOre, UnusualTurtle, Waze, _Adam, aga7hokakological, ajtra, antonttc, asutorufos, bardamu, c3phas, defsec, delfin454000, exd0tpy, fatherOfBlocks, hansfriese, ignacio, joestakey, kenta, ladboy233, m_Rassska, mics, minhquanym, oyc_109, pashov, reassor, robee, s3cunda, sach1r0, saian, sashik_eth, scaraven, sikorico, simon135, slywaters
26.7051 USDC - $26.71
Since the contract uses an upgradeable contract, the developer separates the storage layout from the implementation.
In storage layout code, the unchanged state can be changed from public to immutable to save gas.
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/StakingStorage.sol#L8
address public TOKE_POOL; address public TOKE_MANAGER; address public TOKE_REWARD; address public STAKING_TOKEN; address public YIELDY_TOKEN; address public TOKE_TOKEN; address public LIQUIDITY_RESERVE;
all can be changed to immutable instead of public.
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/StakingStorage.sol#L18
address public COW_SETTLEMENT; address public COW_RELAYER;
the COW_SETTLEMENT and COW_RELAYER is set in staking constructor and never changed so, we can change from public to constants.
In Yieldly storage contract,
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/YieldyStorage.sol#L7
address public stakingContract; // immuable uint256 internal WAD; // immutable
stakingContract can be changed to immutable, WAS can be changed to constant.
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/LiquidityReserveStorage.sol#L5
in LiquidityReserveStorage
address public stakingToken; // staking token address address public rewardToken; // reward token address address public stakingContract; // staking contract address bool public isReserveEnabled; // ensures we are fully initialized
all can be set to immutable.
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/Staking.sol#L713
In function rebase in staking,
we can replace
if (balance <= staked) { epoch.distribute = 0; } else { epoch.distribute = balance - staked; }
with
epoch.distribute = balance <= staked ? 0 : balance - staked;
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/LiquidityReserve.sol#L134
function _calculateReserveTokenValue(uint256 _amount) internal view returns (uint256)
the function estimate the reserve token value as a helper function,
developer can use this _calculateReserveTokenValue function inside the function add Liquidity
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/LiquidityReserve.sol#L104
function addLiquidity(uint256 _amount) external
to replace the duplicate logic in addLiqudity
uint256 stakingTokenBalance = IERC20Upgradeable(stakingToken).balanceOf( address(this) ); uint256 rewardTokenBalance = IERC20Upgradeable(rewardToken).balanceOf( address(this) ); uint256 lrFoxSupply = totalSupply(); uint256 coolDownAmount = IStaking(stakingContract) .coolDownInfo(address(this)) .amount; uint256 totalLockedValue = stakingTokenBalance + rewardTokenBalance + coolDownAmount; uint256 amountToMint = (_amount * lrFoxSupply) / totalLockedValue;
https://github.com/code-423n4/2022-06-yieldy/blob/main/src/contracts/Staking.sol#L370
function unstakeAllFromTokemak() public onlyOwner {
we can change the function visibility from public to external to save gas.