Platform: Code4rena
Start Date: 23/05/2022
Pot Size: $50,000 USDC
Total HM: 44
Participants: 99
Period: 5 days
Judge: hickuphh3
Total Solo HM: 11
Id: 129
League: ETH
Rank: 60/99
Findings: 3
Award: $84.77
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Ruhum
Also found by: 0x1f8b, 0x4non, 0xDjango, Dravee, GimelSec, StErMi, berndartmueller, blackscale, catchup, cccz, csanuragjain, defsec, eccentricexit, ellahi, horsefacts, hubble, joestakey, kenzo, pedroais, peritoflores, reassor, rotcivegaf, sashik_eth, shenwilly, sseefried, throttle, xiaoming90
1.8534 USDC - $1.85
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L310 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L279 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L274
Admin is allowed to make critical updates such as the Bath token fee, reserve ratio, time delay, etc. Such changes may effect user decisions, hence they should have some safeguards such as timelocks and/or limits. Even if there is no bad intention, this kind of excessive power given to the admin can potentially be used to damage the reputation of the protocol.
Manual review
#0 - bghughes
2022-06-03T21:10:55Z
Duplicate of #344
#1 - HickupHH3
2022-06-23T15:51:13Z
Generic issue about limits and timelock. Grouping it with #21.
🌟 Selected for report: IllIllI
Also found by: 0x1337, 0x1f8b, 0x4non, 0xDjango, 0xKitsune, 0xNazgul, 0xf15ers, ACai, AlleyCat, Bahurum, BouSalman, CertoraInc, Chom, Dravee, ElKu, FSchmoede, Funen, GimelSec, Hawkeye, JC, JMukesh, Kaiziron, MaratCerby, Metatron, PP1004, Picodes, Ruhum, SmartSek, StErMi, TerrierLover, UVvirus, UnusualTurtle, WatchPug, Waze, _Adam, asutorufos, berndartmueller, blackscale, blockdev, broccolirob, c3phas, catchup, cryptphi, csanuragjain, defsec, delfin454000, dipp, eccentricexit, ellahi, fatherOfBlocks, gzeon, hansfriese, horsefacts, hubble, ilan, joestakey, kebabsec, minhquanym, oyc_109, parashar, pauliax, rotcivegaf, sach1r0, sashik_eth, shenwilly, simon135, sorrynotsorry, sseefried, throttle, unforgiven, xiaoming90
52.0453 USDC - $52.05
setBathHouseAdmin() is called by the current admin to change the admin address. It can be a better approach to follow a 2-step process when updating such priviliged addresses First transaction proposes the pending admin address, second transaction which can only be called by the proposed address accepts the role.
It is a good practice to include non-zero address check especially when updating important addresses. I suggest to include non-zero address checks when setting addresses such as admin, strategist, fee recepient, etc.
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L253 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L264 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L327
Functions which are executed only by privileged users and change important parameters should emit events.
All the onlyAdmin functions in BathHouse.sol
Most of the contracts are using 0.7.6 compilers which are a bit outdated. It would be better to use a version >= 0.8.4 to benefit from new features such as builtin safemath operations and bugfixes.
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xf15ers, 0xkatana, Chom, DavidGialdi, Dravee, ElKu, FSchmoede, Fitraldys, Funen, GimelSec, JC, Kaiziron, MaratCerby, Metatron, MiloTruck, Picodes, Randyyy, RoiEvenHaim, SmartSek, Tomio, UnusualTurtle, WatchPug, Waze, _Adam, antonttc, asutorufos, berndartmueller, blackscale, blockdev, c3phas, catchup, csanuragjain, defsec, delfin454000, ellahi, fatherOfBlocks, gzeon, hansfriese, ilan, joestakey, minhquanym, oyc_109, pauliax, pedroais, reassor, rfa, rotcivegaf, sach1r0, samruna, sashik_eth, simon135, z3s
30.8734 USDC - $30.87
Some variables are initialised with their default values which cause unnecessary gas consumption
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L310 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L311 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L427 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L480 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L582 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathToken.sol#L635 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L82-L83 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L85 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L168 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L169 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L226 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L227 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L990
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L206 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L311 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L427 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L480 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L582 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathToken.sol#L635 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L436 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L1165 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L85 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L169 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconRouter.sol#L227
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L111 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L281 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L400 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L402 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L985 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L1002 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L1175
Error strings take space in the deployed bytecode. Every reason string takes at least 32 bytes so make sure your string fits in 32 bytes or it will become more expensive.
There are many instances, some of them are below: https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/proxy/Address.sol#L65 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/proxy/Address.sol#L147 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/proxy/Address.sol#L188 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/proxy/Address.sol#L224 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/peripheral_contracts/BathBuddy.sol#L45 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/peripheral_contracts/BathBuddy.sol#L96 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L145 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L149 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L162 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L177
If a state variable is going to be accessed multiple times in a function, it is better to cache it and use it from the stack. SLOAD costs ~100 gas, so 100 gas would be saved for each extra read. This is especially more important if the state variable is used within a loop, since there can be many extra reads there.
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L311 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathToken.sol#L635
It is cheaper to use calldata for the read-only arguments of external functions because then intermediate memory operations are avoided.
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L578 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L413-L417 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathPair.sol#L464-L469