Bonds

Overview

The Fabriq bonding system presents a novel mechanic for interchain lending. It's flexibility makes it suitable for a number of use-cases.

From a bond issuer’s perspective, bonds support a variety of use-cases including:

  • Cross-chain collateralized liquidity (cross-chain flashloan)

  • Short-, medium- or long-duration interchain debt notes

  • Constructing short positions

From a bond underwriter’s perspective, bonds provide:

  • A low-risk profit-sharing instrument for satisfying retail orderflow

  • A mechanism for additional interest-based yields for assets held long

  • A mechanism for porfolio or interchain liquidity rebalancing

Issuing Bonds

A bond begins with tendering and issuance. A bond issuer has an opportunity they would like to gain liquidity to access.


const walletClient: WalletClient = createWalletClient({
	account: privateKeyToAccount(privateKey),
	chain: sei,
	transport: http(),
});

const tokensOp = await getTokensByChainID(optimism.id);

const tokensSei = await getTokensByChainID(sei.id);
const seiInfo = await getSupportedChainByID(sei.id);

const intentClient = new IntentClient(walletClient, intentPoolURL, seiInfo);

await intentClient.approvePermit2(tokensSei.Ceres);

const inAmount = parseUnits('1.98', 18);
const outAmount = parseUnits('1.99', 18);

const input = createItem(testToken, inAmount, inAmount, sei.id)
const output = createItem(testToken, outAmount, outAmount, optimism.id);

const bondId = await intentClient.submitBondIntent(input, output);

The status of a bond can be checked by:

const bond = intentClient.getBondIntent(bondId);
console.log(bond.status);
// `pending`, `registered`, `finalized` or `expired`

Discovering Bonds

From the perspective of a counterparty who is providing liquidity in some way, the process of interacting with bonds starts with discovery.

We can retrieve bond details, including:

  • Collateral type and amount

  • Maturity period

  • Expected yield (Solver margin split)

  • Bond status

Subsequently, counterparties can use internal risk filters to analyze bond preference based on collateral quality, expected yield, and duration.

To discover outstanding/un-issued bonds:

const currentBonds = await intentPool.queryBonds();

Bonds can be filtered similarly to Swaps with the SDK:

filter = { destinationChains: [/* ... */], destinationTokens: [ /* ... */ ] };

const currentBonds = await intentPool.queryBonds(filter);

Acquiring Bonds

Once a counterparty has discovered a bond to purchase, the counterparty registers the bond, much like a SwapIntent, and then provides the requested liquidity through the bond. Providing the liquidity can be don

const desirableBonds = selectBonds(currentBonds);
const exampleBond = desirableBonds[0];

intentPool.fillBond(exampleBond);

Using Bond Liquidity

Once a bond has been purchased, making use of bond liquidity can be done through an SDK provided interface, Bond. Bond provides a means of taking funds from the bond and putting them to use:

exampleBond.withdraw(destinationAddress, destinationAmt);

This will execute a transaction from within the Bond contract on-chain. Support for more complicated transactions in the SDK

Selling Issued Bonds

[note: this is slated for the upcoming release, Ganymede]

Bonds can be sold if liquidity is preferable. The bondholder can make use of this by issuing a Swap with the input being the bond. It’s an ERC721 that can be exchanged with the same mechanics as a Swap for ERC20 tokens, though it can only be priced over the output asset.

// pricing info

const privateKey = /* ... */;

const walletClient: WalletClient = createWalletClient({
	account: privateKeyToAccount(privateKey),
	transport: http(),
});

const tokensEth = await getTokensByChainID(ethereum.id);

const intentClient = new IntentClient(walletClient, intentPoolURL, optimismInfo);

const outAmount = parseUnits('198.43', 18);
const output = createItem(tokensEth.USDC, outAmount, outAmount, sei.id)

intentClient.submitSwapBondIntent(inputBond, output);

Last updated