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: 21/99
Findings: 5
Award: $552.08
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xDjango
Also found by: BowTiedWardens, Metatron, cccz, hansfriese, shung, ych18, zzzitron
Staking.setCurvePool() doesn't approve allowance when changes CURVE_POOL. It will affect when users exchange asset through CURVE_POOL.
When initialize the contract, Staking contract approves CURVE_POOL here.
But when admin updates CURVE_POOL here, it doesn't approve for the new CURVE_POOL, this exchange logic wouldn't work properly.
Solidity Visual Developer of VSCode
We should approve the new CURVE_POOL. Replace L159 like below. It's not recommended using ERC20.approve() as I suggest in my low risk findings, but I just wrote same as the original one here.
if (CURVE_POOL != address(0)) { IERC20(TOKE_POOL).approve(CURVE_POOL, type(uint256).max); setToAndFromCurve(); }
#0 - toshiSat
2022-06-27T21:24:22Z
duplicate #264
#1 - KenzoAgada
2022-08-26T08:54:41Z
The judging sheet mentions this as duplicate of #222 instead of #165.
🌟 Selected for report: BowTiedWardens
Also found by: PwnedNoMore, TrungOre, hansfriese, hubble, minhquanym, shung
https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/Yieldy.sol#L100 https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/Yieldy.sol#L110-L131
Yieldy._storeRebase() saves and emits wrong values. I don't think the asset will be lost directly because of this but the rebase storage will have wrong values and it might affect the system later.
The _previousCirculating must be a previous total supply but it passes current total supply here. As a result, rebasePercent, rebase: rebasePercent,, totalStakedBefore: _previousCirculating,, rebasePercent will be saved and emitted incorrectly.
Solidity Visual Developer of VSCode
We should pass previous total supply here.
_storeRebase(currentTotalSupply, _profit, _epoch);
#0 - toshiSat
2022-06-27T21:23:40Z
duplicate #259
🌟 Selected for report: Chom
Also found by: hansfriese, minhquanym
https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/Yieldy.sol#L91-L98 https://github.com/code-423n4/2022-06-yieldy/blob/524f3b83522125fb7d4677fa7a7e5ba5a2c0fe67/src/contracts/Yieldy.sol#L257
Yieldy._totalSupply has different upper bounds. Yieldy._mint() will revert when _totalSupply is exactly same as MAX_SUPPLY.
From L91-L98, we can see _totalSupply can be same as MAX_SUPPLY and I think "_totalSupply <= MAX_SUPPLY" is reasonable also. Btw here, it checks a strict inequality and _mint() function will be failed when _totalSupply is exactly same as MAX_SUPPLY even though it should work properly.
Solidity Visual Developer of VSCode
We should modify this part.
require(_totalSupply <= MAX_SUPPLY, "Max supply");
#0 - toshiSat
2022-07-28T19:25:46Z
duplicate #200
🌟 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.3348 USDC - $53.33
🌟 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
We can modify like below. We can assume there is no duplicate elements according to G8. This approach won't save the order of elements after deleting.
uint256 contractsLength = contracts.length; for (uint256 i; i < contractsLength; ) { if (contracts[i] == _address) { contracts[i] = contracts[contractsLength - 1]; contracts.pop(); break; } unchecked { ++i; } }