Inverse Finance contest - Ruhum's results

Rethink the way you borrow.

General Information

Platform: Code4rena

Start Date: 25/10/2022

Pot Size: $50,000 USDC

Total HM: 18

Participants: 127

Period: 5 days

Judge: 0xean

Total Solo HM: 9

Id: 175

League: ETH

Inverse Finance

Findings Distribution

Researcher Performance

Rank: 8/127

Findings: 3

Award: $3,422.45

🌟 Selected for report: 1

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: Ruhum

Labels

bug
2 (Med Risk)
satisfactory
sponsor acknowledged
selected for report
M-07

Awards

3397.8465 USDC - $3,397.85

External Links

Lines of code

https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L124

Vulnerability details

Impact

The two-day feature of the oracle can be gamed where you only have to manipulate the oracle for ~2 blocks.

Proof of Concept

The oracle computes the day using:

uint day = block.timestamp / 1 days;

Since we're working with uint values here, the following is true: $1728799 / 86400 = 1$ $172800 / 86400 = 2$

Meaning, if you manipulate the oracle at the last block of day $X$, e.g. 23:59:50, and at the first block of day $X + 1$, e.g. 00:00:02, you bypass the two-day feature of the oracle. You only have to manipulate the oracle for two blocks.

This is quite hard to pull off. I'm also not sure whether there were any instances of Chainlink oracle manipulation before. But, since you designed this feature to prevent small timeframe oracle manipulation I think it's valid to point this out.

Tools Used

none

If you increase it to a three-day interval you can fix this issue. Then, the oracle has to be manipulated for at least 24 hours.

#0 - c4-sponsor

2022-11-15T14:51:00Z

08xmt marked the issue as sponsor acknowledged

#1 - 08xmt

2022-11-15T14:51:46Z

This is an issue if a 24 hour period elapse without any calls to the oracle and the underlying oracle is manipulable. The two day low is meant to be an added layer of security, but not bullet proof.

#2 - c4-judge

2022-11-28T19:35:26Z

0xean marked the issue as satisfactory

#3 - c4-judge

2022-12-01T15:58:36Z

0xean marked the issue as selected for report

Findings Information

Awards

24.2165 USDC - $24.22

Labels

bug
2 (Med Risk)
satisfactory
duplicate-533

External Links

Lines of code

https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L121

Vulnerability details

Impact

The oracle expects the token to have at most 18 decimals. But, there are tokens with more, e.g. 24. A prominent example is NEAR. It's in place 17 in Etherscan's ERC20 token ranking (by market cap)

The normalization logic will produce wrong results.

Proof of Concept

The price is normalized using:

            uint8 feedDecimals = feeds[token].feed.decimals();
            uint8 tokenDecimals = feeds[token].tokenDecimals;
            uint8 decimals = 36 - feedDecimals - tokenDecimals;
            uint normalizedPrice = price * (10 ** decimals);

With NEAR, you have the following result:

// using real chainlink feed data: https://etherscan.io/address/0xC12A6d1D827e23318266Ef16Ba6F397F2F91dA9b#readContract chainlink round ID = 18446744073709556379 answer = 306615587 ($3.07) normalizedPrice = 306615587 * (10 ** (36 - 24 - 8)) = 30661.5587

The price is scaled to 12 decimals instead of 18. The collateral's value will be lower than it should be and thus unusable.

Tools Used

none

You can scale the value to 18 decimals using

price * (10 ** (18 - feed.decimals()))

The token's own decimals can be ignored. Just scale the oracle's value to 18 decimals and you should be fine.

#0 - c4-judge

2022-11-04T23:41:58Z

0xean marked the issue as duplicate

#1 - c4-judge

2022-11-28T16:04:51Z

0xean marked the issue as not a duplicate

#2 - c4-judge

2022-11-28T16:05:00Z

0xean marked the issue as duplicate of #540

#3 - Simon-Busch

2022-12-05T15:33:38Z

Issue marked as satisfactory as requested by 0xean

#4 - c4-judge

2022-12-07T08:18:20Z

Simon-Busch marked the issue as duplicate of #533

Lines of code

https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L82

Vulnerability details

Impact

The Chainlink oracle latestAnswer() function is deprecated. Instead, you're supposed to use latestRoundData().

Using deprecated functions can result in the PriceOracleImplementation not returning the correct value anymore. It will affect the availability of that module.

Proof of Concept

Usage of latestAnswer(): https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L82

You can find the deprecation notice in the used contract itself: https://etherscan.io/address/0x986b5E1e1755e3C2440e960477f25201B0a8bbD4#code#L142

Tools Used

none

Use latestRoundData() and verify its return values properly, e.g. that the price was updated recently.

#0 - neumoxx

2022-10-31T08:46:22Z

Duplicate of #601

#1 - c4-judge

2022-11-05T17:50:24Z

0xean marked the issue as duplicate

#2 - Simon-Busch

2022-12-05T15:26:40Z

Issue marked as satisfactory as requested by 0xean

#3 - c4-judge

2022-12-07T08:14:13Z

Simon-Busch marked the issue as duplicate of #584

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