sherlock-2025-07-mellow-m09

[M-09] Stuck stETH rewards in queue contracts

보고서

Summary

stETH는 LidoDepositHook 로 wstETH로 변환되지만, 입금 즉시 변환되지는 않는다. DepositQueue에 예치되어 있는 도중 리베이스된 금액을 핸들링하지 않으므로 stETH에서 발생한 수익을 잃게 된다.

Keyword

rebase token, erc20, stETH

Vulnerability

stETH는 리베이스 토큰으로 매일 balance가 변한다. stETH를 입금할 때는 LidoDepositHook 를 사용한다. 훅은 가격 오라클이 업데이트 되어 DepositQueue.handleReport 가 호출될 때마다 호출된다. 가격 오라클이 업데이트 되기 전까지는 stETH의 형태로 DepositQueue에 머무른다. DepositQueue에 예치되어 있는 동안 stETH는 리베이스하여 balance가 변할 수 있지만 이를 핸들링하지 않는다. 따라서 DepositQueue에 예치되어 있는 동안 발생한 stETH의 이자는 컨트랙트에 잠긴다.

function _handleReport(uint224 priceD18, uint32 timestamp) internal override {
    ...
@>  uint256 assets = uint256($.requests.get($.handledIndices, latestEligibleIndex));
    ...
    address asset_ = asset();
    TransferLibrary.sendAssets(asset_, address(vault_), assets);
    IRiskManager riskManager = IVaultModule(address(vault_)).riskManager();
    riskManager.modifyPendingAssets(asset_, -int256(uint256(assets)));
    riskManager.modifyVaultBalance(asset_, int256(uint256(assets)));
@>  vault_.callHook(assets);
}

또한 (아직까지는 일어난 적 없지만) stETH balance가 줄어드는 방향으로 리베이스가 일어날 수도 있다. 이 경우 토큰이 모자라 상호작용이 revert 될 수 있다.

Impact

DepositQueue에 예치되어 있는 동안 발생한 stETH의 이자는 컨트랙트에 잠긴다.

Mitigation

stETH의 경우 DepositQueue에 예치된 시점에 wstETH로 변환해야 한다.


tags: bughunting, mellow, smart contract, solidity, severity medium, rebase token, erc20, weird erc20, asset lock