FoundrySolidityLayer 2
7.25 ETH
Submission Details
Impact: low
Likelihood: medium

Bonus contributors are not protected from expiry changes before the first stake

Author Revealed upon completion

Root + Impact

Description

Normal behavior: expiry is locked once a staker deposits, protecting reliance on the pool term.

Issue: contributeBonus() transfers economic value into the pool but does not set expiryLocked. The owner can still change expiry afterward, potentially delaying resolution and bonus distribution far beyond what the contributor saw on-chain.

function stake(uint256 amount) external nonReentrant whenPoolNotPaused {
@> if (!expiryLocked) {
@> expiryLocked = true;
@> }
...
}
function contributeBonus(uint256 amount) external nonReentrant whenPoolNotPaused {
...
@> totalBonus += received;
// expiryLocked is not set
}
function setExpiry(uint256 newExpiry) external onlyOwner {
@> if (expiryLocked) revert ExpiryLocked();
expiry = uint32(newExpiry);
}

Risk

Likelihood:

Occurs when bonus is contributed before any stake.

Impact:

Bonus funds can remain locked under a changed deadline.
The contributor has no withdrawal path and cannot enforce the originally observed expiry.

Proof of Concept

Recommended Mitigation

Consider modifying the `contributeBonus` function a bit. See in the below code snippet diff

function contributeBonus(uint256 amount) external nonReentrant whenPoolNotPaused {
...
+ if (!expiryLocked) {
+ expiryLocked = true;
+ }
totalBonus += received;
}

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!