---
eip: 6123
title: Smart Derivative Contract
description: A deterministic protocol for frictionless trade processing of financial contracts
author: Christian Fries (@cfries), Peter Kohl-Landgraf (@pekola), Alexandros Korpis (@kourouta)
discussions-to: https://ethereum-magicians.org/t/eip-6123-smart-derivative-contract-frictionless-processing-of-financial-derivatives/12134
status: Draft
type: Standards Track
category: ERC
created: 2022-12-13
---

## Abstract

The Smart Derivative Contract (SDC) allows fully automizing and securing a financial product's - e.g. a financial derivative or bond - complete trade life cycle.[^1]
The SDC leverages the advantages of smart contracts to remove many of the frictions associated with the classical derivative life cycle. Most notably, the protocol allows the removal of counterpart risk essentially.
The SDC can be implemented using a pre-agreed valuation oracle and valuation model, removing ambiguity in the settlement amounts. The SDC provides methods and callbacks to enable fully automated and fully transactional settlements (delivery-versus-payment, payment-vs-payment).
Token-based settlement can be realized by any contract implementation implementing an [ERC-20](./eip-20.md) token.
Proof of concepts in terms of two legally binding digital Interest Rate Swaps were conducted in 2021 and 2022.

## Motivation

### Rethinking Financial Derivatives

By their very nature, so-called "over-the-counter (OTC)" financial contracts are bilateral contractual agreements on exchanging long-dated cash flow schedules.
Since these contracts change their intrinsic market value due to changing market environments, they are subject to counterparty credit risk when one counterparty is subject to default.
The initial white paper describes the concept of a Smart Derivative Contract (SDC) with the central aim to detach bilateral financial transactions from counterparty credit risk and to remove complexities
in bilateral post-trade processing by a complete redesign.

### Concept of a Smart Derivative Contract

A Smart Derivative Contract is a deterministic settlement protocol with the same economic behaviour as a Financial Contract - e.g. an OTC-Derivative or a Bond.
Every process state is specified; therefore, the trade and post-trade process is known in advance and is deterministic over the trade's life cycle. An [ERC-20](./eip-20.md) token can be used for frictionless decentralized settlement, see reference implementation. We do provide a separate interface and implementation for a specific "Settlement Token" derived from [ERC-20](./eip-20.md).
These features enable two or multiple trade parties to process their financial contracts fully decentralized without relying on a third central intermediary agent.
The process logic of SDC can be implemented as a finite state machine on solidity.

### Applications

The interface's life cycle functionality applies to several use cases.

#### Settle-to-Market OTC Derivative

In the case of a settle-to-market OTC derivative, an SDC settles the outstanding net present value of the underlying financial contract on a frequent (e.g. daily) basis. With each settlement cycle, the net present value of the underlying contract is exchanged, and the value of the contract is reset to zero. Pre-agreed margin buffers are locked at the beginning of each settlement cycle so that settlement will be guaranteed up to a certain amount.
If a counterparty fails to obey contract rules, e.g. not providing sufficient pre-funding, SDC will terminate automatically with the guaranteed transfer of a termination fee by the causing party.
We provide a reference implementation for this case.

#### Callateralized OTC Derivative

An implementation variante of the protocol can be used to realize a collateralized OTC derivative.[^2]
Here the contract manages separate collateral and cash tokens.
The constructions allows to eliminate the risk of under-collateralization.
Thus, a separate initial margin is not required.

#### Defaultable OTC Derivative

A defaultable OTC Derivative has no Collateral Process in place. In that case, a smart derivative will settle the according cash flows as determined in the derivative contract specification. A defaultable OTC derivative might end in
a state 'Failure to Pay' if a settlement cannot be conducted.

#### Smart Bond Contract

The life cycle of a bond can also make use of the function catalogue below. The interface enables the issuer to allocate and redeem the bond as well as settle coupon payments. On the other hand, it allows bondholders to interact with each other, conducting secondary market trades. It all boils down to a settlement phase, which needs to be pre-agreed by both parties or triggered by the issuer
which can be processed in a completely frictionless way.

