Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vaultManager): expose liquidation metrics #5393

Merged
merged 31 commits into from
May 25, 2022

Conversation

turadg
Copy link
Member

@turadg turadg commented May 18, 2022

closes: #5300

Description

Include liquidation metrics in VaultManager's notifications.

Security Considerations

Exposes more data, but only that we want to be public.

Documentation Considerations

The metrics and their descriptions:

/**
 * @typedef {object} MetricsNotification
 *
 * @property {number}         numVaults        present count of vaults
 * @property {Amount<'nat'>}  totalCollateral  present sum of collateral across all vaults
 * @property {Amount<'nat'>}  totalDebt        present sum of debt across all vaults
 *
 * @property {Amount<'nat'>}  totalCollateralSold       running sum of collateral sold in liquidation // totalCollateralSold
 * @property {Amount<'nat'>}  totalOverageReceived      running sum of overages, central received greater than debt
 * @property {Amount<'nat'>}  totalProceedsReceived     running sum of central received from liquidation
 * @property {Amount<'nat'>}  totalShortfallReceived    running sum of shortfalls, central received less than debt
 * @property {number}         numLiquidationsCompleted  running count of liquidations
 */

It wasn't clear how to distinguish metrics for "now" vs "up to now". This This introduces a naming scheme: nouns are present values; past-participles are summative. It's included as a comment in vaultManager.js. Are there other places it should go? (assuming reviewer agrees to the scheme)

Testing Considerations

New tests and new harness for expressing diffs from one subscription state to the next.

I want to have a test validating the arithmetic among debt, proceeds, overage, and sales. I'm waiting on #5366 to be able to query the latest state. If that's done by the time this needs to land I'll include it; if not I'll change the FIXME to a TODO.

@turadg turadg force-pushed the 5300-liquidation-econ-metrics branch from 6955665 to 23c4d30 Compare May 20, 2022 23:14
@turadg turadg force-pushed the 5300-liquidation-econ-metrics branch from 23c4d30 to 07d7b31 Compare May 23, 2022 14:48
@turadg turadg changed the title feat(liquidation): expose econ metrics feat(vaultManager): expose liquidation metrics May 23, 2022
@@ -85,9 +85,9 @@
* @property {() => Ratio} getLoanFee
* @property {() => Promise<PriceQuote>} getCollateralQuote
* @property {() => Ratio} getInterestRate - The annual interest rate on a loan
* @property {() => RelativeTime} getChargingPeriod - The period (in seconds) at
* @property {() => NatValue} getChargingPeriod - The period (in seconds) at
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are specifically seconds, not arbitrary RelativeTime. they also can't be relative; they must be positive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RelativeTime should perhaps be renamed to Duration and declared to be Nat. I don't think it can be negative.

For the moment, I think the RelativeTime used by the TimerService is actually what we want here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm. done.

