sherlock-2025-07-mellow-h03

[H-03] Unable to withdraw native tokens because vault and redeem hooks do not handle native tokens

보고서

Summary

볼트와 redeem hook 가 네이티브 토큰의 예외처리를 하지 않아 네이티브 토큰의 출금을 요청했을 때 처리하지 못한다. 유저가 네이티브 토큰을 출금할 수 없다.

Keyword

native token, logic flaw

Vulnerability

볼트는 전반적으로 네이티브 토큰을 지원할 수 있도록 구현되었으며, 네이티브 토큰은 사용 토큰 목록에 포함된다. 하지만 출금 시 토큰 잔액을 조회할 때 asset 토큰이 네이티브 토큰인 경우를 고려하지 않는다. 이로 인해 출금은 실패한다.

  1. RedeemQueue와 SignatureRedeemQueue 는 출금을 처리하기 위해 vault.getLiquidAssets 를 호출하여 토큰 수를 조회한다. 훅을 사용하지 않는 경우 ERC20의 balanceOf 를 호출한다. 만약 asset이 네이티브 토큰이라면 이 함수 호출은 실패하여 트랜잭션이 취소된다. modules/ShareModule.sol#L150
function getLiquidAssets() public view returns (uint256) {
    ...
    address hook = getHook(queue);
@>  return hook == address(0) ? IERC20(asset).balanceOf(address(this)) : IRedeemHook(hook).getLiquidAssets(asset);
}
  1. 훅을 사용하는 경우 Hook.getLiquidAssets 를 호출한다. 현재 출금 훅은 BasicRedeemHook 만 존재한다. BasicRedeemHook.getLiquidAssets 함수는 asset이 네이티브 토큰이라면 balanceOf 가 실패하여 취소된다. hooks/BasicRedeemHook.sol#L35-L39
function getLiquidAssets(address asset) public view virtual returns (uint256 assets) {
    IVaultModule vault = IVaultModule(msg.sender);
@>  assets = IERC20(asset).balanceOf(address(vault));
    uint256 subvaults = vault.subvaults();
    for (uint256 i = 0; i < subvaults; i++) {
        address subvault = vault.subvaultAt(i);
@>      assets += IERC20(asset).balanceOf(subvault);
    }
}
  1. RedeemQueue와 SignatureRedeemQueue 는 출금을 처리하기 위해 vault.callHook을 호출한다. 이 함수는 출금 훅이 등록되어 있는 경우 Hook.callHook 을 delegatecall로 호출한다. 현재 출금 훅은 BasicRedeemHook 만 존재한다. BasicRedeemHook.callHook 은 asset이 네이티브 토큰이라면 balanceOf 가 실패하여 취소된다. hooks/BasicRedeemHook.sol#L11-L19
function callHook(address asset, uint256 assets) public virtual {
    IVaultModule vault = IVaultModule(address(this));
@>  uint256 liquid = IERC20(asset).balanceOf(address(vault));
    ...
    for (uint256 i = 0; i < subvaults; i++) {
        address subvault = vault.subvaultAt(i);
@>      uint256 balance = IERC20(asset).balanceOf(subvault);
        ...
    }
}

Impact

네이티브 토큰을 출금할 수 없다. 유저가 asset 토큰을 꺼낼 수 없다.

Mitigation

asset 토큰이 네이티브 토큰일 시 ERC20.balanceOf 대신 네이티브 토큰의 잔액을 조회한다.


tags: bughunting, mellow, smart contract, solidity, severity high, native token, logic flaw