Platform: Code4rena
Start Date: 01/07/2022
Pot Size: $75,000 USDC
Total HM: 17
Participants: 105
Period: 7 days
Judge: Jack the Pug
Total Solo HM: 5
Id: 143
League: ETH
Rank: 7/105
Findings: 5
Award: $3,510.91
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: 0xNineDec
Also found by: 0x1f8b, 0x29A, 0x52, 0xDjango, 0xdanial, 0xf15ers, Cheeezzyyyy, Chom, Franfran, GalloDaSballo, Green, IllIllI, Meera, Ruhum, bardamu, cccz, codexploder, defsec, hake, hansfriese, horsefacts, hubble, hyh, jonatascm, kebabsec, oyc_109, pashov, rbserver, simon135, tabish, tintin, zzzitron
14.8726 USDC - $14.87
Incorrect of stale oracle results
Change from this: (, int256 _price, , , ) = feed.latestRoundData()
To this: (uint80 roundID, int256 _price, , uint256 timestamp, uint80 answeredInRound) = _feed.latestRoundData(); require(answeredInRound >= roundID, "Stale price"); require(timestamp != 0,"Round not complete"); require(answer > 0,"Chainlink answer reporting 0");
#0 - mejango
2022-07-12T18:24:32Z
dup of #138
🌟 Selected for report: horsefacts
Also found by: 0x1f8b, 0x29A, 0x52, 0xf15ers, AlleyCat, Ch_301, Chom, Franfran, IllIllI, Kaiziron, Limbooo, Meera, Ruhum, Sm4rty, apostle0x01, berndartmueller, cccz, cloudjunky, codexploder, cryptphi, delfin454000, durianSausage, fatherOfBlocks, hake, hansfriese, hyh, jonatascm, m_Rassska, oyc_109, peritoflores, rajatbeladiya, rbserver, svskaushik, zzzitron
3.4075 USDC - $3.41
Some ERC20 tokens don't revert when a transfer fails. In such cases transfer and transferFrom are not reliable to judge if tokens are actually transferred
Implement OZ's safeERC20 and used safeTransfer and safeTransferFrom for ERC20 transfers
#0 - mejango
2022-07-12T18:29:39Z
dup of #281
🌟 Selected for report: berndartmueller
781.4991 USDC - $781.50
When feeDiscount isn't 0 or JBConstants.MAX_FEE_DISCOUNT, the fee calculation will be wrong. It always errors to the underside i.e. takes less fees than it should but the discount is not working as intended for the conditions stated.
Incorrect fee
Constants: JBConstants.MAX_FEE_DISCOUNT = 1E9 JBConstants.MAX_FEE = 1E9
Assumptions: _amount = 1E18 _fee = 2.5E7 (standard fee for a terminal) _feeDiscount = 5E8 (50% discount)
_discountedFee = 2.5E7 - (2.5E7*5E8/1E9) = 1.25E7
1E18 - 1E18*1E9/(1.25E7+1E9) = 0.0123E18
0.0123E18 / 1E18 = 1.23% fee
The expected fee would be 1.25% (50% of 2.5%)
Change L1457-1458 to:
return _amount - PRBMath.mulDiv(_amount, JBConstants.MAX_FEE - discountedFee, JBConstants.MAX_FEE);
#0 - mejango
2022-07-12T19:45:44Z
_amount in this case is pre-fee. So an amount of 110 with a 10% fee should result in a fee of 10. 110 - (110 * 1/ 1.1) = 10.
dup of #270
Fees will be permanently stuck
Each time a fee is taken, a new entry is pushed to _heldFeesOf[_projectID] in L1199 of takeFeeFrom
processFees requires that all outstanding fees be processed in a single transaction. If fees go too long before being collected then this could potentially lead to an array that is too large to process, because _heldFeesOf[_projectID] has no limit in size.
When storing fees, compare the the fee, feeDiscount and beneficiary of the most recent entry. If all three match (i.e. the fee, feeDiscount and beneficiary haven't changed since last fee collection) then add _amount to the amount of last entry instead of pushing a new one.
#0 - mejango
2022-07-12T20:19:14Z
dupe #8
🌟 Selected for report: 0x52
Also found by: DimitarDimitrov
1929.6275 USDC - $1,929.63
Potentially inconsistent currency conversions
addFeedFor requires that a price feed for the _currency _base doesn't exist when adding a new price feed but doesn't check if the inverse already exists. This means that two different oracles (potentially with different prices) could be used for _currency -> _base vs. _base -> _currency. Different prices would lead to inconsistent between conversion ratios depending on the direction of the conversion
Change L115 to: if (feedFor[_currency][_base] != IJBPriceFeed(address(0)) || feedFor[_base][_currency] != IJBPriceFeed(address(0))) revert PRICE_FEED_ALREADY_EXISTS()