# Malt Protocol Uses Stale Results From MaltDataLab Which Can Be Abused By Users

MaltDataLab's price/reserve averages are only refreshed by an EOA updater; stale values let users repeatedly call stabilize to farm 100 Malt auction incentives.

- Payout: Audit contest
- Severity: medium
- Program: Malt Finance
- Found by: leastwood
- Disclosed: 2022-02-14
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-11-malt-findings/issues/373
- Library page: https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AM-30
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:oracle-manipulation

**Target:** MaltDataLab MovingAverage oracle / StabilizerNode stabilize()
**Root cause:** MaltDataLab's trackMaltPrice/trackPool/trackPoolReserves are only pushed by an UPDATER_ROLE EOA, so protocol paths read stale averages; MovingAverage also uses spot samples rather than cumulative prices.
**Steps:**
1. Malt price exceeds lower bound so `stabilize` is callable by anyone and `_stabilityWindowOverride` passes.
2. `exchangeRate` reads `maltPriceAverage` which is stale because updater hasn't pushed.
3. `_startAuction` runs and pays `msg.sender` 100 Malt incentive.
4. Collude with a miner to censor `trackMaltPrice`/`trackPool` updates.
5. Repeat `stabilize` every `fastAveragePeriod` to keep collecting incentives while price stays stale.
**How found:** Code review of MaltDataLab integration: noticed sensitive values are only refreshed by an EOA via UPDATER_ROLE rather than inlined at use sites, and that MovingAverage is built from spot samples, making reads stale/manipulable.
**Exploitation:** Attacker colludes with a block producer to censor UPDATER_ROLE transactions to MaltDataLab, keeping averages stale, then repeatedly triggers stabilize() to collect the 100 Malt auction incentive each fastAveragePeriod; profitable as long as incentive exceeds updater gas cost.
**Escalation:** Also noted: well-funded actors or flashloans could sandwich trackMaltPrice/trackPool/trackPoolReserves calls to manipulate the spot-sample MovingAverage.
**Insight:** When an oracle/aggregator is refreshed by a privileged EOA rather than inlined at consumption points, enumerate every consumer and check whether a stale read still yields a payout or state transition an attacker can farm repeatedly.
