sherlock-Usual ETH0

这是一个关于代币质押与兑换的合约

移除某些质押代币后,导致某些函数功能不能使用

因为某些函数(swap等)利用的数组来实现历遍质押代币,有些条件判断了质押代币不能为零,如果某些代币被移除后,那么整个函数就会被revert.

精度的问题,四舍五入,向下取整,多层函数实现的

向下取整后,又作为分母,导致差值越来越大
建议给分母加一消除向下取整

function wadTokenAmountForPrice(uint256 wadStableAmount, uint256 wadPrice, uint8 tokenDecimals)
internal
pure
returns (uint256)
{
+ return Math.mulDiv(wadStableAmount, 10 ** tokenDecimals, wadPrice + 1, Math.Rounding.Floor);
- return Math.mulDiv(wadStableAmount, 10 ** tokenDecimals, wadPrice, Math.Rounding.Floor);
}

前置攻击

合约中没有为 wstETH 和其他 LST(流动性质押代币) 设置链上的价格偏离阈值检查机制。当这些代币价格偏离预期区间时,合约不会自动暂停或回滚交易。

缓解方案
必须在链上实现 LST 的价格偏离检查机制,仅靠链下监控 + 提交交易是不安全的,因为交易提交后未必能立刻执行,容易被前置交易。

方案一:与市场价格交叉验证
AbstractOracle.getPrice()_checkDepegPrice() 中引入机制:

若 wstETH 的链上市场价格(例如 Chainlink 报价)与 Oracle 汇率价格偏差超过某个阈值,自动中止交易。

例如 Chainlink 的 wstETH 报价跌至 0.5,而 stEthPerToken() 仍为 1.2,可判定为异常,直接回滚交易。

此方式能防止因 LIDO Oracle 延迟而导致的套利攻击。

方案二:与预期价格增长幅度交叉验证
参考 AAVE 的做法:

LST 年化收益大致为 5%,若某时返回的汇率远高于或低于这一合理增长区间,可能意味着价格被操纵或系统出现异常。

在这种情况下,可以启用价格上限(如 AAVE 中的 maxRatio)或直接暂停操作。

提供一个参考的机制,