@agoric/zoe
Version:
Zoe: the Smart Contract Framework for Offer Enforcement
106 lines (95 loc) • 3.81 kB
JavaScript
import { Nat } from '@endo/nat';
import {
assertIssuerKeywords,
makeRatio,
} from '../../contractSupport/index.js';
import { makeLendInvitation } from './lend.js';
/**
* @import {PriceAuthority, PriceDescription, PriceQuote, PriceQuoteValue, PriceQuery,} from '@agoric/zoe/tools/types.js';
*/
/**
* Add collateral of a particular brand and get a loan of another
* brand. Collateral (also known as margin) must be greater than the
* loan value, at an amount set by the Maintenance Margin Requirement
* (mmr) in the terms of the contract. The loan does not have a
* distinct end time. Rather, if the value of the collateral changes
* such that insufficient margin is provided, the collateral is
* liquidated, and the loan is closed. At any time, the borrower can
* add collateral or repay the loan with interest, closing the loan.
* The borrower can set up their own margin calls by getting the
* `priceAuthority` from the terms and calling
* `E(priceAuthority).quoteWhenLT(allCollateral, x)` where x is the
* value of the collateral in the Loan brand at which they want a
* reminder to addCollateral.
*
* Note that all collateral must be of the same brand and all of the
* loaned amount and interest must be of the same (separate) brand.
*
* Terms:
* * mmr (default = 150/100) - the Maintenance Margin Requirement, as a
* ratio. The default is 150/100, meaning that collateral should be
* worth at least 150% of the loan. If the value of the collateral
* drops below mmr, liquidation occurs.
* * priceAuthority - will be used for getting the current value of
* collateral and setting liquidation triggers.
* * autoswapInstance - The running contract instance for an Autoswap
* installation. The publicFacet of the
* instance is used for producing an invitation to sell the
* collateral on liquidation.
* * periodNotifier - the Notifier that provides notifications that
* periods have passed, on which compound interest will be
* calculated using the interestRate. Notifiers don't guarantee
* that clients will see all the changes, so the contract must
* track when interest last accrued.
* * interestRate - the rate in basis points that will be multiplied
* with the debt on every period to compound interest.
* * interestPeriod - the period at which interest compounds.
*
* IssuerKeywordRecord:
* * Keyword: 'Collateral' - The issuer for the digital assets to be
* escrowed as collateral.
* * Keyword: 'Loan' - The issuer for the digital assets to be loaned
* out.
*
* @param {ZCF<{
* mmr: Ratio,
* autoswapInstance: Instance,
* priceAuthority: PriceAuthority,
* periodNotifier: PeriodNotifier,
* interestRate: Ratio,
* interestPeriod: bigint,
* }>} zcf
*/
const start = async zcf => {
assertIssuerKeywords(zcf, harden(['Collateral', 'Loan']));
// Rather than grabbing the terms each time we use them, let's set
// some defaults and add them to a contract-wide config.
const {
autoswapInstance,
priceAuthority,
periodNotifier,
interestRate,
interestPeriod,
brands: { Loan: loanBrand, Collateral: collateralBrand },
mmr = makeRatio(150n, loanBrand), // Maintenance Margin Requirement
} = zcf.getTerms();
assert(autoswapInstance, 'autoswapInstance must be provided');
assert(priceAuthority, 'priceAuthority must be provided');
assert(periodNotifier, 'periodNotifier must be provided');
Nat(interestPeriod);
/** @type {LoanTerms} */
const config = {
mmr,
autoswapInstance,
priceAuthority,
periodNotifier,
interestRate,
interestPeriod,
loanBrand,
collateralBrand,
};
const creatorInvitation = makeLendInvitation(zcf, harden(config));
return { creatorInvitation };
};
harden(start);
export { start };