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.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.