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(vault): econ metrics notifiers #5260

Merged
merged 44 commits into from
May 18, 2022

Conversation

turadg
Copy link
Member

@turadg turadg commented Apr 29, 2022

closes: #4649

Description

Per Contract (Director object)

Per Collateral (Manager object)

  • Governance parameters, including interest rate, liquidation ratio, liquidation penalty per collateral, current debt limit governed
  • Current debt limit governed
  • Number of vaults
  • Total outstanding debt (vaultKit publicNotifiers.asset)
  • Total collateral held
  • Compounded interest (vaultKit publicNotifiers.asset)
  • Liquidation strategy governed
  • Liquidation state (DEFERRED Expose econ metrics on vault liquidations #5300)

Per Vault

  • Debt (debtSnapshot.debt)
  • Collateral (locked)
  • Interest snapshot (debtSnapshot.interest)
  • Status (open, closed, liquidating, liquidated) vaultState

Use existing notifiers except for values that have high change frequency.

Security Considerations

Everything being exposed here is intentional.

Documentation Considerations

We will need to update these docs. Waiting on technical writer.

Testing Considerations

New tests for notifier output.

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

/**
* @typedef {{
* governedValues: {}, // ??? what type? ??? aren't there already subscriptions?
Copy link
Member Author

Choose a reason for hiding this comment

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

Since governance is already on-chain, do we need to republish all the values or can we point to them somehow?

Also, @Chris-Hibbert WDYT of ParamManager having methods to support this?

Copy link
Contributor

Choose a reason for hiding this comment

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

It absolutely makes sense for ParamManager to provide support. I'm waiting on more detailed requirements.

I'm hoping to hear

  • what publishing/sharing mechanisms are needed
  • whether we want to emit events or statistics. At ${JOB-1} the s/w mostly said "x happened" and the monitoring systems did all the counting, averaging, etc. I can imagine we want more to happen in the contracts, so we'd emit counts, averages, maximums, etc.

@@ -72,13 +80,17 @@ const initState = (zcf, directorParamManager, debtMint) => {

const vaultParamManagers = makeScalarMap('brand');

// XXX need a way to register this data stream for consumption
const { updater: econMetrics } = makeNotifierKit();
Copy link
Member Author

Choose a reason for hiding this comment

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

@gibson042 I punted on mocking this because I wasn't sure where to put it. seems like @dtribble may have some designs in mind so I don't want to proceed too far.

@turadg turadg force-pushed the 4649-expose-vaultFactor-econ-metrics branch 4 times, most recently from db362c6 to 74e672d Compare May 5, 2022 20:53
@turadg turadg marked this pull request as ready for review May 5, 2022 21:01
@turadg turadg requested a review from dtribble as a code owner May 5, 2022 21:01
@turadg turadg force-pushed the 4649-expose-vaultFactor-econ-metrics branch from 74e672d to 8761fe1 Compare May 5, 2022 21:26
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.

Generally great, but some namings and renamings are problematic. Note that those could mostly be not entangled with the core of this change.

@@ -37,7 +38,7 @@
* @param {Issuer} collateralIssuer
* @param {Keyword} collateralKeyword
* @param {VaultManagerParamValues} params
* @returns {Promise<VaultManager>}
* @returns {Promise<VaultManagerObject>}
Copy link
Member

Choose a reason for hiding this comment

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

"Object" is a terrible thing to stick in a name. It's completely vacuous.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. VaultManager was used already by ReturnType<typeof makeVaultManagerKit>['manager'] so I was trying to make a small change but I'll make the better change.

@@ -174,6 +174,7 @@ export const makePrioritizedVaults = (reschedulePriceCheck = () => {}) => {
addVault,
entries: vaults.entries,
entriesPrioritizedGTE,
getSize: vaults.getSize,
Copy link
Member

Choose a reason for hiding this comment

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

"count" would be much better "size". "Size" could mean any number of things (total market cap? AUM? disk space used?)

@@ -66,14 +66,15 @@ const validTransitions = {
/**
* @typedef {Phase[keyof typeof Phase]} TitlePhase
*
* @typedef {object} VaultUIState
* @typedef {object} VaultTitleState
Copy link
Member

Choose a reason for hiding this comment

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

"Title" has the wrong connotations:

  • it's a thing looked up in a registry
  • it feels ACL-based
  • it's primarily the meta-data, not the authority.

Thus the "title" woudl be more the invitation made in a transfer request (I sign over the title to you and then you get the keys to the property)

Copy link
Member

Choose a reason for hiding this comment

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

This is not just being pedantic. Using a term "near but wrong" would be a larger cause of deep confusion than using a new or clumsy term. Hence, "outer" would still be better.

  • ref
  • outer
  • handle (but used elsewhere ina. consistent way without operations)
  • proxy (but used in JS already)
  • front
  • facet
  • facade (implies fake though)
  • aspect (but "aspect oriented programming polluted that)

Copy link
Member Author

@turadg turadg May 9, 2022

Choose a reason for hiding this comment

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

This is not just being pedantic. Using a term "near but wrong" would be a larger cause of deep confusion than using a new or clumsy term.

Agree naming is important and "near but wrong' can be worse that obviously wrong.

Thus the "title" woudl be more the invitation made in a transfer request

I don't agree with the bullets supporting it but I agree with this conclusion.

Note that this just a typename. In the vault offer result it's,

    publicNotifiers: {
      vault: title.getNotifier(),
      asset: assetNotifier,
    },

So how about VaultNotifierState? VaultState could also work but given how easy it is to change type names I'd err towards more explicit and if we find over time the disambiguation is unnecessary we can shorten it.

EDIT: I went with VaultNotification.

@@ -66,14 +66,15 @@ const validTransitions = {
/**
* @typedef {Phase[keyof typeof Phase]} TitlePhase
*
* @typedef {object} VaultUIState
Copy link
Member

Choose a reason for hiding this comment

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

We need a general term for the state snapshot from a notifier. We could remove "UI" from that with "vaultSnapshot"? but "vaultState" isn't terrible.

Copy link
Member Author

Choose a reason for hiding this comment

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

Came up above and proposed Notification. I could see that being used for the wrapping object (with value and updateCount) but that's so generic as to not need a name.

@@ -254,6 +275,7 @@ const machineBehavior = {
}
// TODO add aggregate debt tracking at the vaultFactory level #4482
// totalDebt = AmountMath.add(totalDebt, toMint);
facets.machine.notifyEcon();
Copy link
Member

Choose a reason for hiding this comment

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

what is "machine"?

Copy link
Member Author

@turadg turadg May 9, 2022

Choose a reason for hiding this comment

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

That term started here 15322a1#diff-0b7d727a28b84089ac4ebe9b76f8957bb71bfee261640828bad01c4189cbe73fR283

I kept it because it distinguishes between the "creator facet" of the contract and the "limited creator facet" that it can return. I think we should move from "this thing is for what consumer" to "what this thing does or how". (For the same reasons that "public notifiers" is better than "UI notifiers")

@@ -237,12 +255,23 @@ const helperBehavior = {
compoundedInterest: state.compoundedInterest,
interestRate,
latestInterestUpdate: state.latestInterestUpdate,
totalDebt: state.totalDebt,
// XXX move to EconState and type as present with null
liquidatorInstance: state.liquidatorInstance,
Copy link
Member

Choose a reason for hiding this comment

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

That should be in governance notifier I would think

trace(t, 'pa', { governorInstance, vaultFactory, lender, priceAuthority });
trace(t, 'pa', {
governorInstance,
vaultFactory: vaultFactoryCreator,
Copy link
Member

Choose a reason for hiding this comment

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

remove vaultFactory:

@@ -364,7 +368,11 @@ test('first', async t => {
undefined,
500n,
);
const { vaultFactory, lender, aethVaultManager } = services.vaultFactory;
const {
vaultFactoryCreator: vaultFactory,
Copy link
Member

Choose a reason for hiding this comment

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

it would be good to not have this property renaming.

Copy link
Member Author

Choose a reason for hiding this comment

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

goal was to not have vaultFactory.vaultFactory as before. granted the type system indicates they're different, but just eyeballing it's not clear.

In general I think we would benefit from more consistency in how we name facets, contracts, and virtual/durable objects in contracts. That's a bigger endeavor that is out of scope so I'll revert this change.

const [
governorInstance,
vaultFactory,
vaultFactoryCreator,
Copy link
Member

Choose a reason for hiding this comment

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

this renaming causes a lot of churn. If you really want it, the uses below need to be updated as well so we dont' have a bunch of vaultFactory: vaultFactoryCreator. Given that the type system clarifies that it's the creator facet, this seems unnecessary.

@@ -784,7 +792,7 @@ test('vaultFactory display collateral', async t => {
500n,
);

const { vaultFactory } = services.vaultFactory;
const { vaultFactoryCreator: vaultFactory } = services.vaultFactory;
Copy link
Member

Choose a reason for hiding this comment

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

As above

@turadg turadg changed the title track vault factory econ metrics feat(vault): econ metrics notifiers May 9, 2022
@turadg turadg force-pushed the 4649-expose-vaultFactor-econ-metrics branch from 8761fe1 to c5bd54d Compare May 9, 2022 18:31
liquidatorInstance: state.liquidatorInstance,
});
state.assetUpdater.updateState(payload);
},

/** @param {MethodContext} context */
metricsNotify: ({ state }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

notify would conventionally be a fine name, but with notifier/updater the notifier half is about getting notified and the updater half is about sending notifications. I think this needs to be updateMetrics.

Copy link
Member Author

Choose a reason for hiding this comment

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

liquidatorInstance: state.liquidatorInstance,
});
state.assetUpdater.updateState(payload);
},

