Alert Source Discuss
⚠️ Draft Standards Track: ERC

ERC-8348: Financial Lease

Jurisdiction-neutral interface for tokenized financial leases with indexed-denomination schedules.

Authors Javier Mateos (@javierpmateos)
Created 2026-07-23
Discussion Link https://ethereum-magicians.org/t/erc-8348-financial-lease/29076
Requires EIP-20, EIP-165, EIP-721, EIP-4907, EIP-8325

Abstract

This EIP defines a standard interface for financial lease agreements represented on-chain. Each lease is identified by a leaseId and the lessor position is represented as an ERC-721 token, making assignment and securitization of lease portfolios compatible with existing NFT infrastructure. The interface exposes the payment schedule, outstanding balance, arrears and default state, purchase option, and party assignment, while remaining neutral with respect to jurisdiction, interest mathematics, and compliance regime.

Schedules are denominated in abstract units of account with an explicit conversion to the payment asset, so that both fixed-amount leases and index-adjusted leases (UVA in Argentina, UF in Chile, IPCA-linked in Brazil) implement the same interface.

An optional extension binds the lease to an on-chain token representing the leased asset, enabling atomic settlement of the purchase option.

Motivation

Financial leasing is a major credit instrument worldwide, yet no ERC defines how a lease contract should be queried or observed on-chain. ERC-4907 standardizes temporary usage rights for NFTs but does not model installments, interest, arrears, purchase options, or assignment. ERC-2615 (a stagnant Draft) adds rental and mortgage roles and liens to ERC-721 but has no credit semantics: no schedules, no indexed denominations, no delinquency model, no purchase option. ERC-3475 standardizes fungible debt securities organized in classes and nonces, oriented to redemption, not bilateral contracts with named parties, formal default, or asset escrow. Outside the EVM standards process, ACTUS (Algorithmic Contract Types Unified Standards) defines a taxonomy of roughly three dozen contract types describing financial instruments as algorithmic cash-flow patterns, and has been used as a reference standard by the US Office of Financial Research. A Solidity encoding existed but covered a single contract type and has been unmaintained since 2020. ACTUS and this standard address different problems: ACTUS is a modelling ontology that requires adopting its full taxonomy to describe an instrument, while this standard defines how a lease contract is observed and queried without prescribing how its obligations are computed. An implementation may use an ACTUS engine internally and expose this interface externally. Compliance standards such as ERC-3643 and ERC-7943 govern who may hold a token, but not the financial semantics of a lease.

Without a common interface, every originator exposes bespoke contracts, and integrators (secondary marketplaces, securitization vaults, auditors, credit scorers) must write custom adapters per originator and per country. This standard follows the approach of ERC-4626: it does not invent leasing; it defines a common way to interact with lease contracts, so that a fund can price and acquire lease portfolios originated in different countries through one interface.

The semantics of “financial lease” used here are informed by the UNIDROIT Convention on International Financial Leasing (Ottawa, 1988): a lessor grants a lessee the use of an asset against periodic payments, with an eventual option to purchase. The term refers to the contractual instrument this interface models. This standard does not determine the accounting classification of a lease, for the lessor or the lessee, under IFRS 16 or ASC 842.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Definitions

  • Unit of account: the abstract denomination of the schedule (e.g. UVA, UF, or the payment asset itself for fixed leases).
  • Payment asset: the ERC-20 token in which payments are made.
  • Lessor position: ownership of the lease receivable, represented by the ERC-721 token whose tokenId equals leaseId.

Core interface

Implementations MUST implement ERC-165 and ERC-721, and MUST use tokenId == leaseId. Transferring the ERC-721 token assigns the lessor position; implementations MAY restrict transfers through a compliance layer.

interface IFinancialLease {
    enum LeaseStatus {
        Active, InArrears, InDefault,
        Terminated, Completed, PurchaseExercised
    }

    // Legal layer
    function jurisdiction(uint256 leaseId) external view returns (bytes2);
    function governingLaw(uint256 leaseId) external view returns (string memory);
    function agreementHash(uint256 leaseId) external view returns (bytes32);
    function assetReference(uint256 leaseId) external view returns (string memory);

    // Parties
    function lessor(uint256 leaseId) external view returns (address);
    function lessee(uint256 leaseId) external view returns (address);

