Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Lack of Oracle staleness check can cause over-borrowing and unfair liquidations

未关闭
#794 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
30/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
solidity

调研方向

从 Auditor.assetPrice 和 IPriceFeed 接口开始,然后追踪返回值如何传递到 accountLiquidity、checkBorrow、checkLiquidation 和 calculateSeize。定义 feed 的新鲜度要求和每个 feed 的配置,然后通过有针对性的测试验证过期值不能支持借款或清算决策。

由索引模型根据 Issue 内容生成。

描述

Summary

Auditor.assetPrice() trusts IPriceFeed.latestAnswer() and only checks price > 0. But it does not verify that the oracle value is fresh (no timestamp/round/heartbeat validation).

During a real world Chainlink stalls (sequencer downtime, feed pauses/delays, node issues), latestAnswer() commonly returns the last valid price without reverting, which this protocol will treat as current.

  • This can enable two issues in this contracts:

  • (1) over-borrow using stale-high collateral prices (bad debt / lender loss)

  • (2) liquidations using stale-low collateral prices (steal from users).

Root cause

  • Auditor.assetPrice():
function assetPrice(IPriceFeed priceFeed) public view returns (uint256) {
  if (address(priceFeed) == BASE_FEED) return basePrice;

  int256 price = priceFeed.latestAnswer();
  if (price <= 0) revert InvalidPrice();
  return uint256(price) * baseFactor;
}
  • No updatedAt, no heartbeat, no answeredInRound checks (the IPriceFeed interface only exposes latestAnswer()/decimals()).

If you notice this price is used throughout critical logic, e.g. collateral/debt valuation:

vars.price = assetPrice(m.priceFeed);
sumCollateral += vars.balance.mulDivDown(vars.price, baseUnit).mulWadDown(adjustFactor);
sumDebtPlusEffects += vars.borrowBalance.mulDivUp(vars.price, baseUnit).divWadUp(adjustFactor);
  • and borrow eligibility:
(uint256 collateral, uint256 debt) = accountLiquidity(borrower, Market(address(0)), 0);
if (collateral < debt) revert InsufficientAccountLiquidity();
  • Liquidation math also depends on assetPrice() (e.g. checkLiquidation, calculateSeize).

Impact

  1. Over-borrow with stale-high collateral price → protocol/lenders eat bad debt

Condition and likelihood: collateral oracle is stale at an old higher price during a drop (common during L2 sequencer incidents or oracle delays).

Flow:

  • Attacker deposits collateral and enters market.
  • Calls Market.borrow(...).
  • Auditor.checkBorrow() → accountLiquidity() uses the stale high price, inflating collateral value → borrow passes.
  • Attacker exits with borrowed assets.
    After: once the oracle updates, the position becomes underwater; liquidation may not fully cover → bad debt.
  1. Unfair liquidation with stale-low collateral price → steal from users

Condition and likelihood: oracle is stale at an old lower price during a pump.

Flow

  • A borrower who is healthy at the real price appears unhealthy at the stale-low price.
  • Liquidator calls Market.liquidate(...).
  • Auditor.checkLiquidation() / Auditor.calculateSeize() use the stale-low collateral price, enabling liquidation and determining seize amounts on wrong inputs.

Impact: borrower loses collateral even though they were healthy at real market prices; liquidator profits.

Recommendation

  • Replace IPriceFeed.latestAnswer() with a Chainlink-style interface exposing latestRoundData() and enforce freshness:
require(updatedAt >= block.timestamp - MAX_STALENESS)
  • Make staleness thresholds per-feed configurable (governance-set) since heartbeats differ across assets/chains.

@cruzdanilo @pmolina @lucaslain

Pls take a look at this, as i have other issues of bugs i would be submitting for this contract.

主要语言
Solidity
星标
92
派生
44
平均合并
8 天 7 小时
30 天内合并 PR
4

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

exactly/protocol 的其他 Issue

查看 exactly/protocol 的全部 Issue

相似的 Issue

更多 Blockchain Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。