# Stale Prices

{% hint style="info" %}
[**Book an audit with Zokyo**](https://www.zokyo.io/)
{% endhint %}

## .latestRoundData() does not update the oracle - ExchangeRate.sol

#### Vulnerability Details

**Impact**

The function `.latestRoundData()` employed on an oracle retrieves the most recently updated price. However, it's crucial to understand that this retrieved price isn't necessarily reflective of the asset's current market value. To obtain an accurate and real-time price, it’s imperative to actively query the oracle and then patiently await a callback to complete the request, thereby confirming the data’s receipt and accuracy.

Failure to procure precise, real-time data can lead to immediate and substantial financial losses. Consider a scenario wherein an asset's market price experiences a 5% decline, but the oracle’s data remains stagnant, not reflecting this change. In this instance, a user might deposit funds and inadvertently receive a 5% credit due to the oracle’s outdated data. Once `.latestRoundData()` is eventually updated (either organically or through user initiation), reflecting the accurate asset price, the user might proceed to withdraw the funds in the original asset form, effectively gaining an unwarranted 5% windfall.

**Proof of Concept**

The vulnerability is illustrated within the code at the following link: [ExchangeRate.sol Code](https://github.com/code-423n4/2021-08-notional/blob/4b51b0de2b448e4d36809781c097c7bc373312e9/contracts/internal/valuation/ExchangeRate.sol#L84)

**Recommended Mitigation Steps**

To remedy and prevent the outlined financial risks and inaccuracies:

* **Avoid Relying Solely on `.latestRoundData()`:** Refrain from solely depending on the `.latestRoundData()` for fetching the latest asset prices as this approach doesn't guarantee real-time accuracy.
* **Active Oracle Query:** Initiate an active query to the oracle to request updated asset prices.
* **Await Callback Confirmation:** After initiating the query, it’s vital to await a callback, which serves as a confirmation that the request is fulfilled, ensuring you receive and work with the most accurate and current price data available.

Implementing these steps ensures that your contract relies on accurate, up-to-date data, effectively safeguarding against potential losses stemming from outdated or inaccurate oracle price feeds.

## [WrappedIbbtcEth contract will use stalled price for mint/burn if updatePricePerShare wasn't run properly](https://github.com/code-423n4/2021-10-badgerdao-findings/issues/86)

#### Vulnerability Details

**Impact**

A malicious user could exploit stale `pricePerShare` data to secure risk-free profits at the contract's expense. If the `SetPricePerShare` event hasn't been triggered recently, and the market has shifted, the contract's `pricePerShare` might be outdated. An exploitative user can leverage this by executing `mint()` at the outdated `pricePerShare`, waiting for the price to update, and then executing `burn()` at the refreshed rate.

**Proof of Concept**

The contract's `pricePerShare` variable is updated via the `updatePricePerShare` function but is used in `mint/burn/transfer` functions without verification of its timeliness. This vulnerability is exploitable when the external `updatePricePerShare` function stalls for any reason.

* [`balanceToShares` Function](https://github.com/code-423n4/2021-10-badgerdao/blob/main/contracts/WrappedIbbtcEth.sol#L155)
* [`updatePricePerShare` Function](https://github.com/code-423n4/2021-10-badgerdao/blob/main/contracts/WrappedIbbtcEth.sol#L72)

The risk arises if there's a failure in the system's off-chain script which updates the price, leading to a price stall in the contract. Failures could occur due to internal bugs or external factors like network outages or systemic dependencies.

**Recommended Mitigation Steps**

The core issue stems from the system design. While wrapping price updates at the contract level minimizes gas costs, it introduces risk if not paired with appropriate safeguard mechanisms. Implement the following to reduce risk:

1. **Introduce a Time Threshold:** Add a variable representing the maximum allowable time since the last `pricePerShare` update.
2. **Create Two Transfer Function Variants:** Each should check the condition `{now - time since last price update < threshold}`. If the condition is met, both variants execute the transfer. If not, the first variant should revert, while the second should trigger a price update.
   * The first variant is a “light” transfer function that operates at low cost but requires recent pricing.
   * The second variant, or “full” transfer function, behaves like the first but also updates pricing when necessary. Although usually operating at low cost, it requires more gas when executing a price update due to stalled pricing.

With these changes, if the scheduled price update fails (due to network conditions, for example), the financial risk is limited to market volatility during the threshold time, effectively capping the potential loss.

## Malt Protocol Uses Stale Results From `MaltDataLab` Which Can Be Abused By Users&#x20;

#### Impact Overview

MaltDataLab incorporates multiple MovingAverage contracts to retrieve critical data integral to the functionality of the Malt protocol, including real LP token values, average Malt prices, and average reserve ratios. Data updating functions - `trackMaltPrice`, `trackPoolReserves`, and `trackPool` - are exclusively called by an account with the UPDATER\_ROLE, which is an Externally Owned Account (EOA) rather than a contract.

#### Vulnerability Insight

The continuous and accurate updating of these functions is crucial for providing current values, creating a dependency on the designated EOA to perform regular updates. However, this process is susceptible to miner interference. Miners have the capability to censor calls to MaltDataLab, which could lead to the utilization of outdated values in various protocol areas, creating an opportunity for value extraction.

#### Proof of Concept

Consider a potential attack scenario:

1. The Malt price rises above the lower bound threshold, allowing any user to invoke the `stabilize` function.
2. The `_stabilityWindowOverride` function conditions are met, executing the function.
3. The `exchangeRate` state variable calls `maltPriceAverage` but may utilize an outdated exchange rate due to lack of updates.
4. The `_startAuction` function activates, rewarding the `msg.sender` with 100 Malt as an incentive for initiating an auction.
5. Without subsequent price updates, malicious actors could collaborate with miners to prevent further pool updates and repeatedly call `stabilize` during every `fastAveragePeriod` interval, extracting incentive payments in the process.
6. If these incentive payments surpass the amount the UPDATER\_ROLE is willing to expend for calling `trackMaltPrice`, sustained attacks of this nature become feasible, posing a serious threat to the protocol's stability.

#### Additional Concerns

The reliance of MaltDataLab on spot price data points for calculating the Moving Average also warrants attention. Well-capitalized malicious actors could potentially manipulate the MovingAverage contract. This could be achieved by strategically placing calls to `trackMaltPrice`, `trackPool`, and `trackPoolReserves` in between other transactions, further compounding the vulnerability.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zokyo-auditing-tutorials.gitbook.io/zokyo-tutorials/tutorial-17-dexs-decentralized-exchanges/common-vulnerabilities-in-dex-code/vulnerabilities-in-oracle-implementations/stale-prices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