## Specification

The methods and event are separated into different interfaces:

- `ISDCTrade` - events and functions related to trade inception, confirmation and termination.
- `ISDCSettlement` - events and functions related to the settlement life-cycle of a trade.
- `IAsyncTransferCallback` - events and the callback function `afterTransfer` for settlements that utilize and external payment system.
- `IAsyncTransfer` - events and functions related to async transfer (e.g., for external payment systems).

The `ISDC` interface is the aggregation of `ISDCTrade`, `ISDCSettlement` and `IAsyncTransferCallback`.

### Methods of `ISDCTrade`

The following methods specify a Smart Derivative Contract's trade initiation, trade termination and settlement life cycle. For further information, please also look at the interface documentation `ISDC.sol`.

#### Trade Initiation Phase: `inceptTrade`

A party can initiate a trade by providing the party address to trade with, trade data, trade position, payment amount for the trade and initial settlement data. Only registered counterparties are allowed to use that function.

```solidity
function inceptTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external returns (string memory);
```

The position and the paymentAmount are viewed from the incepter.
The function will return a generated unique `tradeId`. The trade id will also be emitted by an event.

#### Trade Initiation Phase: `confirmTrade`

A counterparty can confirm a trade by providing its trade specification data, which then gets matched against the data stored from `inceptTrade` call.

```solidity
function confirmTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external;
```

Here, the position and the paymentAmount is viewed from the confimer (opposite sign compared to the call to `inceptTrade`).

#### Trade Initiation Phase: `cancelTrade`

The counterparty that called `inceptTrade` has the option to cancel the trade, e.g., in the case where the trade is not confirmed in a timely manner.

```solidity
function cancelTrade(address withParty, string memory tradeData, int position, int256 paymentAmount, string memory initialSettlementData) external;
```

#### Trade Termination: `requestTermination`

Allows an eligible party to request a mutual termination of the trade with the corresponding `tradeId` with a termination amount she is willing to pay and provide further termination terms (e.g. an XML)

```solidity
function requestTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external;
```

#### Trade Termination: `confirmTradeTermination`

Allows an eligible party to confirm a previously requested (mutual) trade termination, including termination payment value and termination terms

```solidity
function confirmTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external;
```

#### Trade Termination: `cancelTradeTermination`

The party that initiated `requestTradeTermination` has the option to withdraw the request, e.g., in the case where the termination is not confirmed in a timely manner.

```solidity
function cancelTradeTermination(string memory tradeId, int256 terminationPayment, string memory terminationTerms) external;
```

### Methods of `ISDCSettlement`

#### Settlement Phase: `initiateSettlement`

Allows eligible participants (such as counterparties or a delegated agent) to trigger a settlement phase.

```solidity
function initiateSettlement() external;
```

#### Settlement Phase: `performSettlement`

Valuation may be provided on-chain or off-chain via an external oracle service that calculates the settlement or coupon amounts and uses external market data.
This method serves as a callback called from an external oracle providing settlement amount and used settlement data, which also get stored.
The settlement amount will be checked according to contract terms, resulting in either a regular settlement or a termination of the trade.

The method may perform a synchonous transfer of the settlement or make use of an `IAsyncTransfer`, which will finalize the
transfer though the callback `afterTransfer`.

The transactionData is emitted as part of the corresponding event: `SettlementTransferred` or `SettlementFailed`
This might result in a termination or start of the next settlement phase, depending on the provided success flag.

The parameter `settlementData` will be ussed as `lastSettlementData` as part of the `SettlementRequested` event (see there)
and may contain updates to the determination of the next settlement, e.g., data to determine the reference value for margining or
the specification of updated margin buffer values.

```solidity
function performSettlement(int256 settlementAmount, string memory settlementData) external;
```

#### Settlement Phase: `afterSettlement`

The method is called to verify and prepare the next settlement and move to that phase.
The method may trigger optional checks (e.g. pre-funding check).

Depending on the implementation, this method may be called automatically at the end of performSettlement
or called externally (e.g. from a time-oracle to allow for a time-period to prepare the next settlement).

