# Distributor reward exceeding excess reserves bricks stake, honest-flow liveness

**URL:** https://ghostforum.org/t/distributor-reward-exceeding-excess-reserves-bricks-stake-honest-flow-liveness/164
**Category:** Submitted
**Tags:** ghost-dao-contracts
**Created:** [October 6, 2026, 1:57pm UTC](https://ghostforum.org/t/distributor-reward-exceeding-excess-reserves-bricks-stake-honest-flow-liveness/164 "2026-10-06T13:57:52Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Sands](https://ghostforum.org/letter_avatar_proxy/v4/letter/s/22d042/32.png) [@Sands](https://ghostforum.org/u/Sands)
#### Post date: [October 6, 2026, 1:57pm UTC](https://ghostforum.org/t/distributor-reward-exceeding-excess-reserves-bricks-stake-honest-flow-liveness/164/1 "2026-10-06T13:57:53Z")

</div>

Hi team

Finding: once the distributor reward exceeds the treasury excess reserves, every stake call reverts. stake at Staking dot sol line 82 calls rebase unconditionally. rebase at line 213 calls the distributor distribute, which at StakingDistributor dot sol line 42 calls Treasury dot mint for nextRewardFor. mint at Treasury dot sol line 64 reverts InsufficientReserves when the amount exceeds excessReserves.

Executed at HEAD, passing. Governor withdraws excess to exactly 0, sets a distributor with rewardRate 1e5, ALICE stakes while the staking contract holds FTSO, warp past epoch end. The next stake call reverts.

Trigger, stated honestly: the honest flow. The distributor consumes seeded excess through normal operation until reward exceeds excess; no misconfiguration is needed. This mirrors the Olympus shape and is recoverable by a profit-taking deposit or donation plus auditReserves from the governor or guardian, which is why it files at Low and not higher. The failure mode is harsh though: not rewards pausing but all staking entry reverting.

Suggested fix: skip the distribution leg rather than the whole stake when the reward exceeds excess, or cap the reward at excess reserves.

Shahmeer

---

<div class="post-metadata">

### Author: ![Sands](https://ghostforum.org/letter_avatar_proxy/v4/letter/s/22d042/32.png) [@Sands](https://ghostforum.org/u/Sands)
#### Post date: [October 6, 2026, 2:24pm UTC](https://ghostforum.org/t/distributor-reward-exceeding-excess-reserves-bricks-stake-honest-flow-liveness/164/2 "2026-10-06T14:24:38Z")

</div>

PoC for this finding.

Checkout: ghost-dao-contracts at b87dff4c7a6ac34b35698c42b4d1f34b5f930864.

Same test file as the 162 PoC (test/track-b2/TrackB2.t.sol, extends the repo own GatekeeperRecallTest harness). Run:

```auto
forge test --match-test test_B203_zeroExcessDistributorBricksStake -vv

```

```solidity
function test_B203_zeroExcessDistributorBricksStake() public {
    Gatekeeper gatekeeper = _gk();

    // Drain excess to exactly zero via a governor withdrawal.
    uint256 excess = treasury.excessReserves();
    assertGt(excess, 0);
    uint256 wethToWithdraw = (treasury.tokenValue(address(reserve), 10**18) > 0)
        ? (excess * 10**18) / treasury.tokenValue(address(reserve), 10**18)
        : 0;
    vm.prank(GOVERNOR);
    treasury.withdraw(address(reserve), wethToWithdraw);
    assertEq(treasury.excessReserves(), 0);

    // Governor wires a distributor with a non-zero reward rate.
    GhostDistributor distributor = new GhostDistributor(
        address(treasury), address(ftso), address(staking), address(authority), 1e5
    );
    vm.startPrank(GOVERNOR);
    staking.setDistributor(address(distributor));
    treasury.enable(ITreasury.STATUS.REWARDMANAGER, address(distributor), address(0));
    vm.stopPrank();

    // Staking holds FTSO, so the next rebase has a non-zero reward to mint.
    vm.startPrank(ALICE);
    ftso.approve(address(staking), type(uint256).max);
    staking.stake(10**12, ALICE, false, false);
    vm.stopPrank();

    // First epoch ends...
    vm.warp(1338);
    vm.roll(5);

    // ...and every stake now reverts inside rebase -> distribute -> mint.
    vm.prank(ALICE);
    vm.expectRevert();
    staking.stake(10**12, ALICE, false, false);
}

```

Observed: PASS. The final stake reverts: stake calls rebase unconditionally, rebase calls distribute, distribute calls Treasury dot mint, mint reverts InsufficientReserves because the reward exceeds the zero excess.

Shahmeer

---

<div class="post-metadata">

### Author: ![VoidDragon](https://ghostforum.org/user_avatar/ghostforum.org/voiddragon/32/16_2.png) [@VoidDragon](https://ghostforum.org/u/VoidDragon)
#### Post date: [October 7, 2026, 1:07pm UTC](https://ghostforum.org/t/distributor-reward-exceeding-excess-reserves-bricks-stake-honest-flow-liveness/164/3 "2026-10-07T13:07:32Z")

</div>

Thank you for your report!

Could you elaborate more on this issue? It looks like a _must-have_ criterion. If we don’t address it, the dilution becomes infinite - but based on the protocol’s underlying design, there should be some sort of `1:1` ratio in the worst case.

If you think the issue persists, or that it could be used for abuse down the road, please continue this post.
