ph.outflowRate() and ph.inflowRate() return rate statistics for the rolling window that caused a cumulative ERC20 flow trigger to invoke an assertion. The getters take no arguments, do not register a trigger, and do not enforce a rate limit.
Interface
When it runs
After deployment, the cumulative watcher tracks the assertion adopter’s balance changes for the configured ERC20 token. It invokes the registered assertion function when net inflow or outflow is strictly greater thanthresholdBps of the window-start balance.
During that invocation, ph.inflowRate() or ph.outflowRate() returns rate statistics calculated from the same rolling-window data. The getter does not trigger the assertion by itself.
Directional flow
The executor records both inflow and outflow. It derives the directional values as follows:
Opposite-direction flow therefore offsets the watched direction. The per-block rates clamp each bucket independently, while the mean uses net flow across the entire retained window.
Rate calculations
All three rate fields are integer values measured in basis points oftvlSnapshot per second.
Peak rate
For every retained block bucket, the executor calculates:bucket rate = floor(net block flow × 10,000 ÷ (tvlSnapshot × 10 seconds))
peakRateBps is the greatest bucket rate. The denominator always uses 10 seconds; it does not use the chain’s actual block interval.
Latest rate
lastRateBps is the bucket rate for the most recent retained block. A previous spike can therefore remain in peakRateBps while lastRateBps falls to a lower value.
Mean rate
The mean uses the active span between the earliest and latest retained buckets:active span = latest bucket timestamp - earliest bucket timestamp + 10 seconds
mean rate = floor(net window flow × 10,000 ÷ (tvlSnapshot × active span))
It does not divide by the full configured window when the retained activity covers a shorter span. With one retained bucket, the active span is 10 seconds, so peak, latest, and mean rates are equal.
Returned fields
Edge cases
Calculation example
For atvlSnapshot of 100,000 tokens:
Both results use the fixed 10-second denominator for each block bucket. The timestamps of the first and last retained blocks determine
meanRateBps.
Combined inflow and outflow example
This assertion registers both cumulative directions with a low dispatch threshold, reads the matching cumulative and rate contexts, and rejects when either configured limit is exceeded.Circuit breakers should be paired with invalidation monitoring and an incident-response plan. See Monitoring and incident response.