- An implementation that uses adjusting of pre-funding can check the pre-funding within this method.
- An implementation that checked a static pre-funding upon confirmation of the trade might not require this step. 

In any case, the method may trigger termination if the settlement failed.

Emits a `SettlementTransferred` or a `SettlementFailed` event. May emit a `TradeTerminated` event.

```solidity
function afterSettlement() external;
```

### Methods of `IAsyncTransferCallback`

#### Settlement Phase: `afterTransfer`

This method is called back from a settlement token or from an eligible address if the transfer of the settlement
amount was successful. - completes the settlement transfer.
The transactionData is emitted as part of the corresponding event: `SettlementTransferred` or `SettlementFailed`
This might result in a termination or start of the next settlement phase, depending on the provided success flag.

```solidity
function afterTransfer(bool success, uint256 transactionID, string memory transactionData) external;
```

### Trade Events

The following events are emitted during an SDC Trade life-cycle.

#### TradeIncepted

Emitted on trade inception - method 'inceptTrade'

```solidity
event TradeIncepted(address initiator, string tradeId, string tradeData);
```

#### TradeConfirmed

Emitted on trade confirmation - method 'confirmTrade'

```solidity
event TradeConfirmed(address confirmer, string tradeId);
```

#### TradeCanceled

Emitted on trade cancellation - method 'cancelTrade'

```solidity
event TradeCanceled(address initiator, string tradeId);
```

#### TradeActivated

Emitted when a Trade is activated

```solidity
event TradeActivated(string tradeId);
```

#### TradeTerminationRequest

Emitted when termination request is initiated by a counterparty

```solidity
event TradeTerminationRequest(address initiator, string tradeId, int256 terminationPayment, string terminationTerms);
```

#### TradeTerminationConfirmed

Emitted when termination request is confirmed by a counterparty

```solidity
event TradeTerminationConfirmed(address confirmer, string tradeId, int256 terminationPayment, string terminationTerms);
```

#### TradeTerminationCanceled

Emitted when termination request is canceled by the requesting counterparty

```solidity
event TradeTerminationCanceled(address initiator, string tradeId, string terminationTerms);
```

#### TradeTerminated

Emitted when trade is terminated

```solidity
event TradeTerminated(string cause);
```


### Settlement Events

The following events are emitted during the settlement phases.

#### SettlementRequested

Emitted when a settlement is requested (via `initiateSettlement`). May trigger the settlement phase.

The argument `lastSettlementData` is the one that was passed upon a previous settlement
in `performSettlement` (under the name `settlementData`). It may be used to pass updated settlement
specific information calculated during the previous settlement, e.g., when margin buffer amounts are a function
of market parameters. In case of an external oracle it can pass the `settlementData` via `performSettlement`
and pick it up in the `SettlementRequested` event (allows for stateless external oracles).

```solidity
event SettlementRequested(address initiator, string tradeData, string lastSettlementData);
```

#### SettlementDetermined

Emitted when the settlement phase is started (via `performSettlement`).

```solidity
event SettlementDetermined(address initiator, int256 settlementAmount, string settlementData);
```

#### SettlementTransferred

Emitted when the settlement succeeded.

```solidity
event SettlementTransferred(string transactionData);
```

#### SettlementFailed

Emitted when the settlement failed.

```solidity
event SettlementFailed(string transactionData);
```


## Rationale

The interface design and reference implementation are based on the following considerations:

- An SDC protocol enables interacting parties to initiate and process a financial transaction in a bilateral and deterministic manner. Settlement and Counterparty Risk is managed by the contract.
- The provided interface specification is supposed to completely reflect the entire trade life cycle.
- The interface specification is generic enough to handle the case that parties process one or even multiple financial transactions (on a netted base)
- Usually, the valuation of financial trades (e.g. OTC Derivatives) will require advanced valuation methodology to determine the market value. This is why the concept might rely on an external market data source and hosted valuation algorithms
- A pull-based valuation-based oracle pattern can be implemented by using the provided callback pattern (methods: `initiateSettlement`, `performSettlement`)
- The reference implementation `SDCSingleTrade.sol` considers a single trade and is based on a state-machine pattern where the states also serve as guards (via modifiers) to check which method is allowed to be called at a particular given process and trade state
- The interface allows the extension to multiple trades with common (netted) settlement.