    // Denomination and conversion
    function paymentAsset(uint256 leaseId) external view returns (address);
    function denomination(uint256 leaseId)
        external view returns (string memory symbol, address oracle);
    function convertToAssets(uint256 leaseId, uint256 units)
        external view returns (uint256 assets);
    function convertToUnits(uint256 leaseId, uint256 assets)
        external view returns (uint256 units);
    function conversionRateAsOf(uint256 leaseId)
        external view returns (uint256 rate, uint64 asOf);

    // Schedule (immutable, in units)
    function paymentCount(uint256 leaseId) external view returns (uint256);
    function paymentAt(uint256 leaseId, uint256 index)
        external view returns (uint256 units, uint64 dueDate, bool paid);

    // Live economics
    function outstandingUnits(uint256 leaseId) external view returns (uint256);
    function outstandingBalance(uint256 leaseId) external view returns (uint256);
    function nextPayment(uint256 leaseId)
        external view returns (uint256 assets, uint64 dueDate);
    function arrears(uint256 leaseId) external view returns (uint256);
    function status(uint256 leaseId) external view returns (LeaseStatus);

    // Input freshness (see "Input freshness")
    function inputFreshness(uint256 leaseId, bytes32 input)
        external view returns (uint64 observedAt, uint64 reportedAt, uint64 maxStaleness);

    // Actions
    function pay(uint256 leaseId, uint256 assets) external;
    function purchaseOption(uint256 leaseId)
        external view returns (uint256 priceInAssets, bool exercisable);
    function exercisePurchaseOption(uint256 leaseId) external;

    // Events
    event LeaseCreated(uint256 indexed leaseId, address indexed lessor,
        address indexed lessee, bytes2 jurisdiction, address paymentAsset);
    event PaymentReceived(uint256 indexed leaseId, address indexed payer,
        uint256 assets, uint256 unitsSettled, uint256 conversionRate,
        uint256 newOutstandingUnits);
    event ArrearsAccrued(uint256 indexed leaseId, uint256 totalArrearsUnits);
    event DefaultDeclared(uint256 indexed leaseId, address indexed declarer);
    event DefaultCured(uint256 indexed leaseId);
    event PurchaseOptionExercised(uint256 indexed leaseId, uint256 priceInAssets);
    event LeaseTerminated(uint256 indexed leaseId, LeaseStatus finalStatus);
    event LesseeAssigned(uint256 indexed leaseId,
        address indexed oldLessee, address indexed newLessee);
    event TerminationRecorded(uint256 indexed leaseId, bytes32 indexed reason);
    event ServicingUpdated(uint256 indexed leaseId, bytes32 indexed input,
        uint64 observedAt, uint64 reportedAt);
}