/** @param {MethodContext} context */
metricsNotify: ({ state }) => {
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 metricNotify should be called on liquidateAll(), but I don't see how it will be.

Do individual liquidations invoke 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.

They should. 41fa373

though I ran into an accounting issue that isn't obvious to solve and will be changed by #5343 so I'll come back to this after that.

@turadg turadg requested a review from Chris-Hibbert May 16, 2022 21:34
@turadg turadg added the automerge:squash Automatically squash merge label May 16, 2022
@Chris-Hibbert
Copy link
Contributor

/home/runner/work/agoric-sdk/agoric-sdk/packages/run-protocol/test/vaultFactory/test-vaultFactory.js
Error: 43:1 error @agoric/notifier import should occur before import of ../../src/makeTracer.js import/order

@turadg turadg dismissed dtribble’s stale review May 16, 2022 22:08

confident I executed requested changes

@mergify mergify bot merged commit 6c3cdf3 into master May 18, 2022
@mergify mergify bot deleted the 4649-expose-vaultFactor-econ-metrics branch May 18, 2022 19:25
@@ -34,11 +38,15 @@ const trace = makeTracer('VM', false);
* compoundedInterest: Ratio,
* interestRate: Ratio,
* latestInterestUpdate: bigint,
* totalDebt: Amount<'nat'>,
Copy link
Contributor

Choose a reason for hiding this comment

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

This caused a null reference error in the UI https://github.com/Agoric/dapp-treasury/blob/main/ui/src/components/vault/VaultConfigure/VaultConfigure.jsx#L200. I guess typescript/CI didn't catch this somehow...

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I didn't realize that was being used. Yeah, the dapp-treasury repo currently has no type checking Agoric/dapp-treasury#97

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 key Vault Factory economic data via subscription
4 participants