Skip to content

[PR #38] p2: executeOperation callback body (steps a-l) has zero deterministic test coverage #126

@obchain

Description

@obchain

Summary

CharonLiquidator.t.sol Section A tests the two entry gates of executeOperation (!pool, !initiator). No test exercises any code beyond those two require statements. The 12 steps documented in the executeOperation NatSpec — Venus liquidation, collateral redemption, PancakeSwap swap, profit sweep, balance verification, and Aave repayment approval — are covered only by the skipped fork test.

This means the following code paths have zero test coverage:

  • Step a: abi.decode(data, (LiquidationParams))
  • Step b: require(asset == p.debtToken, "asset/debt mismatch") and require(amount == p.repayAmount, "amount/repay mismatch")
  • Step c: IERC20.approve + IVToken.liquidateBorrow + liqErr check
  • Step d: approval zero-out
  • Step e: IVToken.balanceOf + redeem + vBal > 0 check + redeemErr check
  • Step f: IERC20(collateral).balanceOf + ISwapRouter.exactInputSingle + minSwapOut enforcement
  • Step g: router approval zero-out
  • Step h: require(finalBal >= totalOwed, "swap output below repayment")
  • Step i: profit transfer to owner
  • Step j: LiquidationExecuted event emission
  • Step k: Aave approval for totalOwed
  • Step l: return true

Location

contracts/test/CharonLiquidator.t.sol — Sections A, B, C, D all bypass executeOperation's liquidation body. Section E is skipped.

PRD / invariant violated

This is the core fund-moving logic of the entire protocol. The CLAUDE.md safety invariants — profit swept to cold wallet, Aave repaid correctly — apply to code that is completely untested by this PR.

Risk

The three p0/p1 bugs already filed (#120 profit-to-hot-wallet, #121 vBNB path broken, #122 fee tier hardcoded) all live inside the untested body. A test suite that passes green while these bugs exist provides false assurance. A mocked walkthrough of executeOperation — using stub vToken and stub router contracts that return controlled values — would have surfaced all three bugs without requiring a fork.

Fix

Add at least one deterministic unit test that exercises the happy path of executeOperation end-to-end using stub/mock external contracts (stub Aave pool that calls executeOperation directly, stub vToken that returns 0 for liqErr and redeemErr, stub router that transfers a fixed debtToken amount). Assert:

  • LiquidationExecuted emitted with correct args
  • profit amount transferred to expected address
  • Aave pool approved for totalOwed

Refs #38

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions