@indigo-labs/indigo-sdk
Version:
Indigo SDK for interacting with Indigo endpoints via lucid-evolution
221 lines (197 loc) • 5.13 kB
text/typescript
import { AssetClass } from '@3rd-eye-labs/cardano-offchain-common';
import {
LucidEvolution,
TxBuilder,
unixTimeToSlot,
} from '@lucid-evolution/lucid';
import {
addrDetails,
requestSpAccountAdjustment,
bigintMax,
requestSpAccountClosure,
createE2s2sSnapshots,
requestSpAccountCreation,
fromSystemParamsAsset,
openCdp,
processSpRequest,
SystemParams,
} from '../../src';
import {
findAllNecessaryOrefs,
findPriceOracleFromCollateralAsset,
} from '../cdp/cdp-queries';
import {
findE2s2sSnapshots,
findStabilityPool,
findStabilityPoolAccount,
} from '../queries/stability-pool-queries';
import { LucidContext, runAndAwaitTx } from '../test-helpers';
import { expect } from 'vitest';
import { findIAsset } from '../queries/iasset-queries';
import {
rationalCeil,
rationalDiv,
rationalFromInt,
rationalMul,
rationalSub,
} from '../../src/types/rational';
export async function runOpenCdpAndCreateSPAccount(
context: LucidContext,
sysParams: SystemParams,
asset: string,
/**
* The collateral asset to back the borrowed iAssets that will be used for stability pool deposit.
*/
collateralAsset: AssetClass,
spDepositAmount: bigint,
): Promise<TxBuilder> {
const orefs = await findAllNecessaryOrefs(
context.lucid,
sysParams,
asset,
collateralAsset,
);
const priceOracleUtxo = await findPriceOracleFromCollateralAsset(
context.lucid,
orefs.collateralAsset,
);
const collateral = bigintMax(
orefs.collateralAsset.datum.minCollateralAmt,
// collateralisation should be maintenance ratio * 2
rationalCeil(
rationalMul(
rationalFromInt(2n * spDepositAmount),
orefs.collateralAsset.datum.maintenanceRatio,
),
),
);
// Mint enough to match the intended SP deposit after paying debt minting fees.
const mintAmount = rationalCeil(
rationalDiv(
rationalFromInt(spDepositAmount),
rationalSub(rationalFromInt(1n), orefs.iasset.datum.debtMintingFeeRatio),
),
);
await runAndAwaitTx(
context.lucid,
openCdp(
collateral,
BigInt(mintAmount),
sysParams,
orefs.cdpCreatorUtxo,
orefs.iasset.utxo,
orefs.collateralAsset.utxo,
priceOracleUtxo,
orefs.interestOracleUtxo,
orefs.treasuryUtxo,
context.lucid,
context.emulator.slot,
),
);
return requestSpAccountCreation(
asset,
spDepositAmount,
sysParams,
context.lucid,
);
}
async function waitForAccountCooldown(
context: LucidContext,
sysParams: SystemParams,
asset: string,
// Request owner
pkh: string,
) {
const accountUtxo = await findStabilityPoolAccount(
context.lucid,
sysParams,
pkh,
asset,
);
if (accountUtxo.datum.lastRequestProcessingTime !== 0n) {
const targetSlot = unixTimeToSlot(
context.lucid.config().network!,
Number(accountUtxo.datum.lastRequestProcessingTime) +
sysParams.stabilityPoolParams.accountProcessingCooldownMs,
);
if (targetSlot > context.emulator.slot) {
expect(targetSlot).toBeGreaterThan(context.emulator.slot);
context.emulator.awaitSlot(targetSlot - context.emulator.slot + 2);
}
}
}
export async function runProcessSpRequest(
context: LucidContext,
sysParams: SystemParams,
asset: string,
// Request owner
pkh: string,
): Promise<TxBuilder> {
const sp = await findStabilityPool(context.lucid, sysParams, asset);
const ia = await findIAsset(
context.lucid,
sysParams.validatorHashes.iassetHash,
fromSystemParamsAsset(sysParams.cdpParams.iAssetAuthToken),
asset,
);
const accountUtxo = await findStabilityPoolAccount(
context.lucid,
sysParams,
pkh,
asset,
);
await waitForAccountCooldown(context, sysParams, asset, pkh);
return processSpRequest(
sp.utxo,
accountUtxo.utxo,
ia.utxo,
(await findE2s2sSnapshots(context.lucid, sysParams, asset)).map(
(res) => res.utxo,
),
sysParams,
context.lucid,
context.emulator.slot,
);
}
export async function runCreateAdjustRequest(
lucid: LucidEvolution,
sysParams: SystemParams,
asset: string,
adjustment: bigint,
): Promise<TxBuilder> {
const [pkh, _] = await addrDetails(lucid);
const accountUtxo = await findStabilityPoolAccount(
lucid,
sysParams,
pkh.hash,
asset,
);
return requestSpAccountAdjustment(
adjustment,
accountUtxo.utxo,
sysParams,
lucid,
);
}
export async function runCreateCloseRequest(
lucid: LucidEvolution,
sysParams: SystemParams,
asset: string,
): Promise<TxBuilder> {
const [pkh, _] = await addrDetails(lucid);
const accountUtxo = await findStabilityPoolAccount(
lucid,
sysParams,
pkh.hash,
asset,
);
return requestSpAccountClosure(accountUtxo.utxo, sysParams, lucid);
}
export async function runCreateE2s2sSnapshots(
context: LucidContext,
sysParams: SystemParams,
asset: string,
): Promise<TxBuilder> {
const spUtxo = await findStabilityPool(context.lucid, sysParams, asset);
return createE2s2sSnapshots(spUtxo.utxo, sysParams, context.lucid);
}