Skip to content

Commit

Permalink
feat!: make Treasury use ParamManagers for loan & fee parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris-Hibbert committed Jun 14, 2021
1 parent df28867 commit 5766e66
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 31 deletions.
1 change: 1 addition & 0 deletions packages/governance/src/exported.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './types';
1 change: 1 addition & 0 deletions packages/treasury/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@agoric/deploy-script-support": "^0.2.9",
"@agoric/ertp": "^0.11.2",
"@agoric/eventual-send": "^0.13.14",
"@agoric/governance": "^0.1.0",
"@agoric/marshal": "^0.4.11",
"@agoric/nat": "^4.0.0",
"@agoric/notifier": "^0.3.14",
Expand Down
13 changes: 13 additions & 0 deletions packages/treasury/src/paramKeys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @ts-check

export const POOL_FEE_KEY = 'poolFee';
export const PROTOCOL_FEE_KEY = 'protocolFee';

export const CHARGING_PERIOD_KEY = 'chargingPeriod';
export const RECORDING_PERIOD_KEY = 'recordingPeriod';

export const INITIAL_MARGIN_KEY = 'initialMargin';
export const LIQUIDATION_MARGIN_KEY = 'liquidationMargin';
export const INITIAL_PRICE_KEY = 'initialPrice';
export const INTEREST_RATE_KEY = 'interestRate';
export const LOAN_FEE_KEY = 'loanFee';
98 changes: 90 additions & 8 deletions packages/treasury/src/stablecoinMachine.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import '@agoric/zoe/exported';
import '@agoric/zoe/src/contracts/exported';
import '@agoric/governance/src/exported';

// The StableCoinMachine owns a number of VaultManagers, and a mint for the
// "RUN" stablecoin. This overarching SCM will hold ownershipTokens in the
Expand Down Expand Up @@ -32,10 +33,26 @@ import {
makeRatioFromAmounts,
} from '@agoric/zoe/src/contractSupport/ratio';
import { AmountMath } from '@agoric/ertp';
import {
buildParamManager,
ParamType,
} from '@agoric/governance/src/param-manager';

import { makeTracer } from './makeTracer';
import { makeVaultManager } from './vaultManager';
import { makeLiquidationStrategy } from './liquidateMinimum';
import { makeMakeCollectFeesInvitation } from './collectRewardFees';
import {
PROTOCOL_FEE_KEY,
POOL_FEE_KEY,
RECORDING_PERIOD_KEY,
CHARGING_PERIOD_KEY,
INITIAL_MARGIN_KEY,
LIQUIDATION_MARGIN_KEY,
INITIAL_PRICE_KEY,
INTEREST_RATE_KEY,
LOAN_FEE_KEY,
} from './paramKeys';

const trace = makeTracer('ST');

