Skip to content

Commit

Permalink
feat(auction): add an auctioneer to manage vault liquidation (#7000)
Browse files Browse the repository at this point in the history
* feat(auction): add an auctioneer to manage vault liquiditation

Separate pieces include a scheduler that manages the phases of an
auction, the AuctionBook that holds onto offers to buy, and the
auctioneer, which accepts good for sale and has the APIs. Params are
managed via governance. The classes are not durable.

This is DRAFT, for early review.

The changes to VaultFactory to make use of this approach to
liquidation rather than the AMM are in a separate PR, which will be
available before this PR is finalized.

closes: #6992

* refactor: cleanups from working on vault liquidation

* chore: cleanups suggested in review

* refactor: simplify keys in sortOffers

* chore: cosmetic cleanups from review

* chore: auction was introduced to vaultfactory too early.

It will be introduced with #7047 when vaultfactory makes use of the
auction for liquidation

* chore: correctly revert removal of param declaration

It'll be removed in #7074, I think, but for now it like a change in
this PR.

* test: repair dependencies for startAuction

* chore: responses to reviews

* test:  refactor proportional distribution test to use macros

* refactor: correct sorting of orders by time

Add a test for this case.

make all auctionContract tests serial

* chore: cleanups suggested in review

for loops rather than foreach
better type
extraneous line

* chore: clean up scheduler; add test for computeRoundTiming

* chore: minor cleanups from review

* chore: rename auctionKit to auctioneerKit

* chore: drop auction from startPSM

* chore: clean-ups from review

* refactor: computeRoundTiming should not allow duration === frequency

* chore: clean up governance, add invitation patterns in auctioneer

* refactor: don't reschedule next if price is already locked
  • Loading branch information
Chris-Hibbert authored Mar 6, 2023
1 parent 1a66ff6 commit 398b70f
Show file tree
Hide file tree
Showing 35 changed files with 4,073 additions and 11 deletions.
3 changes: 2 additions & 1 deletion packages/SwingSet/tools/manual-timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const setup = () => {
* kernel. You can make time pass by calling `advanceTo(when)`.
*
* @param {{ startTime?: Timestamp }} [options]
* @returns {TimerService & { advanceTo: (when: Timestamp) => void; }}
* @returns {TimerService & { advanceTo: (when: Timestamp) => bigint; }}
*/
export const buildManualTimer = (options = {}) => {
const { startTime = 0n, ...other } = options;
Expand All @@ -79,6 +79,7 @@ export const buildManualTimer = (options = {}) => {
assert(when > state.now, `advanceTo(${when}) < current ${state.now}`);
state.now = when;
wake();
return when;
};

return Far('ManualTimer', { ...bindAllMethods(timerService), advanceTo });
Expand Down
2 changes: 2 additions & 0 deletions packages/governance/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export const ParamTypes = /** @type {const} */ ({
RATIO: 'ratio',
STRING: 'string',
PASSABLE_RECORD: 'record',
TIMESTAMP: 'timestamp',
RELATIVE_TIME: 'relativeTime',
UNKNOWN: 'unknown',
});

Expand Down
14 changes: 14 additions & 0 deletions packages/governance/src/contractGovernance/assertions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { isRemotable } from '@endo/marshal';
import { assertIsRatio } from '@agoric/zoe/src/contractSupport/ratio.js';
import { mustMatch } from '@agoric/store';
import { RelativeTimeRecordShape, TimestampRecordShape } from '@agoric/time';

const { Fail } = assert;

Expand Down Expand Up @@ -41,9 +43,21 @@ const makeAssertBrandedRatio = (name, modelRatio) => {
};
harden(makeAssertBrandedRatio);

const assertRelativeTime = value => {
mustMatch(value, RelativeTimeRecordShape);
};
harden(assertRelativeTime);

const assertTimestamp = value => {
mustMatch(value, TimestampRecordShape, 'timestamp');
};
harden(assertTimestamp);

export {
makeLooksLikeBrand,
makeAssertInstallation,
makeAssertInstance,
makeAssertBrandedRatio,
assertRelativeTime,
assertTimestamp,
};
20 changes: 20 additions & 0 deletions packages/governance/src/contractGovernance/paramManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { assertAllDefined } from '@agoric/internal';
import { ParamTypes } from '../constants.js';

import {
assertTimestamp,
assertRelativeTime,
makeAssertBrandedRatio,
makeAssertInstallation,
makeAssertInstance,
Expand Down Expand Up @@ -44,6 +46,8 @@ const assertElectorateMatches = (paramManager, governedParams) => {
* @property {(name: string, value: Ratio) => ParamManagerBuilder} addRatio
* @property {(name: string, value: import('@endo/marshal').CopyRecord<unknown>) => ParamManagerBuilder} addRecord
* @property {(name: string, value: string) => ParamManagerBuilder} addString
* @property {(name: string, value: import('@agoric/time/src/types').Timestamp) => ParamManagerBuilder} addTimestamp
* @property {(name: string, value: import('@agoric/time/src/types').RelativeTime) => ParamManagerBuilder} addRelativeTime
* @property {(name: string, value: any) => ParamManagerBuilder} addUnknown
* @property {() => AnyParamManager} build
*/
Expand Down Expand Up @@ -184,6 +188,18 @@ const makeParamManagerBuilder = (publisherKit, zoe) => {
return builder;
};

/** @type {(name: string, value: import('@agoric/time/src/types').Timestamp, builder: ParamManagerBuilder) => ParamManagerBuilder} */
const addTimestamp = (name, value, builder) => {
buildCopyParam(name, value, assertTimestamp, ParamTypes.TIMESTAMP);
return builder;
};

/** @type {(name: string, value: import('@agoric/time/src/types').RelativeTime, builder: ParamManagerBuilder) => ParamManagerBuilder} */
const addRelativeTime = (name, value, builder) => {
buildCopyParam(name, value, assertRelativeTime, ParamTypes.RELATIVE_TIME);
return builder;
};

/** @type {(name: string, value: any, builder: ParamManagerBuilder) => ParamManagerBuilder} */
const addUnknown = (name, value, builder) => {
const assertUnknown = _v => true;
Expand Down Expand Up @@ -356,6 +372,8 @@ const makeParamManagerBuilder = (publisherKit, zoe) => {
getRatio: name => getTypedParam(ParamTypes.RATIO, name),
getRecord: name => getTypedParam(ParamTypes.PASSABLE_RECORD, name),
getString: name => getTypedParam(ParamTypes.STRING, name),
getTimestamp: name => getTypedParam(ParamTypes.TIMESTAMP, name),
getRelativeTime: name => getTypedParam(ParamTypes.RELATIVE_TIME, name),
getUnknown: name => getTypedParam(ParamTypes.UNKNOWN, name),
getVisibleValue,
getInternalParamValue,
Expand All @@ -379,6 +397,8 @@ const makeParamManagerBuilder = (publisherKit, zoe) => {
addRatio: (n, v) => addRatio(n, v, builder),
addRecord: (n, v) => addRecord(n, v, builder),
addString: (n, v) => addString(n, v, builder),
addRelativeTime: (n, v) => addRelativeTime(n, v, builder),
addTimestamp: (n, v) => addTimestamp(n, v, builder),
build,
};
return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ const isAsync = {
* | ST<'nat'>
* | ST<'ratio'>
* | ST<'string'>
* | ST<'timestamp'>
* | ST<'relativeTime'>
* | ST<'unknown'>} SyncSpecTuple
*
* @typedef {['invitation', Invitation]} AsyncSpecTuple
Expand Down
5 changes: 5 additions & 0 deletions packages/governance/src/contractHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getMethodNames, objectMap } from '@agoric/internal';
import { ignoreContext } from '@agoric/vat-data';
import { keyEQ, M } from '@agoric/store';
import { AmountShape, BrandShape } from '@agoric/ertp';
import { RelativeTimeRecordShape, TimestampRecordShape } from '@agoric/time';
import { assertElectorateMatches } from './contractGovernance/paramManager.js';
import { makeParamManagerFromTerms } from './contractGovernance/typedParamManager.js';

Expand All @@ -23,6 +24,8 @@ const publicMixinAPI = harden({
getNat: M.call().returns(M.bigint()),
getRatio: M.call().returns(M.record()),
getString: M.call().returns(M.string()),
getTimestamp: M.call().returns(TimestampRecordShape),
getRelativeTime: M.call().returns(RelativeTimeRecordShape),
getUnknown: M.call().returns(M.any()),
});

Expand Down Expand Up @@ -51,6 +54,8 @@ const facetHelpers = (zcf, paramManager) => {
getNat: paramManager.getNat,
getRatio: paramManager.getRatio,
getString: paramManager.getString,
getTimestamp: paramManager.getTimestamp,
getRelativeTime: paramManager.getRelativeTime,
getUnknown: paramManager.getUnknown,
};

Expand Down
7 changes: 6 additions & 1 deletion packages/governance/src/types-ambient.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@

/**
* @typedef { Amount | Brand | Installation | Instance | bigint |
* Ratio | string | unknown } ParamValue
* Ratio | string | import('@agoric/time/src/types').TimestampRecord |
* import('@agoric/time/src/types').RelativeTimeRecord | unknown } ParamValue
*/

// XXX better to use the manifest constant ParamTypes
Expand All @@ -47,6 +48,8 @@
* T extends 'nat' ? bigint :
* T extends 'ratio' ? Ratio :
* T extends 'string' ? string :
* T extends 'timestamp' ? import('@agoric/time/src/types').TimestampRecord :
* T extends 'relativeTime' ? import('@agoric/time/src/types').RelativeTimeRecord :
* T extends 'unknown' ? unknown :
* never
* } ParamValueForType
Expand Down Expand Up @@ -427,6 +430,8 @@
* @property {(name: string) => bigint} getNat
* @property {(name: string) => Ratio} getRatio
* @property {(name: string) => string} getString
* @property {(name: string) => import('@agoric/time/src/types').TimestampRecord} getTimestamp
* @property {(name: string) => import('@agoric/time/src/types').RelativeTimeRecord} getRelativeTime
* @property {(name: string) => any} getUnknown
* @property {(name: string, proposedValue: ParamValue) => ParamValue} getVisibleValue - for
* most types, the visible value is the same as proposedValue. For Invitations
Expand Down
12 changes: 12 additions & 0 deletions packages/inter-protocol/scripts/add-collateral-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ export const psmGovernanceBuilder = async ({
psm: publishRef(
install('../src/psm/psm.js', '../bundles/bundle-psm.js'),
),
vaults: publishRef(
install(
'../src/vaultFactory/vaultFactory.js',
'../bundles/bundle-vaultFactory.js',
),
),
auction: publishRef(
install(
'../src/auction/auctioneer.js',
'../bundles/bundle-auctioneer.js',
),
),
econCommitteeCharter: publishRef(
install(
'../src/econCommitteeCharter.js',
Expand Down
1 change: 1 addition & 0 deletions packages/inter-protocol/scripts/deploy-contracts.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const contractRefs = [
'../bundles/bundle-vaultFactory.js',
'../bundles/bundle-reserve.js',
'../bundles/bundle-psm.js',
'../bundles/bundle-auctioneer.js',
'../../vats/bundles/bundle-mintHolder.js',
];
const contractRoots = contractRefs.map(ref =>
Expand Down
4 changes: 4 additions & 0 deletions packages/inter-protocol/scripts/init-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ const installKeyGroups = {
],
},
main: {
auction: [
'../src/auction/auctioneer.js',
'../bundles/bundle-auctioneer.js',
],
vaultFactory: [
'../src/vaultFactory/vaultFactory.js',
'../bundles/bundle-vaultFactory.js',
Expand Down
Loading

0 comments on commit 398b70f

Please sign in to comment.