Normative requirements:

  • The schedule returned by paymentAt MUST be immutable after LeaseCreated, and MUST be denominated in units of account.
  • For fixed-denomination leases, denomination MUST return oracle == address(0) and both conversion functions MUST be the identity function.
  • outstandingBalance(id) MUST equal convertToAssets(id, outstandingUnits(id)).
  • The conversion rate returned by conversionRateAsOf MUST express how many base units of the payment asset correspond to 1e18 units of account, absorbing both the oracle’s and the payment asset’s decimal conventions.
  • Rounding MUST NOT favor the caller: convertToAssets used to compute amounts owed MUST round up; convertToUnits used to credit payments MUST round down. Implementations MUST document rounding.
  • Arrears and penalties MUST accrue in units of account. Penalty accrual MUST NOT reduce or be conflated with schedule principal.
  • The arrears and penalty amounts reported by arrears(leaseId) MUST be a function of the payment schedule, the recorded payment history, and the time elapsed since each installment’s due date. They MUST NOT depend on the number, frequency, or timing of the transactions that caused accrual state to be persisted. Two leases with an identical schedule, identical payments and identical elapsed time MUST report identical arrears, however many state-mutating calls occurred in between.
  • Penalty accrual for an installment MUST be measured from that installment’s own due date. An implementation MUST NOT grant an implicit grace period by starting accrual at the moment delinquency is first observed on-chain.
  • paymentAt MUST report an installment as paid only when it has been effectively settled; overdue unpaid installments MUST NOT be reported as paid.
  • View functions MUST report state accrued as of the querying block.timestamp, regardless of when the implementation last persisted state. An implementation MAY accrue lazily in state-changing calls, but a caller that only reads MUST NOT observe stale delinquency, arrears, or status.
  • An installment falls due when block.timestamp exceeds its dueDate. Payment at exactly dueDate MUST NOT be treated as overdue.
  • PaymentReceived.conversionRate MUST record the rate applied, using the same scaling as conversionRateAsOf, so historical conversions are reconstructible without oracle history.
  • Transitions to InArrears MUST be objective (a due date elapsed unpaid). Transitions to InDefault MUST be explicit acts by an authorized declarer and MUST emit DefaultDeclared.
  • ArrearsAccrued signals the objective fact that a due date elapsed unpaid. It does not by itself imply economic loss: an installment settled shortly after its due date may emit the event with no penalty accrued. Consumers evaluating credit behaviour SHOULD read the reported amount rather than the mere occurrence of the event.
  • Lessee assignment MUST emit LesseeAssigned. It MUST be authorized either by the outgoing lessee, or by a role explicitly and separately granted that authority. Holding a role whose purpose is default declaration, servicing, or holding the lessor position MUST NOT by itself confer authority to reassign the lessee, and an implementation MUST NOT default such authority to the lease originator.
  • A role tied to the lessor position — including default-declaration authority — SHOULD resolve to the current holder of the ERC-721 token rather than to a fixed address recorded at origination, so that it follows the economic position when the lease is assigned.
  • If a required oracle is stale beyond the implementation’s documented tolerance, state-changing functions that depend on conversion SHOULD revert; conversionRateAsOf MUST always expose the timestamp of the rate that would be applied.
  • The statuses Completed, PurchaseExercised and Terminated are terminal. An implementation MUST NOT transition a lease out of a terminal status, except from Completed to PurchaseExercised when the purchase option is exercised, and MUST determine terminality by explicit status membership rather than by the ordering of enumeration members.
  • Default is curable: a lease in InDefault whose arrears are settled MUST return to a non-delinquent status and MUST emit DefaultCured. This preserves the standard’s separation between the objective fact of delinquency (InArrears) and the formal act of declaring default (InDefault), and gives DefaultCured operational meaning.
  • INPUT_COLLECTIONS and INPUT_ARREARS_RECORD report the state of the collections process — notices sent, payment plans agreed, referral to legal. They MUST NOT be read as an authoritative restatement of the amount returned by arrears(), which remains the sole on-chain source of truth for amounts owed. INPUT_INSURANCE_STATUS is scoped to insurance covering the leased asset itself, not to instruments guaranteeing payment.

Lease lifecycle

A lease is originated in Active and ends in a terminal status. The only transition between terminal statuses is Completed to PurchaseExercised.

From To Trigger
Active InArrears a due date elapses unpaid
InArrears Active arrears settled
Active / InArrears InDefault formal declaration by an authorized declarer
InDefault Active arrears settled (DefaultCured)
Active / InArrears / InDefault Terminated early termination
any non-terminal Completed full schedule settled
Completed PurchaseExercised purchase option exercised

Permitted operations by status:

Operation names in this table other than pay and exercisePurchaseOption denote implementation-defined entry points. This includes declareDefault, lessee reassignment, the termination operations and updateServicing. This standard constrains their preconditions and observable effects, not their signatures, so they are not part of any interface or identifier defined here.

Operation Active InArrears InDefault Terminal
pay ✓ ✓ ✓ ✗
declareDefault ✓ ✓ ✗ ✗
lessee reassignment ✓ ✓ see below ✗
propose / accept termination ✓ ✓ ✓ ✗
terminate for default ✗ ✗ ✓ ✗
exercisePurchaseOption ✗ ✗ ✗ only from Completed
updateServicing ✓ ✓ ✓ ✓

updateServicing remains available on terminated leases because servicing attestations report observed facts and do not alter lease state.

For an indexed lease, declareDefault, terminate for default and release of the asset upon default before termination are also subject to the preconditions in Payment-path liveness.

Whether lessee reassignment is permitted while a lease is InDefault is a commercial policy rather than an interoperability concern. Implementations MAY permit or forbid it, and SHOULD document which they do.

