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: 25/99
Findings: 4
Award: $455.59
π Selected for report: 0
π Solo Findings: 0
π Selected for report: berndartmueller
Also found by: 0x1f8b, 0xDjango, 0xsomeone, ACai, Bahurum, BouSalman, CertoraInc, Deivitto, Dravee, GimelSec, IllIllI, JMukesh, Kaiziron, PP1004, Ruhum, SmartSek, VAD37, WatchPug, _Adam, aez121, antonttc, blockdev, broccolirob, camden, cccz, cryptphi, defsec, dipp, ellahi, fatherOfBlocks, gzeon, horsefacts, ilan, jayjonah8, joestakey, kenta, kenzo, minhquanym, oyc_109, pauliax, pedroais, peritoflores, sashik_eth, shenwilly, simon135, throttle, xiaoming90, z3s
0.1022 USDC - $0.10
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathToken.sol#L605
Transfer function can succeed without an actual token transfer
BathToken can have an arbitrary ERC20 token as underlying. However, some tokens don't strictly follow ERC20 standard. For example, some tokens return bool confirmation during transfer(). Other tokens don't return and don't revert at all.
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathToken.sol#L605
Consider using safeTransfer()
and checking balance before and after.
#0 - bghughes
2022-06-07T22:36:18Z
Duplicate of #316
π 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/RubiconMarket.sol#L1231
Fee parameter is unbounded which can render unpredictable loss for users
There are no bound checks for fee parameter in RubiconMarket. It can go over 100%. https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L1231
Malicious admin could frontrun fee parameter change in a way that a user would lose all it's token funds (well over 100% of what is inside the pool)
Set meaningful bounds for tax parameter. Add timelock.
#0 - bghughes
2022-06-04T20:32:25Z
Duplicate of #125
#1 - HickupHH3
2022-06-18T04:38:11Z
Duplicate of #21
π Selected for report: xiaoming90
Also found by: throttle
401.6035 USDC - $401.60
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L655-L675 https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L612-624
Main Orderbook invariant is broken. User can post crossed order without it being filled.
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L612-624
User can call function offer(uint256 pay_amt, ERC20 pay_gem, uint256 buy_amt, ERC20 buy_gem)
and
accidentally post an order which crosses the orderbook (buy order (sell) well above (below) market price).
In correctly implemented orderbook, such order would match against offers from orderbook. Here is no such case.
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/RubiconMarket.sol#L655-L675
Theoretically keepers should put an order into orderbook but actually an arbitrage bot could call buy()
and match that order at unfair price and then sell it. Zero risk profit.
This is high because user can lose funds and the offer()
function is very natural to be called by users. There is no docs instructing users not to call this function.
Make sure the main orderbook invariant holds.
#0 - bghughes
2022-06-04T20:27:24Z
I believe this argument is the same as #110
#1 - HickupHH3
2022-06-22T16:14:34Z
Yeap, duplicate of #110. The case for loss of funds is gray; a user putting up an offer that is worse than the market rate would be under the classification of "user-error" bugs that typically see a medium severity.
π 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.0353 USDC - $52.04
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L106
Centralization risk - admin has too much control over protocol.
The protocol defines an admin role, which can update almost any parameter in the protocol. Admin is not behind a multisig and changes are not behind a timelock. Even if protocol admins/developers are not malicious there is still a chance for admin keys to be stolen. In such case, an attacker could steal all the user's funds and kill the protocol.
https://github.com/code-423n4/2022-05-rubicon/blob/main/contracts/rubiconPools/BathHouse.sol#L106
Try to redesign the protocol to be less centralized. Add support for multisig and timelock.
#0 - bghughes
2022-06-03T20:15:18Z
Company centralization is an acknowledged risk in the system in v1. See the future works section of our white paper ;)
#1 - HickupHH3
2022-06-15T14:44:35Z
It's great that wardens raise up rugpull vector concerns so that the sponsor is at least aware of it. I've deliberated much over how to best group these issues regarding centralization and owner privilege risks, and would like to explain my rationale and thought process.
A precedent has been set from a previous contest finding where all issues were grouped together. Meanwhile, some wardens have pointed to the Insure contest where multiple high severity findings stem from the fact that a compromised owner is able to rug user funds through various means.
In this case, we have 2 groups of privileged access controls: the admin and the strategist(s). As it stands currently, the team is the sole strategist (stated in the future works section of the whitepaper), keeping the risk level the same as the admin. Different wardens have showcased how the admin and strategist is able to cause the loss of funds in multiple ways.
The README stated that "BathHouse has an admin that is the EOA administrator of the entire protocol in v1.", which in my opinion, favours the wardens' POV of the likelihood of rugpulling should the wallet be compromised. It is unclear if the admin and strategist shares the same EOA. In practice, I hope that they aren't.
I note that the strategists can potentially be increased in size, so the likelihood and risk of a malicious attack is greater in that regard.
On the other hand, the README stated the following:
Note that the Bath Token looks to both the Bath House (via onlyBathHouse) and the Bath Pair/strategists (via onlyPair) as permissioned actors. The Bath House admins key storage variables while strategists access funds and manage liquidity positions
The (weak) implication is that there is an acceptable trust assumption we can make about the admin and strategist(s). I am therefore in favour of keeping the medium severity rating for the issues raised.
The issues raised about rugpull vulnerabilities via centralisation risks can be broadly classified into 2 categories:
While the premise is the same (assume strategist / admin is compromised), there is a spectrum in the write-up quality of issues. Some are generic in nature and are of low value, while others have written POCs and explained the potential impact in great detail.
It would be ideal and fair to reward wardens who provide meaningful context and details more than those who don't. Hence, in this regard, it makes sense to split up the issues based on the various attack vectors described by different ones.
Yet, there may be those who did spot these rugpull vulnerabilities, but chose not to mention them because of the privileged access and assumed that the risk was acceptable. I would like to encourage those who fall in this category (me being 1 of them :p) to raise these issues nonetheless, unless explicitly told otherwise / stated in the README that it is a trust assumption by the protocol / out of scope. Better to have your issue looked at and invalidated than not at all!
Category 1 can be separated into the various attack vectors and actors (admin / strategist), as the mitigation is more tangible in nature. This way, the recommended fixes can also be easily identified and adopted. A warden that grouped multiple attack vectors together will have their issue made the primary issue; the rest will be marked as duplicates of it. Examples: #249 and #157
Regarding category 2, for issues that are generic "put admin under timelock" without explaining how and why a compromised owner / strategist can rug, as per the rulebook ruling and judges' general consensus, I will downgrade their severity to QA. Those that explained the impact and vulnerability in detail will be grouped together with medium severity because there isn't much that can be done about it.
#2 - HickupHH3
2022-06-17T15:44:47Z
This issue falls under cat 2 - generic timelock recommendation. Downgrading to QA