LlamaRisk

Market-state workflow

The pendle_ema_oracle workflow is the state-producing stage of the PT oracle. It converts finalized Pendle market data into one smoothed observation that both recommendation workflows can consume. It does not recommend or change an Aave parameter.

What one run does

  1. Take the CRE consensus timestamp as computedAt.
  2. Resolve the latest finalized source-chain block and read the configured Pendle market.
  3. Verify that the market's PT is the configured PT.
  4. Stop without writing if the market has matured.
  5. Read enabled, modelVersion, and emaSpan from PTParameterRegistry on the write chain.
  6. Stop without writing if the registry entry is disabled.
  7. Read the latest accepted EmaImpliedRateUpdate, if one exists.
  8. Bootstrap or advance both EMA series.
  9. Submit one DON-signed update to the configured LlamaGuard receiver.

All contract reads use finalized confidence. The concrete source block number is included in the result so a reader can identify the state from which it was calculated.

Source observation

The workflow reads lastLnImpliedRate, totalPt, totalSy, scalarRoot, and expiry from the Pendle market. It also reads SY.exchangeRate() and YT.pyIndexStored().

Pendle values the SY balance with the non-decreasing PY index:

PY index    = max(SY exchange rate, stored PY index)
total asset = total SY × PY index
p_current   = total PT / (total PT + total asset)

Using the stored PY index when it is higher prevents negative yield from overstating the PT share of the pool. Both the logarithmic implied rate and market proportion are carried as 18-decimal fixed-point values.

EMA state transition

For registry span N, the workflow calculates:

alpha    = 2 / (N + 1)
EMA_next = alpha × current + (1 - alpha) × EMA_previous

The calculation is applied independently to the logarithmic implied rate and market proportion. Signed fixed-point division rounds half away from zero so positive and negative deltas are treated symmetrically.

If no earlier EMA record exists, each series is seeded from its current observation:

rate EMA       = current logarithmic implied rate
proportion EMA = current market proportion

The record flags which values were seeded. On subsequent runs, the workflow continues from the latest accepted EMA values and records the previous values in the new payload.

Span depends on sampling frequency

emaSpan is a number of observations, not a duration. Its effective time horizon therefore depends on the deployment's cron schedule.

Effect of a short-lived move

For emaSpan = 48, the newest observation receives weight:

alpha = 2 / (48 + 1) ≈ 0.0408

If the workflow samples hourly and the raw implied rate is displaced by one percentage point for a single observation, the immediate change in the EMA is approximately:

1 percentage point × 0.0408 ≈ 0.0408 percentage point ≈ 4.08 basis points

The example illustrates why a short-lived market move has limited influence on the shared input. It is not a complete manipulation-cost claim: the actual effect depends on the sampling schedule, the duration and path of the move, finalized-state timing, and subsequent observations.

When it does not write

The workflow intentionally returns without publishing when:

  • the Pendle market has matured; or
  • the PT entry is disabled in PTParameterRegistry.

There is no deviation threshold or minimum-delay gate in this workflow: every eligible run publishes the next EMA state. A missing required read, PT-address mismatch, invalid market proportion, invalid span, or receiver failure aborts the run.

Published record

The update type is EmaImpliedRateUpdate, keyed by the PT address.

Record fieldContents
newValueABI-encoded signed WAD implied-rate EMA
referenceIdUpdate type, source chain ID, PT address, finalized source block, and model version
additionalDataRaw rate, previous rate EMA, span, maturity, calculation time, source block, model version, bootstrap flags, raw proportion, previous proportion EMA, and new proportion EMA
deadlinecomputedAt + 86,400 seconds

The deadline limits how long the signed observation can remain publishable. Downstream freshness is stricter and independent: both recommendation workflows compare the observation time and the source block's timestamp with emaFreshnessSeconds before using the record.

On this page