Early termination

A lease MAY terminate before its schedule completes. The standard defines when a lease may reach Terminated and requires the reason to be observable; it does not define how any remaining obligation is settled.

Termination reasons are domain-separated identifiers:

bytes32 constant TERMINATION_MUTUAL_AGREEMENT = keccak256("erc8348.termination.mutualAgreement");
bytes32 constant TERMINATION_DEFAULT          = keccak256("erc8348.termination.default");
  • Termination by mutual agreement MUST require affirmative action from both the lessee and the holder of the lessor position — a propose/accept sequence or an equivalent mechanism. It MAY be initiated from any non-terminal status.
  • Termination for default MUST require the lease to be in InDefault and MUST NOT take effect before a configurable delay has elapsed since the declaration. That delay MUST be greater than zero: a zero value admits several reasonable readings and MUST be rejected at origination rather than assigned a default meaning.
  • A transition to Terminated MUST emit both LeaseTerminated and TerminationRecorded, the latter carrying the reason. Implementations MAY define additional reasons under their own domain without changing this interface.
  • Economic quantities reported for a terminated lease — outstanding balance, arrears, penalties — MUST NOT change after termination. The standard does not prescribe how an implementation achieves this.
  • This specification deliberately leaves post-termination settlement out of scope: what is owed after early termination depends on the agreement, the jurisdiction and the product, and normalizing it would impose commercial policy rather than define an interface. Consequently no state-changing payment operation is defined once a lease is terminal, and implementations requiring on-chain settlement SHOULD define it as an extension with its own semantics.

Optional extension: anchored leases

Where a lease is written over a titled asset recorded in an ERC-8325 registry, implementations MAY expose the binding explicitly rather than encoding it in the assetReference string. This avoids cross-registry ambiguity: an anchor identifier alone is insufficient without the registry it lives in and the chain that registry is deployed on.

interface IFinancialLeaseAnchored {
    /// @return chainId    EIP-155 chain ID of the registry
    /// @return registry   ERC-8325 registry address
    /// @return anchorId   anchor identifier within that registry
    function assetAnchor(uint256 leaseId) external view returns (
        uint256 chainId, address registry, bytes32 anchorId);
}
  • A lease MAY be unanchored, in which case assetAnchor returns zero values.
  • The tuple MUST be all-zero or fully populated. A partially zeroed tuple — a nonzero anchorId with a zero registry, for instance — MUST be invalid, since it leaves consumers to define their own handling of an ambiguous reference.
  • leaseId remains the lease layer’s own identifier; this extension expresses a relationship to the asset layer, it does not replace the lease identifier with the anchor identifier. The two objects have distinct lifecycles.
  • Implementations of this extension MUST return true from supportsInterface for 0x09fce36a.

Input freshness

A lease depends on inputs with independent freshness characteristics. The reference-index observation used to convert an indexed schedule has one timestamp; off-chain servicing data (reconciled collections, manually recorded arrears, insurance status, asset condition, residual-value appraisals) has others. A consumer composing a lease-portfolio NAV cannot treat a freshly published NAV as fresh if it incorporates an economically old input.

Implementations MUST expose per-input freshness through inputFreshness, a single parameterized view declared in the core interface. It returns observedAt (when the datum was observed off-chain), reportedAt (when it was recorded on-chain) and maxStaleness (the tolerance declared for that input, 0 if none is declared). This view reports; it does not enforce. A consumer decides what staleness is acceptable for its purpose. The enforcement based on the index tolerance is specified separately, in Payment-path liveness.

/// Base input identifiers, domain-separated. Implementations MAY define
/// additional identifiers under their own domain.
bytes32 constant INPUT_INDEX_OBSERVATION  = keccak256("erc8348.input.indexObservation");
bytes32 constant INPUT_COLLECTIONS        = keccak256("erc8348.input.collections");
bytes32 constant INPUT_ARREARS_RECORD     = keccak256("erc8348.input.arrearsRecord");
bytes32 constant INPUT_INSURANCE_STATUS   = keccak256("erc8348.input.insuranceStatus");
bytes32 constant INPUT_ASSET_CONDITION    = keccak256("erc8348.input.assetCondition");
bytes32 constant INPUT_RESIDUAL_APPRAISAL = keccak256("erc8348.input.residualAppraisal");
  • Implementations MUST expose both timestamps. Observation time is what a valuation consumer needs to judge how economically old an input is; report time is what accountability needs to know when the chain learned of it. Reporting only one loses information the other layer may require.
  • INPUT_INDEX_OBSERVATION is not a stored attestation: its timestamps MUST be derived from conversionRateAsOf, and its maxStaleness reflects the oracle tolerance already governing conversion. It is the only input whose staleness can revert a state-changing call: pay and exercisePurchaseOption MAY revert because conversion requires it, and default actions MUST revert under Payment-path liveness.
  • The remaining inputs are attestations maintained off-chain and surfaced on-chain by an authorized servicer. Updating them MUST NOT affect lease state: outstanding balance, status, and arrears are computed independently of servicing freshness. Servicing staleness is observable, never enforced. Recording an attestation MUST emit ServicingUpdated, and MUST be rejected for INPUT_INDEX_OBSERVATION.
  • An implementation MUST reject an observedAt in the future. It MUST NOT reject an old one: how old is too old is the consumer’s judgement, not the standard’s.
  • maxStaleness MUST be set as lease configuration, not by the servicer supplying the attestation. A servicer declaring the tolerance applied to its own attestations is self-assessment.
  • Querying an input that has never been attested MUST return zero values rather than reverting: never reported is itself information.
  • Input identifiers are domain-separated bytes32 values rather than a closed enumeration, so that lease structures with inputs beyond the base set extend without an interface change. The base identifiers above are defined by this standard and MUST have the values given, so the common set does not fragment across implementations.

Payment-path liveness

An indexed lease cannot be paid while its index observation is stale, because conversion requires it. The rules in this section keep a lease from reaching default only because its payment path was unavailable. They apply to a lease that declares a tolerance for INPUT_INDEX_OBSERVATION, that is, a non-zero maxStaleness in inputFreshness. A lease with no declared tolerance never treats its index as stale, and a fixed-denomination lease has no index.

In this section, default actions are default declaration, termination for default, and, in the asset-bound extension, release of the asset to the lessor upon default while the lease is not terminal. Once a lease has been terminated for default, releasing the asset follows the terms of that termination and is not a default action: the lessee can no longer pay, so the payment path no longer bears on it.

The index is stale at an instant when the time elapsed since the observation time of the observation then in force exceeds maxStaleness. An interval during which the observation in force could not be used for conversion, such as a non-positive rate, also counts as stale; an earlier usable observation that is still within tolerance does not cover it.

  • Default actions MUST NOT succeed while the index is stale.
  • Default actions MUST NOT succeed unless the index has been continuously non-stale throughout a recovery grace period of G seconds ending at the current block, with 0 < G < maxStaleness. Implementations MUST document G.
  • Whether the index was continuously non-stale MUST be determined from data verifiable on-chain. Which observation was in force at each instant follows from when it took effect on-chain: the update time of each round for a Chainlink-style feed, or the on-chain recording time for an attested index. It MUST NOT depend on a timestamp supplied by the party taking the default action.
  • An unusable observation recorded in the oracle’s history MUST be treated as stale for as long as it was in force. Failures that the history does not record, such as a change in the oracle’s configuration that is later reverted, can only be detected at the current block; implementations SHOULD document which failures their history records.
  • If an implementation allows the oracle or index of a lease to be replaced, history predating the moment the replacement became effective for that lease MUST NOT count toward the grace period.
  • An implementation that cannot establish that the index was continuously non-stale for the whole grace period, for example because the available history does not reach back far enough, MUST treat the precondition as not met.
  • An attested observation SHOULD be recorded on-chain no later than maxStaleness - G after its observation time. A later recording leaves less than G before the observation goes stale, and the grace period may not complete.
  • These rules restrict default actions only. Arrears and penalties continue to accrue as specified above during an outage and during the grace period; whether penalties accrued while the lease could not be paid are waived is left to the agreement.
  • Implementations SHOULD settle payments so that a payment recipient blocked by the payment asset’s issuer cannot prevent payment, for example by crediting the holder of the lessor position and letting it withdraw separately.
  • Implementations MAY let the lessee tender payment while the payment path is unavailable, as an extension. A tender MUST expire after a timeout fixed in the lease configuration, so that it cannot suspend default actions indefinitely.
  • The tolerance declared for the index SHOULD exceed the oracle’s expected update interval by a margin. A tolerance at or below that interval makes ordinary update cadence count as an outage.