Comment on lines -552 to -555
state.totalCollateral = AmountMath.add(
state.totalCollateral,
vaultKit.vault.getCollateralAmount(),
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this didn't previously account for changes in collateral after a vault was created. it's handled now in updateVaultAccounting

@turadg turadg requested a review from Chris-Hibbert May 23, 2022 22:41
@turadg turadg marked this pull request as ready for review May 23, 2022 22:41
@turadg turadg requested a review from dtribble as a code owner May 23, 2022 22:41
@@ -85,9 +85,9 @@
* @property {() => Ratio} getLoanFee
* @property {() => Promise<PriceQuote>} getCollateralQuote
* @property {() => Ratio} getInterestRate - The annual interest rate on a loan
* @property {() => RelativeTime} getChargingPeriod - The period (in seconds) at
* @property {() => NatValue} getChargingPeriod - The period (in seconds) at
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RelativeTime should perhaps be renamed to Duration and declared to be Nat. I don't think it can be negative.

For the moment, I think the RelativeTime used by the TimerService is actually what we want here.

@turadg turadg force-pushed the 5300-liquidation-econ-metrics branch from 72b4696 to 0897a66 Compare May 24, 2022 16:49
@turadg turadg requested a review from Chris-Hibbert May 24, 2022 16:52
@turadg turadg added the automerge:squash Automatically squash merge label May 25, 2022
Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my only substantive comment is about whether t.pass() is necessary.

* @param {Amount<'nat'>} debt
* @param {Amount<'nat'>} proceeds
*/
const calcMetrics = (debt, proceeds) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're now consistently using 'metrics' for the data that gets published by subscriptions. As long as it's not exposed outside this helper, it doesn't matter. I think the naming is inconsequential, since the return value is { proceeds: proceeds.RUN, overage, shortfall }.

@@ -33,6 +33,21 @@ const { details: X } = assert;

const trace = makeTracer('VM', false);

// Metrics naming scheme: nouns are present values; past-participles are summative.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 'summative' an actual word? How about 'running totals' or 'accumulations'? If you prefer summative, I'll be fine with it. Its meaning is obvious.

Copy link
Member Author

@turadg turadg May 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is indeed a word. Primed in my brain summative assessments. Accumulative is much better though because they grow monotonically. Changing to that.

@@ -19,13 +21,14 @@ export const subscriptionTracker = async (t, subscription) => {
const prevNotif = notif;
notif = await metrics.getUpdateSince(notif.updateCount);
const actualDelta = diff(prevNotif.value, notif.value);
console.log({ actualDelta });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this have a label?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally. this is just a test so I don't feel strongly. I'll remove though and people can add it whip it up if they need to debug a failure.

@@ -2398,60 +2400,264 @@ test('director notifiers', async t => {

// Not testing rewardPoolAllocation contents because those are simply those values.
// We could refactor the tests of those allocations to use the data now exposed by a notifier.

t.pass();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it a bug if no assertions get called on t?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this was a holdover from when assertChange was asserting without t, in which case Ava needn't to be told that if we get to this line we passed. No longer necessary so I'll remove.

@turadg turadg requested a review from Chris-Hibbert May 25, 2022 21:41
Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good!

Copy link
Member

@dtribble dtribble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. My only objection is in the partialAssign usage, which predates this PR. Please eitehr fix that or file a ticket for it.

* @param {Amount<'nat'>} proceeds
*/
const calcMetrics = (debt, proceeds) => {
if (AmountMath.isGTE(debt, proceeds)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a conditional expression?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean return AmountMath.isGTE(debt, proceeds) ? or something else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8b6231

debtBrand: fixed.debtBrand,
vaultCounter: 0,
latestInterestUpdate,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"latest" here seems redundant. All state is "latest"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will follow up

Copy link
Member Author

@turadg turadg May 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dtribble this is not about the state of "interest update", it's specifying the last in a stream of "interest update" values. What would be a better name?

this is sent as part of the AssetNotification so renaming would be a breaking change. If you think the new name idea is worth that lemme know.

@@ -243,7 +255,7 @@ const helperBehavior = {
},
updateTime,
);
Object.assign(state, stateUpdates);
partialAssign(state, stateUpdates);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this pattern. It makes the entire state of the vault vulnerable to the interest computation. Can we replace with explicit assign of the allowed fields?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll let this one merge since it's on the train and follow up in the morning with another.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d179e5

oldCollateral,
);
// debt accounting managed through minting and burning
facets.helper.updateMetrics();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this trigger two updates, one for collateral and one for debt? For an adjustBalances there should just be one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd see that in tests.

@@ -19,13 +21,14 @@ export const subscriptionTracker = async (t, subscription) => {
const prevNotif = notif;
notif = await metrics.getUpdateSince(notif.updateCount);
const actualDelta = diff(prevNotif.value, notif.value);
console.log({ actualDelta });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment out now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or should be using trace

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

He did drop it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was removed in last push

@@ -10,6 +10,8 @@ import { diff } from 'deep-object-diff';
export const subscriptionTracker = async (t, subscription) => {
const metrics = makeNotifierFromAsyncIterable(subscription);
let notif;
const getLastNotif = () => notif;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a strange name. Isn't it the last state snapshot?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(oh it's in test. ok nvm :)

@mergify mergify bot merged commit 47d4823 into master May 25, 2022
@mergify mergify bot deleted the 5300-liquidation-econ-metrics branch May 25, 2022 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:squash Automatically squash merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose econ metrics on vault liquidations
3 participants