-
Notifications
You must be signed in to change notification settings - Fork 212
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
Manage treasury 3189 #3310
Manage treasury 3189 #3310
Conversation
912ec10
to
df28867
Compare
964877b
to
9ffd163
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a bunch of code here that seems redundant with another pull request soI'm not sure what's up. I also have a more friendly API for params to discuss.
const { | ||
publicFacet: rateManagerPublic, | ||
manager: rateManager, | ||
} = buildParamManager([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has got to go into a different file or something. Or we need a much more abbreviated syntax for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking each param should be a separate object, rather than havign them all looked up through essentially a map.
const chargingPeriodParam = gov.natParam(CHARGING_PERIOD_KEY, loanParams.chargingPeriod);
const recordingPeriodParam = gov.natParam(RECORDING_PERIOD_KEY, loanParams.recordingPeriod);
and then usage would be chargingPeriodParam.value()
or some such.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to a separate file.
They're not separate objects, but there are separate updateFoo()
functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this PR, someone who is only looking at the treasury contract has no way of knowing how governance can change the parameters. I realize that this PR might have just been just part of the overall concept (just a piecemeal use of the governance params only), but I think for this PR to be a useful test of the system, we should have a test that models the user of the treasury. The user might ask:
- What are the terms that can change? Can I know which terms can change just by looking at the invitation? What if the contract is not reporting the mutable terms correctly?
- For the governed parameters, how are they governed? Under what rules can they change? Who makes decisions? How can I verify what the documentation says?
In order for the user to answer # 2, the whole governance infrastructure needs to be within this contract and the paramManager
should not escape the contract. Adding getParamManager: () => paramManager,
to the creatorFacet would be wrong.
83fe828
to
842a5f1
Compare
5766e66
to
cda95b1
Compare
cda95b1
to
41f66c5
Compare
41f66c5
to
e478297
Compare
e478297
to
a9ad9ab
Compare
06a9e90
to
3b4bc67
Compare
3b4bc67
to
4396a30
Compare
4396a30
to
1c82754
Compare
comments have been addressed. Responsibility for review transferred to @dckc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried just jumping in as if the PR were self-explanatory, but I'm quickly getting in over my head. I better talk with @Chris-Hibbert and maybe @michaelfig .
packages/treasury/src/vault.js
Outdated
@@ -58,6 +58,8 @@ export function makeVaultKit( | |||
assert(vaultState === VaultState.ACTIVE, 'vault must still be active'); | |||
} | |||
|
|||
console.log(`VALT ${q(manager)}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like debug logging. Any particular reason to leave it turned on in production?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. Thanks.
import contractGovernorBundle from './bundle-contractGovernor.js'; | ||
import committeeBundle from './bundle-committee.js'; | ||
import binaryVoteCounterBundle from './bundle-binaryVoteCounter.js'; | ||
import { governedParameterTerms } from '../src/params'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I struggled to find a test where I could walk through this code... it looks like nothing in the tests in this package uses install-on-chain.js
. But I see the cosmic-swingset
integration test does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was how I discovered that I needed to update this was that the integration test failed. It looks like it may be used in bringing up a chain, so I tried to make the settings as realistic as possible.
['INSTALLATION_BOARD_ID', stablecoinMachineInstall], | ||
['RUN_ISSUER_BOARD_ID', centralIssuer], | ||
['RUN_BRAND_BOARD_ID', centralBrand], | ||
['AMM_INSTALLATION_BOARD_ID', autoswapInstall], | ||
['LIQ_INSTALLATION_BOARD_ID', liquidationInstall], | ||
['BINARY_COUNTER_INSTALLATION_BOARD_ID', binaryCounterInstall], | ||
['COMMITTEE_INSTALLATION_BOARD_ID', committeeInstall], | ||
['CONTRACT_GOVERNOR_INSTALLATION_BOARD_ID', contractGovernorInstall], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm struggling to judge whether these board / naming updates are correct. I suspect there are some external constraints... from dapp-treasury?
installOnChain
has no doc comment.
vs-code is complaining that it can't find the NameHub
type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was mostly guessing here. I should ask @michaelfig to review this PR and opine on the changes to `install-on-chain.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list is specifically for the UI config that is returned to dapp-treasury/ui
. So, unless the Treasury UI is going to use those board IDs, please don't bother with them.
Rather than a 5-member committee that has no active members, I would prefer a "don't do anything except unilaterally replace my electorate" facet that could be handed to the bootstrap vat, so that the bootstrap could install the actual initial electorate.
It's fine if that's done in a future PR, but please explicitly mark all the inescapable committee governance in this file as a temporary hack just to allow the treasury not to crash during installation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way governance works is that the electorate has to exist before the contract is instantiated, in order to make the governance visible to all. I'm fine with saying there's no governance during testNet, but the way I'd do that is by building a do-nothing electorate. I think that's straightforward, and may be useful in other, similar circumstances.
It would be visible that there's a place for governance, but no one can initiate governance actions in the current installation.
This list is specifically for the UI config that is returned to dapp-treasury/ui. So, unless the Treasury UI is going to use those board IDs, please don't bother with them.
I'm not going to add code to the Treasury UI at this point, but it ought to be able to help the user review invitations. It should be able to identify the installations. All these installations are relevant to the user.
@@ -74,42 +88,65 @@ export async function installOnChain({ | |||
}), | |||
); | |||
|
|||
const electorateTerms = { committeeName: 'TreasuryBoard', committeeSize: 5 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did we get 5 for the size of the treasury board? Was that specified somewhere? Or is it arbitrary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was arbitrary. Can you think of a good place to put a parameter/manifest constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure a manifest constant would help me; then I'd just wonder why that is 5. I'm trying to learn the story behind these numbers and structures. Which ones stay fixed and which ones change and how and why? I'm struggling to pick it up from the code alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a do-nothing electorate would make that constant unnecessary.
@michaelfig would you take a look at the changes in |
const treasuryCreator = await installEconomy(bootstrapPaymentValue); | ||
// NOTE: no use of the voteCreator. We'll need it to initiate votes on | ||
// changing Treasury parameters. | ||
const { treasuryCreator, _voteCreator } = await installEconomy( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you keep the committee in place, maybe you could make it just 1 member, and send the voteCreator
to the some place as the treasuryCreator
is exposed (look for powerFlagConfig
) and name it treasuryVoteCreator
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a no-action electorate instead, as it's easier to validate that it's not doing anything. We can add an active electorate when we know what we want it to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
calling it a day... I think I'll share what I've got so far.
Getting the types to work with dynamic parameter names is tricky. I haven't gotten all of the suggestions I make here work with yarn lint
at the same time. Feel free to pick the ones you like and disregard the others. I suspect we'll have to change ParamDescs
from an array ParamDesc[]
to Record<string, ParamSomething>
to get them to line up right. That's a substantive change, but it's something that can happen in a separate PR.
@@ -74,42 +88,65 @@ export async function installOnChain({ | |||
}), | |||
); | |||
|
|||
const electorateTerms = { committeeName: 'TreasuryBoard', committeeSize: 5 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Until we work out how anybody should get access to the voter invitations, let's make it 1; that's sort of more obviously not a real committee.
const electorateTerms = { committeeName: 'TreasuryBoard', committeeSize: 5 }; | |
const electorateTerms = { committeeName: 'TreasuryBoard', committeeSize: 1 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've drafted a no-action electorate. I think that's more clear that it does nothing.
packages/treasury/src/params.js
Outdated
}; | ||
|
||
export const makePoolParamManager = (loanParams, rates) => { | ||
/** @type {PoolParamManager} */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is perhaps useful as documentation, but tsc
doesn't grok type annotations on return statements.
I tried to work out appropriate type declarations, but with dynamic parameter names, it gets complicated real quick, so I'm setting it aside for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can declare the return type of makePoolParamManager.
const { | ||
aethKit: { mint: aethMint, issuer: aethIssuer, brand: aethBrand }, | ||
} = setupAssets(); | ||
|
||
const priceAuthorityPromiseKit = makePromiseKit(); | ||
const priceAuthorityPromise = priceAuthorityPromiseKit.promise; | ||
const manualTimer = buildManualTimer(console.log); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to get some of these timers to be quiet unless ava
sees -v
by doing...
const manualTimer = buildManualTimer(console.log); | |
const manualTimer = buildManualTimer(t.log); |
but sometimes t
is not in scope... I'm not sure whether it's worth doing just some of the time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What problem are you trying to solve?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The the problem of lots of unwanted console logs when running tests.
The t.log
function is silent unless the -v
command-line flag is given.
@@ -151,6 +192,7 @@ export async function start(zcf, privateArgs) { | |||
want: { Governance: _govOut }, // ownership of the whole stablecoin machine | |||
} = seat.getProposal(); | |||
assert(!collateralTypes.has(collateralBrand)); | |||
// initialPrice is in rates, but only used at creation, so not in governor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see keywords joined with _
a few lines down:
`${collateralKeyword}_Liquidity`
Is that right? As of landing the Constant Product PR, we have:
const addPool = async (secondaryIssuer, keyword) => {
const liquidityKeyword = `${keyword}Liquidity`;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still tied to multipoolAutoswap. I'd like to convert it to use constantProduct, but that hasn't happened yet. I think that should be a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
multipoolAutoswap and constantProduct have different keyword patterns? on purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ${keyword}_Liquidation
vs ${keyword}Liquidation
conflict seems like a real bug, i.e. incompatibility with the xyk stuff.
And install-on-chain simplifications suggested by MF seem worth doing.
// I'd like to validate Installations, but there doesn't seem to be a | ||
// way to get it from an Instance. I'd verify the Electorate, | ||
// ballotCounter, and contractGovernor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about E(zoe).getInstallationForInstance(instance)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. This comment predates both the implementation of that feature, and I think the issue that tracked it.
const { zoeService, feeMintAccess } = makeZoeKit( | ||
vatAdminSvc, | ||
shutdownZoeVat, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's nothing specific to treasury governance in this vat-zoe.js
, is there? This looks like boilerplate as a consequence of metering changes.
IOU an issue to consolidate it in zoe/tools
or some such.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that would be nice. Yes, it's boilerplate, used repeatedly in many swingset tests.
1a5d557
to
3ca89e8
Compare
@Chris-Hibbert if you want:
The following solves your TS conundrum: diff --git a/packages/treasury/src/params.js b/packages/treasury/src/params.js
index a3aa8958f..6d25c9658 100644
--- a/packages/treasury/src/params.js
+++ b/packages/treasury/src/params.js
@@ -2,6 +2,8 @@
import { buildParamManager, ParamType } from '@agoric/governance';
+import './types.js';
+
export const POOL_FEE_KEY = 'PoolFee';
export const PROTOCOL_FEE_KEY = 'ProtocolFee';
|
e7c329e
to
97f1d53
Compare
97f1d53
to
6ce7f17
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cleanup for the param implementation will be a separate PR.
p.s. I reviewed a slog from https://gist.github.com/8f79071f74a07605499ef7bc2380d699 In particular, all 4 votes go in one round trip: |
closes #3189
closes #3473