Optional extension: asset-bound leases

Contracts implementing this extension MUST hold the bound asset token in escrow while status is Active, InArrears or InDefault.

interface IFinancialLeaseAssetBound {
    enum AssetStandard { ERC721, ERC1155, ERC20 }

    function boundAsset(uint256 leaseId) external view returns (
        address token, uint256 tokenId, uint256 amount, AssetStandard std);
    function canSettleAsset(uint256 leaseId, address to)
        external view returns (bool);

    event AssetEscrowed(uint256 indexed leaseId, address token, uint256 tokenId);
    event AssetSettled(uint256 indexed leaseId, address indexed to);
    event AssetReleased(uint256 indexed leaseId, address indexed to);
}
  • On exercisePurchaseOption, if canSettleAsset(id, lessee) is true, settlement MUST be atomic with payment. If false, the option exercise MUST still be recorded and the asset MUST remain claimable by the lessee once the underlying token’s transfer restrictions allow it.
  • Release of the asset to the lessor upon default MUST NOT be an automatic consequence of InDefault. It MUST require an explicit call by an authorized role and SHOULD be subject to a configurable timelock, reflecting jurisdictional repossession requirements.
  • If the bound asset implements ERC-4907, the implementation SHOULD set the lessee as user for the duration of the lease.

Interface identifiers

The ERC-165 identifiers for this standard are:

Interface Identifier
IFinancialLease 0xf6b0f493
IFinancialLeaseAssetBound 0xf71550a8
IFinancialLeaseAnchored 0x09fce36a

Each identifier is the XOR of the function selectors declared in that interface alone; inherited and extension functions are not included. Implementation-defined entry points are not included. An implementation MUST return true from supportsInterface for 0xf6b0f493, and MUST return true for the identifier of each optional extension it implements.

Rationale

Units of account follow the ERC-4626 share/asset separation: indexed leases are first-class citizens rather than a special case, which is essential in the jurisdictions where leasing volume is concentrated in Latin America. A fixed-rate lease is the degenerate case with identity conversion.

Lessor-position-as-NFT makes portfolio assignment and securitization free: existing ERC-721 marketplaces, custody and vault tooling work unchanged, with compliance enforced in the transfer hook rather than in this interface.

Two-tier delinquency (InArrears vs InDefault) separates the objectively computable fact of a missed payment from the legally significant declaration of default, which in many jurisdictions requires notice or grace periods. The standard records both without opining on local law.

Payment imputation is unspecified (penalties vs interest vs principal) because ordering rules differ by jurisdiction and are sometimes mandatory law. PaymentReceived exposes enough data for indexers to reconstruct any imputation.

Observation rather than modelling. A complete taxonomy of financial instruments — the approach taken by ACTUS — describes what a contract is with enough fidelity to compute its cash flows from first principles. That fidelity has a cost: an integrator must adopt the taxonomy to read anything. This standard takes the opposite trade: it says nothing about how obligations are computed and only defines how the result is observed, so that a marketplace or credit scorer can read a lease without adopting a modelling framework.

Accrual is defined by elapsed time, not by transaction history. An implementation that accrues penalties by repeatedly applying a periodic rate to a running balance produces different totals depending on how often the contract happens to be touched — and since payment entry points are typically permissionless, the party that benefits from a higher figure can also produce it at no cost. Requiring the reported figure to be a function of the schedule and elapsed time removes that possibility without prescribing whether interest is simple or compound.

Default requires a payable lease. Blocking default only while the index is stale is not enough: when the index recovers, the declarer can act in the same block, before the lessee’s payment lands. The recovery grace closes that race. Bounding it below the staleness tolerance keeps the delay finite. When observations take effect on-chain at their observation time, as round updates do, the index stays non-stale for maxStaleness seconds after any recovery unless a further outage begins. With G < maxStaleness every grace period then completes, and each outage that ends delays default by at most its own length plus G; the recording bound for attested observations preserves this. A grace longer than the tolerance could instead be extended indefinitely by observations that each arrive just after the previous one expires. Measuring the grace from the oracle’s own history, rather than from a recovery timestamp recorded by a caller, means no party can shorten it.

