ERC-8329 Subject-linked impact snapshot log

Last Call · Other · created 2026-07-05

A standard for recording quantitative impact measurements, such as carbon emissions, employment, or water treatment, on-chain in an append-only manner, tied to a subject, period, unit, and methodology. It preserves correction history and support/dispute attestations without erasing past records.

Why it is needed

Impact measurements such as carbon offset volumes or employment figures are usually distributed in different data formats across reports and services. On-chain, there was no common interface for recording such values together with the measurement subject, measurement period, unit, and methodology while preserving later corrections. Overwriting a single value cannot distinguish whether it is a value for a new reporting period or a rewrite of a past measurement, and the previous claim is erased the moment it is updated. General-purpose attestations can express individual claims, but behaviors such as per-indicator time-series indexing, exact per-period uniqueness, correction chains, and methodology transitions are not defined by attestations themselves. This standard solves this with append-only recording, correction provenance tracking, and methodology hash commitments. However, it does not judge which indicators or methodologies are valid, nor does it verify the measurement values themselves.

In depth

Snapshot structure and value representation

A single snapshot is stored as an IndicatorSnapshot struct containing subjectId, indicatorId, value, decimals, unit, periodStart, periodEnd, methodologyHash, methodologyURI, reportedBy, reportedAt, correctsIndex, and correctedByIndex. The actual quantity is interpreted as value * 10^(-decimals). value is int256 because measurements such as net emissions or reductions relative to a baseline can be negative, and consumers must not assume the value is non-negative. There is no upper bound on decimals beyond the uint8 type limit, so consumers must safely handle the declared precision. unit is recommended to use the keccak256 hash of a documented canonical unit string, preferably SI- or UCUM-compatible, and custom units must document case, spelling, pluralization, and conversion rules.

Measurement period and period-slot uniqueness

The measurement period is a half-open interval [periodStart, periodEnd) that includes the start and excludes the end. recordSnapshot must revert unless periodStart < periodEnd <= block.timestamp holds, so only periods that have already ended can be recorded. The exact period slot is identified by the four values (subjectId, indicatorId, periodStart, periodEnd), and a given slot can hold at most one original snapshot. Any modification after a slot is filled must go through correction provenance. Different periods may overlap, since legitimate overlaps exist, such as monthly and annual reports. This standard does not determine whether overlapping measurements are summable or duplicative, so the aggregator must apply methodology-specific rules.

Correction chains and sentinel values

Implementations must use the constant NO_CORRECTION = type(uint256).max, and when correctsIndex equals this value the snapshot is an original. If correctedByIndex is 0, the snapshot is a terminal snapshot not yet corrected, since a correction's index is always greater than its target's, making 0 a safe sentinel. A correction must reference a prior snapshot with the same subjectId, and must use the same indicatorId, periodStart, and periodEnd as the target, and may only correct a snapshot whose correctedByIndex is 0. When a correction is accepted, only the target's correctedByIndex changes to the new index; all other fields remain unchanged. Each snapshot can be corrected at most once, which keeps the chain linear and prevents branching. Reporting authority alone must not be allowed to permit correcting another reporter's record; authority may instead be granted to the original reporter, a designated corrector, or an administrator.

Distinguishing recording rules from query functions

Snapshot indices start at 0 per subjectId, and the returned snapshotIndex must equal the number of target snapshots that existed immediately before the append. recordSnapshot must be restricted to approved reporters, and the authorization mechanism must be documented. When stored, reportedBy is set to msg.sender and reportedAt to uint64(block.timestamp); methodologyHash must not be bytes32(0), and methodologyURI must not be empty. On the query side, latestIndicatorSnapshot returns the most recently recorded snapshot, which is based on recording order rather than period recency, so it may be a late correction to an old period. If the current value for a specific reporting period is needed, currentSnapshotForPeriod must be used; this function returns the terminal snapshot for the exact period slot and reverts if the slot is empty.

Standard indicator and unit identifiers

Nine indicator identifiers are defined in the form keccak256("ERC-8329:INDICATOR:<name>"): CARBON_OFFSET, CARBON_EMITTED, ENERGY_GENERATED, ENERGY_SAVED, WATER_TREATED, JOBS_CREATED, BENEFICIARIES, BIODIVERSITY_AREA, and WASTE_DIVERTED. For custom indicators, the pattern keccak256("ERC-8329:INDICATOR:<NAMESPACE>:<NAME>:<VERSION>") is recommended, and generic identifiers such as keccak256("CUSTOM") should be avoided since they fail to distinguish meaning. Seven unit identifiers are defined: UNIT_TCO2E, UNIT_KWH, UNIT_M3, UNIT_FTE, UNIT_PERSONS, UNIT_HECTARES, and UNIT_TONNES. Because an indicator identifier does not enforce a unit, reporters and consumers must not infer the unit from indicatorId alone and should check the stored unit and methodology.

Operating rules of the attestation extension

The attestation extension is optional. attestSnapshot must reject a nonexistent snapshot and a zero evidenceHash, while evidenceURI may be left empty. attestor is recorded as msg.sender and attestedAt as uint64(block.timestamp). The reporter address stored in a snapshot cannot attest to that same snapshot, but this is only an address-level separation and does not guarantee organizational, financial, or legal independence. Attestations are immutable and cannot be deleted, and the same attestor may submit multiple attestations to the same snapshot, including a revised assessment after changing their mind, so consumers must evaluate the full history. Attestations can be attached even to an already-corrected snapshot, but attestations attached to a prior snapshot are not automatically carried over to the correction, so whether they still apply is left to the consumer's judgment.

Methodology versioning and replacement conditions

The methodology versioning extension is also optional. The first snapshot for a given subject and indicator initializes the active methodology with its own methodologyHash and methodologyURI, and subsequent snapshots must use the methodology hash active at that ordinal. supersedeMethodology succeeds only if the methodology has been initialized, oldMethodologyHash matches the active methodology, the new hash is nonzero, the new URI is non-empty, no replacement is pending, and effectiveFromOrdinal is greater than or equal to the current indicatorSnapshotCount. If the effective ordinal equals the current count, the change takes effect immediately; if it is greater, the change becomes pending and is exposed via pendingMethodology. Once the effective ordinal is reached, activeMethodology must expose the new methodology without any separate state-changing call. Historical values recalculated under the new methodology must be submitted as corrections; existing snapshots must not be altered.

Scope of the standard and current status

This standard only specifies representation and lifecycle behavior. It does not define which indicators or methodologies are valid, does not verify reported measurements, does not vet the qualifications of reporters or attestors, does not prevent duplicate claims, and does not provide impact scores. A compliant implementation must implement ERC-165 and return true for type(IImpactSnapshotLog).interfaceId, and if it supports the extensions, it must also return true for the interface IDs of IImpactAttestation and IMethodologyVersioning. However, ERC-165 only indicates interface support and does not guarantee measurement accuracy or eligibility. This proposal is currently in Last Call status (deadline 2026-10-19), the final comment period before finalization, and its content may still change.

Things to watch out for

Original ERC · ← ERCs