Badger Citadel contest - shenwilly's results

Bringing BTC to DeFi

General Information

Platform: Code4rena

Start Date: 14/04/2022

Pot Size: $75,000 USDC

Total HM: 8

Participants: 72

Period: 7 days

Judge: Jack the Pug

Total Solo HM: 2

Id: 110

League: ETH

BadgerDAO

Findings Distribution

Researcher Performance

Rank: 16/72

Findings: 3

Award: $1,178.76

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Ruhum

Also found by: TrungOre, VAD37, cccz, danb, gs8nrv, kyliek, minhquanym, rayn, shenwilly, wuwe1

Labels

bug
duplicate
3 (High Risk)
sponsor confirmed

Awards

896.081 USDC - $896.08

External Links

Lines of code

https://github.com/code-423n4/2022-04-badger-citadel/blob/18f8c392b6fc303fe95602eba6303725023e53da/src/StakedCitadel.sol#L291-L295

Vulnerability details

Impact

Calling balance only returns the balance of underlying token in StakedCitadel, while it should also includes tokens deposited in the strategy. As balance is heavily used within the contract, this wrong value will cause a lot of problems.

In particular, withdrawal uses balance to calculate the amount of token to withdraw per share. If a user tries to withdraw when tokens are deposited in the strategy, they will receive less amount than they should actually get.

Include the token balance of strategy in balance().

#0 - jack-the-pug

2022-05-30T06:52:57Z

Dup #74

Findings Information

🌟 Selected for report: Ruhum

Also found by: 0xBug, 0xDjango, IllIllI, MaratCerby, TrungOre, danb, hyh, m9800, minhquanym, pedroais, remora, shenwilly

Labels

bug
duplicate
2 (Med Risk)
sponsor confirmed

Awards

184.248 USDC - $184.25

External Links

Lines of code

https://github.com/code-423n4/2022-04-badger-citadel/blob/18f8c392b6fc303fe95602eba6303725023e53da/src/Funding.sol#L202-L216 https://github.com/code-423n4/2022-04-badger-citadel/blob/18f8c392b6fc303fe95602eba6303725023e53da/src/Funding.sol#L177

Vulnerability details

Impact

When funding.discount is set to 0, calling getAmountOut will always return 0 instead of the actual amount without discount. As a result, users calling deposit will receive 0 xCitadel, essentially losing their funds. This is particularly dangerous as the contract is initialized with discount value of 0.

Proof of Concept

citadelAmount_ is not assigned value when funding.discount is 0.

Modify L207-2013 to:

citadelAmount_ = _assetAmountIn * citadelPriceInAsset; if (funding.discount > 0) { citadelAmount_ = (citadelAmount_ * MAX_BPS) / (MAX_BPS - funding.discount); }

or alternatively, add a new conditional statement for funding.discount == 0.

#0 - jack-the-pug

2022-05-29T07:11:24Z

Dup #149

Low Risk Vulnerabilities

1. Missing zero address check on strategist

While StakedCitadel.initialize has a zero-address check on strategist, there is no such check in SettAccessControl.setStrategist it inherits. Strategist being set to zero address would cause StakedCitadel.reportAdditionalToken to revert.

Mitigation

Add zero address check in setStrategist.

2. Dangerous governance update

Passing a wrong address to SettAccessControl.setGovernance would mean losing access to governance functions, and would require a contract redeployment to fix.

Mitigation

Use two-step process (set pending governance and accepting the governance) for setting new governance address.

3. Unused variable and comment mismatch: transferFromDisabled

GlobalAccessControl.transferFromDisabled is not used anywhere. The comment stated that it should be set to true in initialize, but there is no such statement in the initialize function.

Mitigation

Remove if unused or implement it according to the specification.

4. Comment mismatch: deposit

Funding.deposit comment mistakenly defines _minCitadelOut param as "ID of DAO to vote for".

Mitigation

Change the comment to "the minimal amount of citadel token to receive".

5. Missing checks for min <= max

Some functions are missing require statement that checks whether min param is lower/equal than max param:

  • setDiscountLimits, setting _minDiscount higher than _maxDiscount would make setDiscount to always revert.
  • setCitadelAssetPriceBounds, setting _minPrice higher than _maxPrice would cause citadelPriceFlag to always be set to true whenever updateCitadelPriceInAsset is called.
Mitigation

Add the comparison checks.

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