The first successful call to stake() permanently transitions the pool by setting expiryLocked = true. However, this state transition occurs silently without emitting an event.
As a result, off-chain indexers, monitoring systems, analytics dashboards, and automation services cannot efficiently detect when the expiry becomes locked without continuously polling contract storage.
The stake() function contains the following logic:
expiryLocked appears to represent an important lifecycle transition for the pool:
Before the first stake, expiry is still mutable.
After the first stake, expiry becomes permanently locked.
The transition only occurs once during the pool's lifetime.
Despite representing a one-time and irreversible state change, no event is emitted.
Ethereum events are the standard mechanism for exposing important state transitions to off-chain consumers. Without an event, external systems must either:
continuously poll the contract,
compare storage snapshots between blocks,
or detect the state transition indirectly through transaction traces.
These approaches are less efficient and more error-prone than subscribing to a dedicated event.
Although this issue does not affect protocol correctness or fund safety, it negatively impacts operational visibility.
Affected off-chain integrations include:
Indexers (The Graph, custom indexers)
Monitoring and alerting systems
Automation bots
Because the transition occurs only once, an event would provide a reliable and canonical signal that the pool's expiry has become immutable.
Emit an event when expiryLocked changes from false to true.
Example:
This provides an inexpensive, standardized notification for off-chain consumers while preserving existing protocol behavior.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
View preliminary resultsAppeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.