Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

indent-core

Clearing primitives for tokenized assets. Novation, multilateral netting, position limits, default waterfall.

tests node deps license


Venues find the price. Indent Layer makes the trade settle.

This package is the part of that you can read and run today. It has no dependencies, no network calls and no build step. Clone it and the tests execute on plain Node.

git clone https://github.com/IndentLayer/indent-core
cd indent-core
node --test "test/**/*.test.js"
node examples/window.js

Why this exists

To settle a trade atomically, both sides have to hold the full asset at the moment of the fill. Every open position therefore has cash frozen against it, and market size ends up bounded by how much capital participants are willing to leave idle rather than by demand.

Atomicity today is bought with idle money. These primitives are how that stops being true.


The number

Three members, one asset, one settlement window.

A owes B 300
B owes C 250
C owes A 200
A owes C 150
C owes B 100

Net position at window close: A −250, B +150, C +100.

gross 1,000   net 250   never moved 750   compression 75.0%

Nothing was cancelled. Every obligation still stands. They simply stopped settling one at a time.

That figure is not a claim in a deck. It is test/netting.test.js, and it runs in CI on every push. If the number on the website is ever wrong, this build goes red.


What is here

Module Does
src/netting.js Multilateral netting across a window, and the transfers that discharge it
src/waterfall.js Loss absorption in fixed layer order
src/limits.js Haircuts, collateral value, position limits
src/obligation.js The signed obligation type and its validation

Netting

import { net } from './src/netting.js';

const r = net([
  { from: 'A', to: 'B', amount: 300 },
  { from: 'B', to: 'C', amount: 250 },
  { from: 'C', to: 'A', amount: 200 },
]);

r.gross;        // 750
r.net;          // 250
r.compression;  // 0.666…
r.transfers;    // [{ from: 'A', to: 'C', amount: 100 }, …]

Bilateral netting cancels what two members owe each other and stops there. Multilateral netting cancels across every member at once, so compression rises with the number of members rather than with the number of pairs. A single venue can only net against itself, which is why this belongs one layer down.

The book must close at zero. If it does not, net() throws rather than settling something incoherent.

Default waterfall

import { absorb } from './src/waterfall.js';

absorb(400, {
  defaulterMargin: 100,
  defaulterFundContribution: 50,
  protocolInsurance: 200,
  mutualisedFund: 400,
});

Losses pass through five layers in a fixed order, and each must be exhausted before the next is touched:

  1. The defaulter's margin
  2. The defaulter's own default fund contribution
  3. The protocol insurance layer
  4. The mutualised fund of surviving members
  5. Auction of the residual position

Layer three is the one that matters. The protocol's own capital burns before any surviving member's does, and absorb() reports survivorsTouched so that property is asserted rather than promised.

Position limits

import { positionLimit, admits } from './src/limits.js';

const limit = positionLimit([{ amount: 1000, haircut: 0 }], 0.1); // 10000
admits(9000, 2000, limit); // false, rejected at submission

Collateral is valued below market, because the collateral itself can fall while a position is being closed out. A trade that would breach a limit is rejected when it is submitted, not unwound afterwards.

Obligations

import { DOMAIN, TYPES, encodeType, validate } from './src/obligation.js';

DOMAIN and TYPES are plain EIP-712 data, so any wallet library can sign against them. This package carries no signing dependency on purpose: the definition is the contract, and the choice of library is yours.


Where this sits

Stage Status
Primitives, open and tested this repository
Clearing contracts not deployed
Testnet not open
Mainnet not live

Nothing here talks to a chain yet. It is the logic that the contracts will enforce, published first so it can be read, argued with and corrected before anything holds value.

Network: Robinhood Chain, chain ID 4663.


Integration, when it opens

A venue needs a matching engine that produces a firm two-sided fill and the ability to collect a signature from each side. Nothing else. No custody changes, no margin posted, no credit risk taken on the trades it submits.


Related

indent-sdk Venue-side obligation building and lifecycle
indent-contracts The on-chain interfaces these primitives back
indentlayer.xyz/docs The model behind all of it

Contributing

Corrections to the mechanics are more welcome than features. If a property that should hold does not, open an issue with the window that breaks it, or a pull request with a failing test.

MIT licensed.

About

Clearing primitives for tokenized assets: novation, multilateral netting, margin and the default waterfall.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages