Abracadabra Mimswap - 0xAadi's results

General Information

Platform: Code4rena

Start Date: 07/03/2024

Pot Size: $63,000 USDC

Total HM: 20

Participants: 36

Period: 5 days

Judge: cccz

Total Solo HM: 11

Id: 349

League: BLAST

Abracadabra Money

Findings Distribution

Researcher Performance

Rank: 17/36

Findings: 1

Award: $377.05

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: 0xAadi

Also found by: 0x11singh99, bareli, hihen

Labels

bug
2 (Med Risk)
downgraded by judge
primary issue
satisfactory
selected for report
sponsor confirmed
sufficient quality report
:robot:_55_group
M-10

Awards

377.0529 USDC - $377.05

External Links

Lines of code

https://github.com/code-423n4/2024-03-abracadabra-money/blob/1f4693fdbf33e9ad28132643e2d6f7635834c6c6/src/oracles/aggregators/MagicLpAggregator.sol#L34

Vulnerability details

The MagicLpAggregator contract contains a flaw within the _getReserves function where it fails to return the reserve values fetched from the pair contract. This oversight results in the latestAnswer function always returning zero, which can have severe implications for any systems that depend on this contract for accurate liquidity pool pricing data.

Impact

The missing return statement in the _getReserves function leads to the latestAnswer function always returning zero. This affects any dependent systems or contracts that rely on accurate price data from the MagicLpAggregator contract, as they will receive incorrect information, potentially leading to financial loss or system failure.

Proof of Concept

The _getReserves function in the provided code snippet does not return the fetched reserves:

33:    function _getReserves() internal view virtual returns (uint256, uint256) {
34:        (uint256 baseReserve, uint256 quoteReserve) = pair.getReserves();
35:    }

https://github.com/code-423n4/2024-03-abracadabra-money/blob/1f4693fdbf33e9ad28132643e2d6f7635834c6c6/src/oracles/aggregators/MagicLpAggregator.sol#L33C5-L35C6

Due to the missing return statement, the latestAnswer function uses uninitialized variables for baseReserve and quoteReserve, which default to zero:

function latestAnswer() public view override returns (int256) {
    // ...
    (uint256 baseReserve, uint256 quoteReserve) = _getReserves();
    baseReserve = baseReserve * (10 ** (WAD - baseDecimals)); // baseReserve defaults to 0
    quoteReserve = quoteReserve * (10 ** (WAD - quoteDecimals)); // quoteReserve defaults to 0
    // ...
}

https://github.com/code-423n4/2024-03-abracadabra-money/blob/1f4693fdbf33e9ad28132643e2d6f7635834c6c6/src/oracles/aggregators/MagicLpAggregator.sol#L42C1-L44C69

Tools Used

Manual Review

Update _getReserves()

-    function _getReserves() internal view virtual returns (uint256, uint256) {
+    function _getReserves() internal view virtual returns (uint256 baseReserve, uint256 quoteReserve) {
-        (uint256 baseReserve, uint256 quoteReserve) = pair.getReserves();
+        (baseReserve, quoteReserve) = pair.getReserves();
     }

Assessed type

Other

#0 - 0xm3rlin

2024-03-15T00:56:04Z

confirmed

#1 - c4-pre-sort

2024-03-15T12:22:50Z

141345 marked the issue as primary issue

#2 - c4-pre-sort

2024-03-15T12:23:27Z

141345 marked the issue as sufficient quality report

#3 - 0xCalibur

2024-03-17T04:31:13Z

Fixed main branch, meanwhile this contest was happenning

https://github.com/Abracadabra-money/abracadabra-money-contracts

#4 - c4-sponsor

2024-03-17T04:31:16Z

0xCalibur (sponsor) confirmed

#5 - c4-judge

2024-03-29T13:37:07Z

thereksfour marked the issue as satisfactory

#6 - c4-judge

2024-03-31T06:48:00Z

thereksfour marked the issue as selected for report

#7 - c4-judge

2024-03-31T06:51:14Z

thereksfour changed the severity to 3 (High Risk)

#8 - trust1995

2024-04-02T14:00:22Z

Hi,

The impact is that oracle ALWAYS returns price = 0. I argue that this is in line with Medium severity (like 3/4 dups submitted it) because:

  • The ProxyOracle contract can always be updated to follow a fixed MagicLPAggregator
  • We have no usage of the price feed in the codebase so their verification of the price cannot be measured.
  • A price of 0 is considered invalid in Chainlink and most other feeds, the assumed behavior would be to revert. Admin can replace the feed at that time. Loss of funds seems very unlikely, it would have to be that the first time the issue is discovered it is when price of 0 is assumed legitimate and used to handle funds - is that in line with required likelihood for High?

@0xCalibur if you can weight in on any assumptions of integration with the Oracle setup it would be helpful.

#9 - 0xCalibur

2024-04-04T13:02:42Z

There was a mistake, not returning the value in _getReserves. We turned on "error on warnings" during compilation on Foundry config to avoid such issues in the future. This could have been avoided easily.

#10 - thereksfour

2024-04-05T11:12:56Z

This fact reduces the severity of this issue, will downgrade it to M

A price of 0 is considered invalid in Chainlink and most other feeds, the assumed behavior would be to revert. Admin can replace the feed at that time. Loss of funds seems very unlikely, it would have to be that the first time the issue is discovered it is when price of 0 is assumed legitimate and used to handle funds - is that in line with required likelihood for High?

#11 - c4-judge

2024-04-05T11:13:06Z

thereksfour changed the severity to 2 (Med Risk)

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