<!-- canonical: https://0xsimao.com/findings/morpho-midnight-test-jumps-asserts-direction -->

# `testReturnJumps` asserts the wrong ratio direction

Low/Info · Blackthorn · Lending · 6th April, 2026

Finding I-1 of the Morpho Midnight security review.

- Protocol: https://morpho.org/
- Report: /reports/morpho-midnight
- Codebase: https://github.com/0xsimao/midnight/tree/e9085f8c5fe96df6e075847b95b0dd7cea86110d
- Source: https://github.com/morpho-org/midnight/blob/main/audits/2026-07-02-blackthorn.pdf

---

## Summary

`testReturnJumps` asserts `currentReturn / previousReturn ~= 1.025`, but the actual ratio is `~0.975` since higher tick means higher price and lower return. The test only passes due to the 10% tolerance.

## Vulnerability Detail

In [`TickLibTest.sol#L33`](https://github.com/sherlock-audit/2026-04-morpho-midnight-apr-6th-2026/blob/main/morpho-org__midnight/test/TickLibTest.sol#L33):

```solidity
function testReturnJumps() public pure {
    for (uint256 i = 220; i <= 770; i++) {
        uint256 previousReturn = _return(TickLib.tickToPrice(i - 1));
        uint256 currentReturn = _return(TickLib.tickToPrice(i));
        assertApproxEqRel(
            currentReturn.mulDivDown(1e18, previousReturn), 1.025e18, 0.1e18, ...
        );
    }
}
```

`_return(price) = 1e18 / price - 1`, which is `1/price - 1`. Since `tickToPrice` is monotonically increasing, a higher tick gives a higher price and a lower return. Therefore `currentReturn / previousReturn = 1/1.025 ~= 0.9756`, not `1.025`.

The assertion passes because `|0.9756 - 1.025| / 1.025 ~= 4.8%`, which is within the 10% relative tolerance.

## Impact

The test does not verify what it intends to. The expected value should be `~0.9756e18` (i.e. `1/1.025`), or the ratio should be flipped to `previousReturn / currentReturn`.

## Code Snippet

https://github.com/sherlock-audit/2026-04-morpho-midnight-apr-6th-2026/blob/main/morpho-org__midnight/test/TickLibTest.sol#L28-L36

## Tool Used

Manual Review

## Recommendation

Fix the assertion to check the correct ratio:

```solidity
assertApproxEqRel(
    previousReturn.mulDivDown(1e18, currentReturn), 1.025e18, 0.01e18, ...
);
```

---

Related findings:

- [Wrong rounding direction in StakingPool::unstake() can be abused](https://0xsimao.com/findings/spirit-protocol-rounding-staking-unstake-abused): Spirit Protocol
