SettleMint
ArchitectureComponentsCapabilities

Issuer-signed scalar feed

Issuer-signed scalar feeds let trusted issuers publish signed integer values for a subject and topic, then expose the latest value through a Chainlink-compatible read interface.

An issuer-signed scalar feed is DALP's primitive for publishing a signed number on-chain. Use it when an asset, identity, or global feed subject needs a topic value attested by a trusted issuer.

The feed answers three questions for downstream systems:

  1. Which subject and topic does this value belong to?
  2. Which trusted issuer signed the update?
  3. What current scalar value should consumers read through the feed interface?

For the procedural API flow, see Create feeds. For the wider registry and adapter model, see Feeds system.

Where it fits

Issuer-signed scalar feeds are deployed by the IssuerSignedScalarFeedFactory. Each feed instance is pinned at creation time to a subject, a numeric topic ID, and the scalar schema hash for that topic. Issuer-signed scalar feeds require the topic scheme to match the scalar (int256 value) schema. The factory derives the schema hash from the topic scheme registry, deploys the feed, then registers it in the FeedsDirectory as a scalar feed.

Consumers do not need to know who deployed the feed. Consumers resolve the (subject, topic) pair through the FeedsDirectory, then read the current value from the returned feed or from an adapter.

Deployment configuration

The create API and factory set the same feed invariants, but they do not accept exactly the same input shape. The API accepts either topicName or topicId and checks that both refer to the same registered topic when both are supplied. Direct factory calls use the numeric topicId only. These values are immutable for the feed instance.

SettingTypeWhat it controls
subjectEVM addressThe asset, identity, or global zero address the feed is about.
topicName or topicIdstringAPI input for the registered topic. Direct factory calls use the numeric topicId.
decimalsinteger, 0 to 18How to interpret fixed-point integer answers.
descriptionstringHuman-readable feed description returned by the aggregator interface.
historyModeLATEST_ONLY, BOUNDED, or FULLHow much historical round data the feed keeps on-chain.
historySizenon-negative integerRing-buffer size for BOUNDED history. Must be greater than zero for bounded history.
requirePositivebooleanWhether the feed rejects zero and negative values.
driftAllowanceinteger secondsHow far observedAt may be in the future relative to the current block timestamp.

driftAllowance is a timestamp tolerance, not a percentage price-change guard. A value of 0 means the submitted observedAt cannot be later than the current block timestamp.

Update verification

Every update is an EIP-712 signed FeedUpdate with these fields:

FieldMeaning
topicIdMust match the feed's pinned topic.
schemaHashMust match the feed's pinned schema hash.
valueThe signed scalar integer.
observedAtThe timestamp used as the feed round's startedAt and updatedAt.
nonceThe issuer's next sequential nonce for this feed. The first valid nonce is 1.
deadlineSignature expiry timestamp. 0 means no deadline.

When submit is called, the feed verifies the update before it changes state:

  1. The topic and schema hash match the feed instance.
  2. The issuer is authorized for the feed's topic and subject in the trusted issuers registry.
  3. The EIP-712 signature recovers to an EOA signer.
  4. The signer has CLAIM purpose on the issuer identity.
  5. The issuer nonce is exactly one greater than the previous nonce.
  6. The deadline has not expired, unless the deadline is 0.
  7. If requirePositive is true, the value is greater than zero.
  8. observedAt is not zero.
  9. observedAt does not move backwards compared with the latest accepted update.
  10. observedAt is not farther in the future than driftAllowance permits.

Only after these checks pass does the feed increment the round, store the latest answer, update the issuer nonce, and emit FeedUpdated.

History modes

History mode controls what getRoundData can return.

ModeBehaviorUse when
LATEST_ONLYStores the latest answer only. getRoundData reverts because historical rounds are not retained.Consumers only need the current value.
BOUNDEDStores recent rounds in a ring buffer of historySize. Older slots are overwritten and evicted rounds cannot be read.Consumers need recent verification history without unbounded storage.
FULLStores every accepted round by round ID.Consumers require full on-chain round history and the update frequency is low enough for that storage profile.

latestRoundData works in every mode and returns the current round ID, answer, timestamp, and answered-in-round value using the Chainlink-style aggregator shape.

Value format

Feed answers are signed integers. The feed's decimals value defines how consumers convert that integer to a human-readable number.

human-readable value = answer / 10^decimals

For example, an answer of 15000 with decimals = 2 represents 150.00. The feed stores and returns the integer value. Consumers are responsible for applying the decimal scale consistently.

When requirePositive is enabled, the feed rejects 0 and negative answers. A feed that represents negative values, such as a spread or rate delta, needs requirePositive disabled.

Discovery path

The FeedsDirectory is the discovery layer for issuer-signed scalar feeds.

  1. The factory deploys the feed with the configured subject, topic, schema, decimals, history mode, positivity rule, and timestamp tolerance.
  2. The factory registers the feed in the FeedsDirectory as a scalar feed for the same subject and topic.
  3. Consumers resolve the (subject, topic) pair to find the feed address.
  4. Consumers read the latest value from the feed, or use an aggregator adapter if they need a stable address that can follow future directory changes.

The feed instance itself is not upgradeable. If consumers need a stable integration point across feed replacement, use the adapter and directory path rather than hard-coding the feed address.

Rejection conditions

Common rejects are deliberate safety checks, not partial writes. A rejected update leaves the feed's latest answer, round counter, and issuer nonce unchanged.

RejectionTriggerTypical fix
TopicMismatch or SchemaHashMismatchThe signed update does not match the feed's pinned topic or schema.Sign an update for the same topic and schema as the feed.
IssuerNotAuthorizedThe trusted issuers registry has no matching entry for the issuer, topic, and subject.Configure the issuer in the registry before submitting.
InvalidSigner or InvalidSignatureThe signature cannot be recovered or the signer is not a CLAIM-purpose key on the issuer identity.Sign with an authorized issuer key and use a standard 65-byte ECDSA signature.
InvalidNonceThe nonce is not the issuer's next sequential nonce.Read the issuer nonce and resubmit with nonce + 1.
DeadlineExpiredThe update has a non-zero deadline in the past.Create a fresh signed update.
ValueNotPositiverequirePositive is enabled and the value is zero or negative.Submit a positive value, or create a different feed for values that may be non-positive.
InvalidObservedAt, StaleObservation, or ObservedAtTooFarInFutureThe observation timestamp is zero, older than the latest accepted observation, or too far in the future.Use a real observation timestamp that is monotonic and within the feed's tolerance.
HistoryNotSupported or RoundNotFoundA consumer asks for history outside the feed's retained rounds.Use latestRoundData, choose a history-retaining mode, or request a retained round.

See also

On this page