Platform: Code4rena
Start Date: 04/05/2022
Pot Size: $50,000 DAI
Total HM: 24
Participants: 71
Period: 5 days
Judge: Justin Goro
Total Solo HM: 14
Id: 119
League: ETH
Rank: 52/71
Findings: 3
Award: $96.90
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: MaratCerby
Also found by: CertoraInc, Ruhum, VAD37, berndartmueller, broccolirob, cryptphi, danb, gzeon, horsefacts, hyh, joestakey, leastwood, pedroais, peritoflores, throttle, wuwe1, z3s
19.1789 DAI - $19.18
Hardcode 1e18 for all rewards token can cause addPool
issue with rewards/reposit token like WBTC (8 decimals) or USDC (6 decimals).
The underlying function getMaximumRewards
will return 0 or smaller rewards than expected due to precision lost.
Normally this would not be a problem because maximumDepositWei
or rewardsWeiPerSecondPerToken
will be token with 18 decimals large enough to handle hardcode 1e18 division.
But if user want user to deposit WBTC and rewards both USDC and promoted token (either with 18 decimals or not), then this issue will occur. (Yield reward per second for USDC is really high but received rewards is 0)
Unexpected contract behaviour + Hypothetical scam = Medium severity.
rewardsWeiPerSecondPerToken
= 1e12 / 2e6 ~= 5e5.fundPool
call. MyToken have no problem, but getMaximumRewards
for USDC will be calculated as
5e5 * 1e9 * 2e6 / 1e18 = 1e21 / 1e18 = 1000 = 0.001 USDC
.The scam use case for this pretty much inflated price for meme/DAO token. Since no USDC is rewarded, the scammer only have to mint their token to give out. Little expense, free exposure. No user lost their WBTC.
The easiest way is replacing hardcode / 1e18
with depositToken.decimals()
.
Note: still not handle meme token case like there is only 1 token
with only 1e18 in circulation.
This is up to user to handle.
#0 - illuzen
2022-05-12T05:11:21Z
Duplicate #47
#1 - itsmetechjay
2022-05-12T19:06:13Z
Re-closing as duplicate.
🌟 Selected for report: MaratCerby
Also found by: 0x1337, 0x52, 0xYamiDancho, AuditsAreUS, CertoraInc, Dravee, GimelSec, IllIllI, PPrieditis, Ruhum, TrungOre, VAD37, berndartmueller, cccz, csanuragjain, defsec, hickuphh3, horsefacts, hyh, jayjonah8, kenzo, leastwood, mtz, p4st13r4, reassor, throttle, wuwe1, ych18
3.1753 DAI - $3.18
https://github.com/code-423n4/2022-05-factorydao/blob/main/contracts/PermissionlessBasicPoolFactory.sol#L180-L202 https://github.com/code-423n4/2022-05-factorydao/blob/main/contracts/PermissionlessBasicPoolFactory.sol#L230
Fee on transfer can DoS the withdrawals
Pools creation is permissionless. Anyone can propose a pool with any ERC20 token. However, some tokens don't strictly follow ERC20 standard. For example, some tokens implement fee on transfer. In such case, the withdrawal could be DOSed
deposit()
function will account for more than the actual transferred.
https://github.com/code-423n4/2022-05-factorydao/blob/main/contracts/PermissionlessBasicPoolFactory.sol#L180-L202
https://github.com/code-423n4/2022-05-factorydao/blob/main/contracts/PermissionlessBasicPoolFactory.sol#L230
transfer()
in withdraw()
function might revert if there is no enough funds.
Thus users will not be able to retrieve invested funds.
And pool owners might not be able to withdraw (potentially huge amounts) excess rewards.
Manual review
Consider accounting for fee-on-transfer during deposit and withdrawal
#0 - illuzen
2022-05-12T05:12:07Z
Duplicate #34
#1 - gititGoro
2022-06-14T02:06:34Z
Changing severity due pool isolation, rewards tokens represent leakage not lost funds and because transfer of deposited funds would fail on deposit.
🌟 Selected for report: horsefacts
Also found by: 0x1f8b, 0xYamiDancho, 0xf15ers, 0xkatana, ACai, AlleyCat, Bruhhh, Dravee, Funen, GimelSec, Hawkeye, IllIllI, MaratCerby, PPrieditis, Picodes, Ruhum, TerrierLover, VAD37, berndartmueller, csanuragjain, defsec, delfin454000, eccentricexit, ellahi, fatherOfBlocks, gzeon, hansfriese, hickuphh3, hyh, ilan, joestakey, juicy, kebabsec, oyc_109, rajatbeladiya, reassor, rfa, robee, samruna, simon135, sorrynotsorry, throttle
74.5412 DAI - $74.54
In few places there are addresses with roles assigned. It's better to reuse battle-tested code. It also improves readability
https://github.com/code-423n4/2022-05-factorydao/blob/main/contracts/MerkleIdentity.sol#L53 https://github.com/code-423n4/2022-05-factorydao/blob/main/contracts/PermissionlessBasicPoolFactory.sol#L76
Consider using OZ library
#0 - illuzen
2022-05-12T08:47:37Z
no thank you, I don't like subclassing
#1 - gititGoro
2022-06-12T02:48:49Z
The openzeppeling roles code is a bit too opinionated to be considered a strong recommendation.