### State diagram of trade and process states

![image info](../assets/eip-6123/doc/sdc_trade_states.svg)

The diagram shows the trade states of a single trade SDC as in `SDCSingleTrade.sol`.

### Sequence diagram of reference implementation 'SDCPledgedBalance.sol'

The following sequence diagram shows the function calls that create the trade and stellement state transitions
and the emitted events.  Shown is the implementation variante that

- utilizes an asynchronous settlement through a settlement token (see the interface `IAsyncTransfer`, `IAsyncTransferCallback`)
- receives the trigger `afterSettlement` to perfrom checks of settlement pre-conditions (see the corresponding method description `afterSettlement`)

![image info](../assets/eip-6123/doc/sequence.svg)

### Sequence diagram of an implementation variant with a separate collateral account

The following sequence diagram shows the implementation variant with a separate collateral account.
This diagram show the settlement phase.

![image info](../assets/eip-6123/doc/sequence-sdc-collateral-settlement.svg)

## Test Cases

Life-cycle unit tests based on the sample implementation and usage of [ERC-20](./eip-20.md) token is provided. See file [test/SDCTests.js](../assets/eip-6123/test/SDCTests.js)
).

## Reference Implementation

An abstract contract class `SDCSingleTrade.sol` for single trade SDCs as well as a full reference implementation SDCPledgedBalance.sol for an OTC-Derivative is provided and is based on the [ERC-20](./eip-20.md) token standard.
See folder `/assets/contracts`, more explanation on the implementation is provided inline.

### Trade Data Specification (suggestion)

Please take a look at the provided xml file as a suggestion on how trade parameters could be stored.

## Security Considerations

No known security issues up to now.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).

[^1]:
```csl-json
    {
        "type": "article-journal",
        "id": "ssrn-3163074",
        "title": "Smart Derivative Contracts (Detaching Transactions from Counterparty Credit Risk: Specification, Parametrisation, Valuation)",
        "author": [
        { "family": "Fries", "given": "Christian P." },
        { "family": "Kohl-Landgraf", "given": "Peter" }
        ],
        "container-title": "SSRN Electronic Journal",
        "DOI": "10.2139/ssrn.3163074",
        "ISSN": "1556-5068",
        "URL": "https://ssrn.com/abstract=3163074",
        "issued": { "date-parts": [[2018, 4, 24]] },
        "original-date": { "date-parts": [[2018, 4, 15]] },
        "note": "Last revised: 2019-01-09",
        "number-of-pages": "22",
        "keyword": "Collateralization, CCP, Initial Margin, Smart Contract, Settlement Risk, Gap Risk",
        "language": "en",
        "source": "SSRN"
    }
```

[^2]:
```csl-json
    {
        "type": "article-journal",
        "id": "ssrn-5454714",
        "title": "A Smart Derivative Contract with Collateral",
        "author": [
        { "family": "Fries", "given": "Christian P." },
        { "family": "Kohl-Landgraf", "given": "Peter" },
        { "family": "Prandtl", "given": "Raphael" },
        { "family": "Schütte", "given": "Wilfried" }
        ],
        "container-title": "SSRN Electronic Journal",
        "DOI": "10.2139/ssrn.5454714",
        "ISSN": "1556-5068",
        "URL": "https://ssrn.com/abstract=5454714",
        "issued": { "date-parts": [[2025, 9, 8]] },
        "original-date": { "date-parts": [[2025, 8, 24]] },
        "note": "Last revised: 2025-09-25",
        "number-of-pages": "19",
        "keyword": "Smart Contract, Settlement, Collateralisation, ERC-6123, Counterparty Credit Risk, Repo",
        "language": "en",
        "source": "SSRN"
    }
```