Authority over the lessee position is separated from other roles. A role granted for one purpose — declaring default, servicing a portfolio, holding the lessor position — does not thereby acquire authority over who receives the purchase option. Conflating them creates a conflict of interest whenever the role holder benefits from a reassignment, and the party best positioned to exploit it is often the one the role defaults to.

Backwards Compatibility

The standard composes with, and does not modify, ERC-20, ERC-721, ERC-165, ERC-4907 and ERC-8325.

Security Considerations

  • Oracle manipulation and staleness: conversion oracles are the main attack surface for indexed leases. Implementations MUST document their oracle source, update cadence and staleness policy, and SHOULD revert state changes on stale data.
  • Payment-path liveness: when a dependency of the payment path fails (a stale index observation, a paused payment asset, or a payment recipient blocked by the asset issuer), pay() cannot succeed while delinquency keeps accruing. Payment-path liveness makes default actions unavailable while the index is stale and for a bounded grace period after it recovers, and recommends a settlement design that a blocked recipient cannot obstruct. A paused payment asset remains a residual risk: while the asset is paused no settlement design lets the lessee pay, and the pause is controlled by the asset issuer rather than by either party. Implementations SHOULD document how default actions behave while the payment asset is paused. Each outage of the index restarts the grace period, so an index that fails repeatedly delays default repeatedly. This standard does not define a cap on the cumulative grace per installment, since a cap would let a default action succeed within a grace period.
  • Index that does not recover: the liveness rules protect the lessee at the cost of the lessor when the index stops for good, for example when a feed is retired, or when the implementation cannot establish freshness from the available history (a phase change in the feed, or more updates within the grace period than the implementation can examine). Default actions then stay unavailable until freshness can be established again, and mutual termination remains the only exit. Implementations SHOULD document how an indexed lease can be moved to a replacement index, and under whose authority; that authority is critical, since it affects both the amounts owed and when default becomes available. Implementations SHOULD also document any limit on the history they can examine. The rules are only as reliable as the oracle’s account of its own history: a lessee that accepts an oracle at origination trusts its history as it trusts its rate.
  • Rounding: directional rounding rules above prevent dust-extraction attacks analogous to ERC-4626 inflation attacks.
  • Penalty conflation: implementations that mix penalty stock with schedule principal in a single accumulator risk crediting penalty payments against principal. Penalties MUST be tracked separately.
  • Compliance-gated settlement: exercisePurchaseOption may be unable to deliver a compliance-restricted asset; recording the exercise while deferring delivery prevents loss of an acquired right.
  • Repossession: the escrow mechanism makes repossession technically trivial; the timelock and role requirements exist so that on-chain capability does not outrun legal authority.
  • Legal enforceability: agreementHash binds the on-chain state to an off-chain agreement, but enforceability of the token as title or receivable depends on each jurisdiction’s legal wrapper. This standard makes jurisdiction observable; it does not create legal effect.
  • Servicing attestations: inputFreshness for off-chain categories reflects what an authorized servicer has attested, not independently verified truth. A stale or dishonest servicer degrades the freshness signal but cannot alter lease state, since servicing data is isolated from balance and status computation. Consumers relying on servicing freshness SHOULD treat the servicer as a trusted party and weight the signal accordingly.
  • Frequency-dependent accrual: an implementation whose arrears figure depends on how often accrual state was persisted can be manipulated by any party able to call the contract, including the lessor at no net cost. Conformance suites SHOULD include a differential test comparing a single end-of-period accrual against repeated intermediate accruals over the same elapsed time.
  • Role conflation: implementations SHOULD treat authority to change who receives the purchase option as access-control critical. Conformance suites SHOULD assert that no address other than the current lessee can change the lessee of record without an explicitly and separately granted authority.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Javier Mateos (@javierpmateos), "ERC-8348: Financial Lease [DRAFT]," Ethereum Improvement Proposals, no. 8348, July 2026. Available: https://eips.ethereum.org/EIPS/eip-8348.