Thunder Loan

AI First Flight #7
Beginner FriendlyFoundryDeFiOracle
EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Oracle Dependency Without Validation

Root + Impact

Description

  • The `getPriceInWeth()` function relies on external TSwap pools to provide price data without any validation. If the oracle returns incorrect prices (zero, extremely high, or manipulated values), the fee calculations will be incorrect, potentially leading to loss of funds or denial of service.


    The oracle function doesn't validate return values:

    ```solidity

    function getPriceInWeth(address token) public view returns (uint256) {

    address swapPoolOfToken = IPoolFactory(s_poolFactory).getPool(token); // @> No validation if pool exists

    return ITSwapPool(swapPoolOfToken).getPriceOfOnePoolTokenInWeth(); // @> No validation of return value

    }

    ```

    This price is then used in fee calculations:

    ```solidity

    function getCalculatedFee(IERC20 token, uint256 amount) public view returns (uint256 fee) {

    //slither-disable-next-line divide-before-multiply

    uint256 valueOfBorrowedToken = (amount * getPriceInWeth(address(token))) / s_feePrecision; // @> Uses unvalidated price

    //slither-disable-next-line divide-before-multiply

    fee = (valueOfBorrowedToken * s_flashLoanFee) / s_feePrecision;

    }

    ```

    If the oracle returns:

    - Zero: Fee becomes zero, protocol loses revenue

    - Extremely high value: Fee becomes prohibitively high, breaking flash loans

    - Manipulated value: Attacker could manipulate fees

Risk

Likelihood:

  • * This occurs whenever `getCalculatedFee()` is called (on every deposit and flash loan)

    * If the TSwap pool is compromised, manipulated, or returns invalid data, the protocol is affected

    * No validation means any return value is accepted

Impact:

  • * Incorrect fee calculations leading to protocol revenue loss or user overpayment

    * Potential denial of service if fees become too high

    * Manipulation of fees through oracle manipulation

    * Could lead to economic attacks on the protocol

Proof of Concept

```solidity
// Scenario 1: Oracle returns 0
// 1. getPriceInWeth() returns 0
// 2. getCalculatedFee() calculates: valueOfBorrowedToken = (amount * 0) / 1e18 = 0
// 3. fee = (0 * s_flashLoanFee) / 1e18 = 0
// 4. Flash loan has zero fee - protocol loses revenue
// Scenario 2: Oracle returns extremely high value
// 1. getPriceInWeth() returns type(uint256).max
// 2. getCalculatedFee() tries to calculate: valueOfBorrowedToken = (amount * max) / 1e18
// 3. Potential overflow or extremely high fee
// 4. Flash loans become impossible or economically unviable
```

Recommended Mitigation

Add validation for oracle return values:
```diff
function getPriceInWeth(address token) public view returns (uint256) {
address swapPoolOfToken = IPoolFactory(s_poolFactory).getPool(token);
+ if (swapPoolOfToken == address(0)) {
+ revert OracleUpgradeable__PoolNotFound(token);
+ }
uint256 price = ITSwapPool(swapPoolOfToken).getPriceOfOnePoolTokenInWeth();
+ if (price == 0) {
+ revert OracleUpgradeable__InvalidPrice(price);
+ }
+ // Add reasonable bounds check (e.g., price should be between 1e12 and 1e24)
+ if (price < 1e12 || price > 1e24) {
+ revert OracleUpgradeable__PriceOutOfBounds(price);
+ }
return price;
}
```
Add the errors to the contract:
```diff
contract OracleUpgradeable is Initializable {
+ error OracleUpgradeable__PoolNotFound(address token);
+ error OracleUpgradeable__InvalidPrice(uint256 price);
+ error OracleUpgradeable__PriceOutOfBounds(uint256 price);
```
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 16 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!