Expand Down Expand Up @@ -64,6 +81,22 @@ export async function start(zcf) {
)}) must be a BigInt`,
);

const {
publicFacet: paramManagerPublic,
manager: paramManager,
} = buildParamManager([
{
name: POOL_FEE_KEY,
value: loanParams.poolFee,
type: ParamType.BIGINT,
},
{
name: PROTOCOL_FEE_KEY,
value: loanParams.protocolFee,
type: ParamType.BIGINT,
},
]);

const [runMint, govMint] = await Promise.all([
zcf.makeZCFMint('RUN', undefined, harden({ decimalPlaces: 6 })),
zcf.makeZCFMint('Governance', undefined, harden({ decimalPlaces: 6 })),
Expand Down Expand Up @@ -114,11 +147,15 @@ export async function start(zcf) {
{ Central: runIssuer },
{
timer: timerService,
poolFee: loanParams.poolFee,
protocolFee: loanParams.protocolFee,
// TODO(hibbert): make the AMM use a paramManager. For now, the values
// are fixed after creation of an autoswap instance.
poolFee: paramManagerPublic.lookup(POOL_FEE_KEY),
protocolFee: paramManagerPublic.lookup(PROTOCOL_FEE_KEY),
},
);

const rateManagers = makeStore('brand'); // Brand -> rateManager

// We process only one offer per collateralType. They must tell us the
// dollar value of their collateral, and we create that many RUN.
// collateralKeyword = 'aEth'
Expand All @@ -131,6 +168,49 @@ export async function start(zcf) {
const collateralBrand = zcf.getBrandForIssuer(collateralIssuer);
assert(!collateralTypes.has(collateralBrand));

const {
publicFacet: rateManagerPublic,
manager: rateManager,
} = buildParamManager([
{
name: CHARGING_PERIOD_KEY,
value: loanParams.chargingPeriod,
type: ParamType.BIGINT,
},
{
name: RECORDING_PERIOD_KEY,
value: loanParams.recordingPeriod,
type: ParamType.BIGINT,
},
{
name: INITIAL_MARGIN_KEY,
value: rates.initialMargin,
type: ParamType.RATIO,
},
{
name: LIQUIDATION_MARGIN_KEY,
value: rates.liquidationMargin,
type: ParamType.RATIO,
},
{
name: INITIAL_PRICE_KEY,
value: rates.initialPrice,
type: ParamType.RATIO,
},
{
name: INTEREST_RATE_KEY,
value: rates.interestRate,
type: ParamType.RATIO,
},
{
name: LOAN_FEE_KEY,
value: rates.loanFee,
type: ParamType.RATIO,
},
]);
assert(!rateManagers.has(collateralBrand));
rateManagers.init(collateralBrand, rateManager);

const { creatorFacet: liquidationFacet } = await E(zoe).startInstance(
liquidationInstall,
{ RUN: runIssuer },
Expand All @@ -147,7 +227,8 @@ export async function start(zcf) {
want: { Governance: _govOut }, // ownership of the whole stablecoin machine
} = seat.getProposal();
assert(!collateralTypes.has(collateralBrand));
const runAmount = multiplyBy(collateralIn, rates.initialPrice);
const initialPrice = rateManagerPublic.lookup(INITIAL_PRICE_KEY);
const runAmount = multiplyBy(collateralIn, initialPrice);
// arbitrarily, give governance tokens equal to RUN tokens
const govAmount = AmountMath.make(runAmount.value, govBrand);

Expand Down Expand Up @@ -223,10 +304,10 @@ export async function start(zcf) {
runMint,
collateralBrand,
priceAuthority,
rates,
rateManagerPublic,
reallocateReward,
timerService,
loanParams,
paramManagerPublic,
liquidationStrategy,
);
collateralTypes.init(collateralBrand, vm);
Expand Down Expand Up @@ -318,8 +399,6 @@ export async function start(zcf) {
return getBootstrapPayment;
}

const getBootstrapPayment = mintBootstrapPayment();

const publicFacet = harden({
getAMM() {
return autoswapInstance;
Expand All @@ -331,6 +410,7 @@ export async function start(zcf) {
getRunIssuer() {
return runIssuer;
},
getParamManager: () => paramManagerPublic,
});

const { makeCollectFeesInvitation } = makeMakeCollectFeesInvitation(
Expand All @@ -348,8 +428,10 @@ export async function start(zcf) {
},
getCollaterals,
getRewardAllocation,
getBootstrapPayment,
getBootstrapPayment: mintBootstrapPayment(),
makeCollectFeesInvitation,
getParamManager: () => paramManager,
getRateManager: rateManagers.get,
});

return harden({ creatorFacet: stablecoinMachine, publicFacet });
Expand Down
21 changes: 17 additions & 4 deletions packages/treasury/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
* @property {(collateralIssuer: Issuer, collateralKeyword: Keyword, rates: Rates) => Promise<Invitation>} makeAddTypeInvitation
* @property {() => Instance} getAMM
* @property {() => Promise<Array<Collateral>>} getCollaterals
* @property {() => Payment} getBootstrapPayment
* @property {() => ParamManager} paramManager
* @property {() => ParamManager} getRateManager
*/

/**
Expand Down Expand Up @@ -65,6 +68,10 @@
* @property {() => Promise<PriceQuote>} getCollateralQuote
* @property {() => Ratio} getInitialMargin
* @property {() => Ratio} getInterestRate - The annual interest rate on a loan
* @property {() => RelativeTime} getChargingPeriod - The period (in seconds) at
* which interest is charged to the loan.
* @property {() => RelativeTime} getRecordingPeriod - The period (in seconds)
* at which interest is recorded to the loan.
* @property {ReallocateReward} reallocateReward
*/

Expand Down Expand Up @@ -113,6 +120,12 @@
* @property {RelativeTime} recordingPeriod
*/

/**
* @typedef {Object} AMMFees
* @property {bigint} poolFee
* @property {bigint} protocolFee
*/

/**
* @typedef {Object} LiquidationStrategy
* @property {() => KeywordKeywordRecord} keywordMapping
Expand All @@ -127,10 +140,10 @@
* @param {ZCFMint} runMint
* @param {Brand} collateralBrand
* @param {ERef<PriceAuthority>} priceAuthority
* @param {Rates} rates
* @param {StageReward} rewardPoolStaging
* @param {ParamManagerPublic} rateManager
* @param {ReallocateReward} reallocateReward
* @param {TimerService} timerService
* @param {LoanParams} loanParams
* @param {ParamManagerPublic} paramManager
* @param {LiquidationStrategy} liquidationStrategy
* @returns {VaultManager}
*/
Expand All @@ -142,7 +155,7 @@
* @param {ZCFMint} runMint
* @param {ERef<MultipoolAutoswapPublicFacet>} autoswap
* @param {ERef<PriceAuthority>} priceAuthority
* @param {LoanParams} loanParams
* @param {ParamManagerPublic} paramManager
* @param {Timestamp} startTimeStamp
* @returns {VaultKit}
*/
Expand Down
6 changes: 3 additions & 3 deletions packages/treasury/src/vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function makeVaultKit(
runMint,
autoswap,
priceAuthority,
loanParams,
loanParamManager,
startTimeStamp,
) {
const trace = makeTracer('VV');
Expand Down Expand Up @@ -57,8 +57,8 @@ export function makeVaultKit(
const interestCalculator = makeInterestCalculator(
runBrand,
manager.getInterestRate(),
loanParams.chargingPeriod,
loanParams.recordingPeriod,
manager.getChargingPeriod(),
manager.getRecordingPeriod(),
);

function getCollateralAllocated(seat) {
Expand Down
30 changes: 22 additions & 8 deletions packages/treasury/src/vaultManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ import { makeVaultKit } from './vault';
import { makePrioritizedVaults } from './prioritizedVaults';
import { liquidate } from './liquidation';
import { makeTracer } from './makeTracer';
import {
RECORDING_PERIOD_KEY,
LIQUIDATION_MARGIN_KEY,
INITIAL_MARGIN_KEY,
LOAN_FEE_KEY,
INTEREST_RATE_KEY,
CHARGING_PERIOD_KEY,
} from './paramKeys';

const trace = makeTracer(' VM ');

Expand All @@ -32,28 +40,34 @@ export function makeVaultManager(
runMint,
collateralBrand,
priceAuthority,
rates,
rateManager,
reallocateReward,
timerService,
loanParams,
loanParamManager,
liquidationStrategy,
) {
const { brand: runBrand } = runMint.getIssuerRecord();

const shared = {
// loans below this margin may be liquidated
getLiquidationMargin() {
return rates.liquidationMargin;
return rateManager.lookup(LIQUIDATION_MARGIN_KEY);
},
// loans must initially have at least 1.2x collateralization
getInitialMargin() {
return rates.initialMargin;
return rateManager.lookup(INITIAL_MARGIN_KEY);
},
getLoanFee() {
return rates.loanFee;
return rateManager.lookup(LOAN_FEE_KEY);
},
getInterestRate() {
return rates.interestRate;
return rateManager.lookup(INTEREST_RATE_KEY);
},
getChargingPeriod() {
return rateManager.lookup(CHARGING_PERIOD_KEY);
},
getRecordingPeriod() {
return rateManager.lookup(RECORDING_PERIOD_KEY);
},
async getCollateralQuote() {
// get a quote for one unit of the collateral
Expand Down Expand Up @@ -174,7 +188,7 @@ export function makeVaultManager(

const periodNotifier = E(timerService).makeNotifier(
0n,
loanParams.recordingPeriod,
rateManager.lookup(RECORDING_PERIOD_KEY),
);
const { zcfSeat: poolIncrementSeat } = zcf.makeEmptySeatKit();

Expand Down Expand Up @@ -211,7 +225,7 @@ export function makeVaultManager(
runMint,
autoswap,
priceAuthority,
loanParams,
loanParamManager,
startTimeStamp,
);

Expand Down
6 changes: 6 additions & 0 deletions packages/treasury/test/test-bootstrapPayment.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ test('bootstrap payment', async t => {
const loanParams = {
chargingPeriod: 2n,
recordingPeriod: 10n,
poolFee: 24n,
protocolFee: 6n,
};
const manualTimer = buildManualTimer(console.log);
// This test value is not a statement about the actual value to
Expand Down Expand Up @@ -81,6 +83,8 @@ test('bootstrap payment - only minted once', async t => {
const loanParams = {
chargingPeriod: 2n,
recordingPeriod: 10n,
poolFee: 24n,
protocolFee: 6n,
};
const manualTimer = buildManualTimer(console.log);
// This test value is not a statement about the actual value to
Expand Down Expand Up @@ -136,6 +140,8 @@ test('bootstrap payment - default value is 0n', async t => {
const loanParams = {
chargingPeriod: 2n,
recordingPeriod: 10n,
poolFee: 24n,
protocolFee: 6n,
};
const manualTimer = buildManualTimer(console.log);
const { creatorFacet: stablecoinMachine, instance } = await E(
Expand Down
4 changes: 2 additions & 2 deletions packages/treasury/test/test-stablecoin.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ test('price drop', async t => {
const loanParams = {
chargingPeriod: 2n,
recordingPeriod: 10n,
poolFee: 24,
protocolFee: 6,
poolFee: 24n,
protocolFee: 6n,
};
const manualTimer = buildManualTimer(console.log);
const { creatorFacet: stablecoinMachine, publicFacet: lender } = await E(
Expand Down
Loading

0 comments on commit 5766e66

Please sign in to comment.