Hubble contest - cmichel's results

Multi-collateral/Cross-Margin Perpetual Futures on Avalanche.

General Information

Platform: Code4rena

Start Date: 17/02/2022

Pot Size: $75,000 USDC

Total HM: 20

Participants: 39

Period: 7 days

Judges: moose-code, JasoonS

Total Solo HM: 13

Id: 89

League: ETH

Hubble

Findings Distribution

Researcher Performance

Rank: 2/39

Findings: 4

Award: $7,480.73

🌟 Selected for report: 2

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: danb

Also found by: Meta0xNull, Ruhum, cmichel, csanuragjain, hyh, kirk-baird, leastwood, minhquanym, robee, throttle

Labels

bug
duplicate
3 (High Risk)

Awards

242.812 USDC - $242.81

External Links

Lines of code

https://github.com/code-423n4/2022-02-hubble/blob/8c157f519bc32e552f8cc832ecc75dc381faa91e/contracts/VUSD.sol#L50-L57

Vulnerability details

Impact

The VUSD.processWithdrawals function only performs maxWithdrawalProcesses (actually maxWithdrawalProcesses + 1) iterations per call. Withdrawals can be freely spammed by a griefer calling burn(amount) with a zero amount. All future withdrawals are blocked until someone calls processWithdrawals to iterate through all the spam withdrawals.

Add a minimum withdrawal amount in withdraw to increase the cost of the attack and make it infeasible.

#0 - atvanguard

2022-02-24T08:05:13Z

Duplicate of #119

Findings Information

🌟 Selected for report: cmichel

Also found by: danb

Labels

bug
3 (High Risk)

Awards

4178.2677 USDC - $4,178.27

External Links

Lines of code

https://github.com/code-423n4/2022-02-hubble/blob/8c157f519bc32e552f8cc832ecc75dc381faa91e/contracts/InsuranceFund.sol#L44-L54

Vulnerability details

Impact

The InsuranceFund.deposit function mints initial shares equal to the deposited amount. The deposit / withdraw functions also use the VUSD contract balance for the shares computation. (balance() = vusd.balanceOf(address(this)))

It's possible to increase the share price to very high amounts and price out smaller depositors.

POC
  • deposit(_amount = 1): Deposit the smallest unit of VUSD as the first depositor. Mint 1 share and set the total supply and VUSD balance to 1.
  • Perform a direct transfer of 1000.0 VUSD to the InsuranceFund. The balance() is now 1000e6 + 1
  • Doing any deposits of less than 1000.0 VUSD will mint zero shares: shares = _amount * _totalSupply / _pool = 1000e6 * 1 / (1000e6 + 1) = 0.
  • The attacker can call withdraw(1) to burn their single share and receive the entire pool balance, making a profit. (balance() * _shares / totalSupply() = balance())

I give this a high severity as the same concept can be used to always steal the initial insurance fund deposit by frontrunning it and doing the above-mentioned steps, just sending the frontrunned deposit amount to the contract instead of the fixed 1000.0. They can then even repeat the steps to always frontrun and steal any deposits.

The way UniswapV2 prevents this is by requiring a minimum deposit amount and sending 1000 initial shares to the zero address to make this attack more expensive. The same mitigation can be done here.

#0 - atvanguard

2022-02-24T05:26:48Z

Duplicate of #116

Findings Information

🌟 Selected for report: bw

Also found by: Ruhum, cmichel, gzeon

Labels

bug
duplicate
2 (Med Risk)

Awards

274.1361 USDC - $274.14

External Links

Lines of code

https://github.com/code-423n4/2022-02-hubble/blob/8c157f519bc32e552f8cc832ecc75dc381faa91e/contracts/ClearingHouse.sol#L122

Vulnerability details

Impact

The ClearingHouse.updatePositions function iterates over all amms. There is no limit to the number of AMMs that can be added in ClearingHouse.whitelistAmm.

The transactions can fail if the arrays get too big and the transaction would consume more gas than the block limit. This will then result in a denial of service for the desired functionality and break core functionality. It also leads to a higher gas cost.

A similar issue was recently marked as medium severity.

It would be best to set a sanity maximum number of AMMs/ that can be added.

#0 - atvanguard

2022-02-24T08:06:27Z

Duplicate of #97

Findings Information

🌟 Selected for report: cmichel

Labels

bug
2 (Med Risk)
disagree with severity
sponsor confirmed

Awards

2785.5118 USDC - $2,785.51

External Links

Lines of code

https://github.com/code-423n4/2022-02-hubble/blob/8c157f519bc32e552f8cc832ecc75dc381faa91e/contracts/Oracle.sol#L34

Vulnerability details

Impact

The Oracle.getUnderlyingPrice function divides the chainlink price by 100. It probably assumes that the answer for the underlying is in 8 decimals but then wants to reduce it for 6 decimals to match USDC.

However, arbitrary underlying tokens are used and the chainlink oracles can have different decimals.

While most USD price feeds use 8 decimals, it's better to take the on-chain reported decimals into account by doing AggregatorV3Interface(chainLinkAggregatorMap[underlying]).decimals(), see Chainlink docs. The price should then be scaled down to 6 decimals.

#0 - atvanguard

2022-02-24T05:36:19Z

All chainlink USD pairings are expected to have 8 decimals hence disagreeing with severity; but yes agree that asserting this check when adding a new asset is a good idea.

#1 - moose-code

2022-03-06T14:51:49Z

Downgrading to medium. Dividing by magic numbers (100) should clearly comment assumptions

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter