Platform: Code4rena
Start Date: 07/06/2022
Pot Size: $75,000 USDC
Total HM: 11
Participants: 77
Period: 7 days
Judge: gzeon
Total Solo HM: 7
Id: 124
League: ETH
Rank: 4/77
Findings: 3
Award: $5,642.61
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 Selected for report: csanuragjain
5505.9897 USDC - $5,505.99
If maturity is reached and user has asked for redeem with opts.transferfCash as true, then if (hasMatured()) turns true at wfCashLogic.sol#L216 causing fcash to be cashed out in underlying token and then sent to receiver. So receiver obtains underlying when fcash was expected. The sender wont get an error thinking fcash transfer was success
If opts.transferfCash is true and maturity is reached then throw an error mentioning that fCash can no longer be transferred
#0 - jeffywu
2022-06-15T14:32:17Z
Sounds reasonable
🌟 Selected for report: berndartmueller
Also found by: 0x1f8b, 0x29A, 0xDjango, 0xNazgul, 0xNineDec, 0xf15ers, 0xkatana, 0xmint, Bronicle, Chom, Cityscape, Deivitto, Funen, GimelSec, GreyArt, IllIllI, JC, Lambda, Meera, Nethermind, Picodes, PierrickGT, Ruhum, Sm4rty, Tadashi, TerrierLover, TomJ, Trumpero, Waze, _Adam, antonttc, ayeslick, c3phas, catchup, cccz, cloudjunky, cryptphi, csanuragjain, delfin454000, dipp, ellahi, fatherOfBlocks, hake, hansfriese, hyh, joestakey, jonah1005, kenzo, minhquanym, oyc_109, sach1r0, saian, simon135, slywaters, sorrynotsorry, sseefried, unforgiven, xiaoming90, z3s, zzzitron
89.1872 USDC - $89.19
An invalid maxMarketIndex is simply accepted by isValidMaturity function. Any maturity compared against this incorrect maxMarketIndex will lead to incorrect maturity being declared valid.
Simply add below checks:
require(maxMarketIndex > 0, "CG: no markets listed"); require(maxMarketIndex <= Constants.MAX_TRADED_MARKET_INDEX, "CG: market index bound");
While initialization, provided maturity is checked against cashGroup obtained from NotionalV2.getCashGroup. But it is never checked that this cashGroup is actually lying within range of Constants.MAX_TRADED_MARKET_INDEX. If cashGroup.maxMarketIndex becomes greater than Constants.MAX_TRADED_MARKET_INDEX then this contract becomes useless as getMarketIndex will always fail.
Kindly add below check to verify sanity of cashGroup.maxMarketIndex
require(cashGroup.maxMarketIndex<=Constants.MAX_TRADED_MARKET_INDEX, "CG: market index bound");
fCash is always computed in 8 decimals. However the underlying and asset tokens might be computed in higher decimal places. Since value will always be truncated to 8 decimal places, it might lead to loss of small dust funds which could accumulate over time with more mints over same token
Right now, there is no way to send this amount from contract to Admin. Consider having a function to sweep this values
DateTime.getMarketIndex function is called with Constants.MAX_TRADED_MARKET_INDEX as maxMarketIndex, however this is not correct. Notional might not be allowing all 7 market index for a particular currency in which case cashGroup.maxMarketIndex will be lesser than Constants.MAX_TRADED_MARKET_INDEX.
This means getMarketIndex will check for non required market indexes as well and may show incorrect maturity market index
Recommendation: Change function to
function getMarketIndex() public view override returns (uint8) { CashGroupSettings memory cashGroup = NotionalV2.getCashGroup(getCurrencyId()); (uint256 marketIndex, bool isIdiosyncratic) = DateTime.getMarketIndex( cashGroup.maxMarketIndex, getMaturity(), block.timestamp ); if (isIdiosyncratic) return 0; // Market index as defined does not overflow this conversion return uint8(marketIndex); }
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xSolus, 0xf15ers, 0xkatana, 0xmint, 8olidity, Chom, Cityscape, DavidGialdi, Deivitto, ElKu, Fitraldys, Funen, GreyArt, Lambda, Meera, Picodes, PierrickGT, Sm4rty, Tadashi, TerrierLover, TomJ, Tomio, UnusualTurtle, Waze, _Adam, antonttc, asutorufos, berndartmueller, c3phas, catchup, csanuragjain, delfin454000, djxploit, ellahi, fatherOfBlocks, hake, hansfriese, hyh, joestakey, kaden, minhquanym, oyc_109, rfa, sach1r0, saian, samruna, simon135, slywaters, ynnad
47.4309 USDC - $47.43
mintViaUnderlying function : if getMarketIndex() is 0 then there is no meaning in doing further processing and getting failed in called to Notional. This will be reverted as market is not tradeable at the moment. Better to have a check for this in beginning to prevent gas
require(getMarketIndex()!=0,"Non tradeable");
Function mintViaUnderlying: If depositAmountExternal is submitted as 0 then there is no meaning in going further and failing at Notional ( causing more high gas). Add a check to revert beforehand
require(depositAmountExternal!=0, "Incorrect amount");