@agoric/inter-protocol 0.13.2-dev-44ea14f.0 → 0.13.2-dev-bdb08a7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/bundle-amm-meta.js +134 -134
- package/bundles/bundle-amm.js +1 -1
- package/bundles/bundle-econCommitteeCharter-meta.js +77 -77
- package/bundles/bundle-econCommitteeCharter.js +1 -1
- package/bundles/bundle-feeDistributor-meta.js +56 -56
- package/bundles/bundle-fluxAggregator-meta.js +300 -156
- package/bundles/bundle-fluxAggregator.js +1 -1
- package/bundles/bundle-interchainPool-meta.js +109 -109
- package/bundles/bundle-interchainPool.js +1 -1
- package/bundles/bundle-liquidateIncrementally-meta.js +71 -71
- package/bundles/bundle-liquidateMinimum-meta.js +71 -71
- package/bundles/bundle-psm-meta.js +112 -112
- package/bundles/bundle-psm.js +1 -1
- package/bundles/bundle-reserve-meta.js +112 -112
- package/bundles/bundle-reserve.js +1 -1
- package/bundles/bundle-scaledPriceAuthority-meta.js +72 -72
- package/bundles/bundle-stakeFactory-meta.js +118 -118
- package/bundles/bundle-stakeFactory.js +1 -1
- package/bundles/bundle-vaultFactory-meta.js +128 -128
- package/bundles/bundle-vaultFactory.js +1 -1
- package/package.json +16 -16
- package/scripts/build-bundles.js +4 -1
- package/scripts/price-feed-core.js +1 -1
- package/src/econCommitteeCharter.js +33 -0
- package/src/price/fluxAggregator.js +24 -32
- package/src/price/fluxAggregatorContract.js +118 -0
- package/src/price/roundsManager.js +5 -1
- package/src/proposals/price-feed-proposal.js +91 -63
- package/src/proposals/utils.js +8 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/inter-protocol",
|
|
3
|
-
"version": "0.13.2-dev-
|
|
3
|
+
"version": "0.13.2-dev-bdb08a7.0+bdb08a7",
|
|
4
4
|
"description": "Core cryptoeconomy contracts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@agoric/assert": "0.5.2-dev-
|
|
33
|
-
"@agoric/ertp": "0.15.4-dev-
|
|
34
|
-
"@agoric/governance": "0.9.2-dev-
|
|
35
|
-
"@agoric/internal": "0.2.2-dev-
|
|
36
|
-
"@agoric/notifier": "0.5.2-dev-
|
|
37
|
-
"@agoric/store": "0.8.4-dev-
|
|
38
|
-
"@agoric/swingset-liveslots": "0.9.1-dev-
|
|
39
|
-
"@agoric/swingset-vat": "0.30.3-dev-
|
|
40
|
-
"@agoric/time": "0.2.2-dev-
|
|
41
|
-
"@agoric/vat-data": "0.4.4-dev-
|
|
42
|
-
"@agoric/vats": "0.13.1-dev-
|
|
43
|
-
"@agoric/zoe": "0.25.4-dev-
|
|
32
|
+
"@agoric/assert": "0.5.2-dev-bdb08a7.0+bdb08a7",
|
|
33
|
+
"@agoric/ertp": "0.15.4-dev-bdb08a7.0+bdb08a7",
|
|
34
|
+
"@agoric/governance": "0.9.2-dev-bdb08a7.0+bdb08a7",
|
|
35
|
+
"@agoric/internal": "0.2.2-dev-bdb08a7.0+bdb08a7",
|
|
36
|
+
"@agoric/notifier": "0.5.2-dev-bdb08a7.0+bdb08a7",
|
|
37
|
+
"@agoric/store": "0.8.4-dev-bdb08a7.0+bdb08a7",
|
|
38
|
+
"@agoric/swingset-liveslots": "0.9.1-dev-bdb08a7.0+bdb08a7",
|
|
39
|
+
"@agoric/swingset-vat": "0.30.3-dev-bdb08a7.0+bdb08a7",
|
|
40
|
+
"@agoric/time": "0.2.2-dev-bdb08a7.0+bdb08a7",
|
|
41
|
+
"@agoric/vat-data": "0.4.4-dev-bdb08a7.0+bdb08a7",
|
|
42
|
+
"@agoric/vats": "0.13.1-dev-bdb08a7.0+bdb08a7",
|
|
43
|
+
"@agoric/zoe": "0.25.4-dev-bdb08a7.0+bdb08a7",
|
|
44
44
|
"@endo/bundle-source": "^2.4.2",
|
|
45
45
|
"@endo/captp": "^2.0.18",
|
|
46
46
|
"@endo/eventual-send": "^0.16.8",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"@endo/promise-kit": "^0.2.52"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@agoric/deploy-script-support": "0.9.5-dev-
|
|
54
|
-
"@agoric/smart-wallet": "0.4.3-dev-
|
|
53
|
+
"@agoric/deploy-script-support": "0.9.5-dev-bdb08a7.0+bdb08a7",
|
|
54
|
+
"@agoric/smart-wallet": "0.4.3-dev-bdb08a7.0+bdb08a7",
|
|
55
55
|
"@endo/init": "^0.5.52",
|
|
56
56
|
"@fast-check/ava": "^1.1.3",
|
|
57
57
|
"ava": "^5.1.0",
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
"publishConfig": {
|
|
79
79
|
"access": "public"
|
|
80
80
|
},
|
|
81
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "bdb08a7f80da1a20faea1139b3381b982c7fc203"
|
|
82
82
|
}
|
package/scripts/build-bundles.js
CHANGED
|
@@ -29,7 +29,10 @@ await createBundles(
|
|
|
29
29
|
'../src/econCommitteeCharter.js',
|
|
30
30
|
'../bundles/bundle-econCommitteeCharter.js',
|
|
31
31
|
],
|
|
32
|
-
[
|
|
32
|
+
[
|
|
33
|
+
'../src/price/fluxAggregatorContract.js',
|
|
34
|
+
'../bundles/bundle-fluxAggregator.js',
|
|
35
|
+
],
|
|
33
36
|
],
|
|
34
37
|
dirname,
|
|
35
38
|
);
|
|
@@ -57,7 +57,7 @@ export const defaultProposalBuilder = async (
|
|
|
57
57
|
brandOutRef: brandOut && publishRef(brandOut),
|
|
58
58
|
priceAggregatorRef: publishRef(
|
|
59
59
|
install(
|
|
60
|
-
'@agoric/inter-protocol/src/price/
|
|
60
|
+
'@agoric/inter-protocol/src/price/fluxAggregatorContract.js',
|
|
61
61
|
'../bundles/bundle-fluxAggregator.js',
|
|
62
62
|
),
|
|
63
63
|
),
|
|
@@ -79,6 +79,32 @@ export const start = async zcf => {
|
|
|
79
79
|
return zcf.makeInvitation(voteOnOfferFilterHandler, 'vote on offer filter');
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* @param {Instance} instance
|
|
84
|
+
* @param {string} methodName
|
|
85
|
+
* @param {string[]} methodArgs
|
|
86
|
+
* @param {import('@agoric/time').TimestampValue} deadline
|
|
87
|
+
*/
|
|
88
|
+
const makeApiInvocationInvitation = (
|
|
89
|
+
instance,
|
|
90
|
+
methodName,
|
|
91
|
+
methodArgs,
|
|
92
|
+
deadline,
|
|
93
|
+
) => {
|
|
94
|
+
const handler = seat => {
|
|
95
|
+
seat.exit();
|
|
96
|
+
|
|
97
|
+
const governor = instanceToGovernor.get(instance);
|
|
98
|
+
return E(governor).voteOnApiInvocation(
|
|
99
|
+
methodName,
|
|
100
|
+
methodArgs,
|
|
101
|
+
counter,
|
|
102
|
+
deadline,
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
return zcf.makeInvitation(handler, 'vote on API invocation');
|
|
106
|
+
};
|
|
107
|
+
|
|
82
108
|
const MakerI = M.interface('Charter InvitationMakers', {
|
|
83
109
|
VoteOnParamChange: M.call().returns(M.promise()),
|
|
84
110
|
VoteOnPauseOffers: M.call(
|
|
@@ -86,10 +112,17 @@ export const start = async zcf => {
|
|
|
86
112
|
M.arrayOf(M.string()),
|
|
87
113
|
TimestampShape,
|
|
88
114
|
).returns(M.promise()),
|
|
115
|
+
VoteOnApiCall: M.call(
|
|
116
|
+
InstanceHandleShape,
|
|
117
|
+
M.string(),
|
|
118
|
+
M.arrayOf(M.any()),
|
|
119
|
+
TimestampShape,
|
|
120
|
+
).returns(M.promise()),
|
|
89
121
|
});
|
|
90
122
|
const invitationMakers = makeExo('Charter Invitation Makers', MakerI, {
|
|
91
123
|
VoteOnParamChange: makeParamInvitation,
|
|
92
124
|
VoteOnPauseOffers: makeOfferFilterInvitation,
|
|
125
|
+
VoteOnApiCall: makeApiInvocationInvitation,
|
|
93
126
|
});
|
|
94
127
|
|
|
95
128
|
const charterMemberHandler = seat => {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Adaptation of Chainlink algorithm to the Agoric platform.
|
|
3
3
|
* Modeled on https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.6/FluxAggregator.sol (version?)
|
|
4
4
|
*/
|
|
5
|
-
import { AmountMath
|
|
6
|
-
import { assertAllDefined } from '@agoric/internal';
|
|
5
|
+
import { AmountMath } from '@agoric/ertp';
|
|
6
|
+
import { assertAllDefined, makeTracer } from '@agoric/internal';
|
|
7
7
|
import {
|
|
8
8
|
makeNotifierFromSubscriber,
|
|
9
9
|
observeNotifier,
|
|
@@ -20,6 +20,8 @@ import { Far } from '@endo/marshal';
|
|
|
20
20
|
import { makeOracleAdmin } from './priceOracleAdmin.js';
|
|
21
21
|
import { makeRoundsManagerKit } from './roundsManager.js';
|
|
22
22
|
|
|
23
|
+
const trace = makeTracer('FlxAgg', false);
|
|
24
|
+
|
|
23
25
|
export const INVITATION_MAKERS_DESC = 'oracle invitation';
|
|
24
26
|
|
|
25
27
|
/**
|
|
@@ -63,20 +65,26 @@ const priceDescriptionFromQuote = quote => quote.quoteAmount.value[0];
|
|
|
63
65
|
* the *Node Operator Aggregation* logic of [Chainlink price
|
|
64
66
|
* feeds](https://blog.chain.link/levels-of-data-aggregation-in-chainlink-price-feeds/).
|
|
65
67
|
*
|
|
68
|
+
* @param {Baggage} baggage
|
|
66
69
|
* @param {ZCF<ChainlinkConfig & {
|
|
67
70
|
* timer: TimerService,
|
|
68
71
|
* brandIn: Brand<'nat'>,
|
|
69
72
|
* brandOut: Brand<'nat'>,
|
|
70
73
|
* unitAmountIn?: Amount<'nat'>,
|
|
71
74
|
* }>} zcf
|
|
72
|
-
* @param {
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* }} privateArgs
|
|
77
|
-
* @param {Baggage} baggage
|
|
75
|
+
* @param {TimerService} timerPresence
|
|
76
|
+
* @param {IssuerRecord<'set'> & { mint: Mint<'set'> }} quoteKit
|
|
77
|
+
* @param {StorageNode} storageNode
|
|
78
|
+
* @param {Marshaller} marshaller
|
|
78
79
|
*/
|
|
79
|
-
export const
|
|
80
|
+
export const provideFluxAggregator = (
|
|
81
|
+
baggage,
|
|
82
|
+
zcf,
|
|
83
|
+
timerPresence,
|
|
84
|
+
quoteKit,
|
|
85
|
+
storageNode,
|
|
86
|
+
marshaller,
|
|
87
|
+
) => {
|
|
80
88
|
// brands come from named terms instead of `brands` key because the latter is
|
|
81
89
|
// a StandardTerm that Zoe creates from the `issuerKeywordRecord` argument and
|
|
82
90
|
// Oracle brands are inert (without issuers or mints).
|
|
@@ -89,7 +97,6 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
89
97
|
minSubmissionValue,
|
|
90
98
|
restartDelay,
|
|
91
99
|
timeout,
|
|
92
|
-
timer,
|
|
93
100
|
|
|
94
101
|
unitAmountIn = AmountMath.make(brandIn, 1n),
|
|
95
102
|
} = zcf.getTerms();
|
|
@@ -103,27 +110,9 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
103
110
|
minSubmissionValue,
|
|
104
111
|
restartDelay,
|
|
105
112
|
timeout,
|
|
106
|
-
timer,
|
|
107
113
|
unitAmountIn,
|
|
108
114
|
});
|
|
109
115
|
|
|
110
|
-
// Get the timer's identity.
|
|
111
|
-
const timerPresence = await timer;
|
|
112
|
-
|
|
113
|
-
const quoteMint =
|
|
114
|
-
privateArgs.quoteMint || makeIssuerKit('quote', AssetKind.SET).mint;
|
|
115
|
-
const quoteIssuerRecord = await zcf.saveIssuer(
|
|
116
|
-
E(quoteMint).getIssuer(),
|
|
117
|
-
'Quote',
|
|
118
|
-
);
|
|
119
|
-
const quoteKit = {
|
|
120
|
-
...quoteIssuerRecord,
|
|
121
|
-
mint: quoteMint,
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const { marshaller, storageNode } = privateArgs;
|
|
125
|
-
assertAllDefined({ marshaller, storageNode });
|
|
126
|
-
|
|
127
116
|
const makeDurablePublishKit = prepareDurablePublishKit(
|
|
128
117
|
baggage,
|
|
129
118
|
'Price Aggregator publish kit',
|
|
@@ -180,7 +169,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
180
169
|
createQuote: roundsManagerKit.contract.makeCreateQuote(),
|
|
181
170
|
notifier: makeNotifierFromSubscriber(answerSubscriber),
|
|
182
171
|
quoteIssuer: quoteKit.issuer,
|
|
183
|
-
timer,
|
|
172
|
+
timer: timerPresence,
|
|
184
173
|
actualBrandIn: brandIn,
|
|
185
174
|
actualBrandOut: brandOut,
|
|
186
175
|
});
|
|
@@ -212,6 +201,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
212
201
|
* @param {string} oracleId unique per contract instance
|
|
213
202
|
*/
|
|
214
203
|
makeOracleInvitation: async oracleId => {
|
|
204
|
+
trace('makeOracleInvitation', oracleId);
|
|
215
205
|
/**
|
|
216
206
|
* If custom arguments are supplied to the `zoe.offer` call, they can
|
|
217
207
|
* indicate an OraclePriceSubmission notifier and a corresponding
|
|
@@ -258,6 +248,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
258
248
|
|
|
259
249
|
/** @param {string} oracleId */
|
|
260
250
|
async initOracle(oracleId) {
|
|
251
|
+
trace('initOracle', oracleId);
|
|
261
252
|
assert.typeof(oracleId, 'string');
|
|
262
253
|
|
|
263
254
|
const oracleAdmin = makeOracleAdmin(
|
|
@@ -266,7 +257,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
266
257
|
maxSubmissionValue,
|
|
267
258
|
oracleId, // must be unique per vat
|
|
268
259
|
roundPowers: roundsManagerKit.oracle,
|
|
269
|
-
timer,
|
|
260
|
+
timer: timerPresence,
|
|
270
261
|
}),
|
|
271
262
|
);
|
|
272
263
|
oracles.init(oracleId, oracleAdmin);
|
|
@@ -283,7 +274,7 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
283
274
|
* @returns {Promise<RoundState>}
|
|
284
275
|
*/
|
|
285
276
|
async oracleRoundState(oracleId, queriedRoundId) {
|
|
286
|
-
const blockTimestamp = await E(
|
|
277
|
+
const blockTimestamp = await E(timerPresence).getCurrentTimestamp();
|
|
287
278
|
const status = await E(oracles.get(oracleId)).getStatus();
|
|
288
279
|
|
|
289
280
|
const oracleCount = oracles.getSize();
|
|
@@ -342,4 +333,5 @@ export const start = async (zcf, privateArgs, baggage) => {
|
|
|
342
333
|
|
|
343
334
|
return harden({ creatorFacet, publicFacet });
|
|
344
335
|
};
|
|
345
|
-
harden(
|
|
336
|
+
harden(provideFluxAggregator);
|
|
337
|
+
/** @typedef {ReturnType<typeof provideFluxAggregator>} FluxAggregator */
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { AssetKind, makeIssuerKit } from '@agoric/ertp';
|
|
2
|
+
import { handleParamGovernance } from '@agoric/governance';
|
|
3
|
+
import { assertAllDefined, makeTracer } from '@agoric/internal';
|
|
4
|
+
import { E } from '@endo/eventual-send';
|
|
5
|
+
import { reserveThenDeposit } from '../proposals/utils.js';
|
|
6
|
+
import { provideFluxAggregator } from './fluxAggregator.js';
|
|
7
|
+
|
|
8
|
+
const trace = makeTracer('FluxAgg', false);
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('@agoric/vat-data').Baggage} Baggage
|
|
11
|
+
* @typedef {import('@agoric/time/src/types').TimerService} TimerService
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* PriceAuthority for their median. Unlike the simpler `priceAggregator.js`, this approximates
|
|
16
|
+
* the *Node Operator Aggregation* logic of [Chainlink price
|
|
17
|
+
* feeds](https://blog.chain.link/levels-of-data-aggregation-in-chainlink-price-feeds/).
|
|
18
|
+
*
|
|
19
|
+
* @param {ZCF<import('./fluxAggregator.js').ChainlinkConfig & {
|
|
20
|
+
* timer: TimerService,
|
|
21
|
+
* brandIn: Brand<'nat'>,
|
|
22
|
+
* brandOut: Brand<'nat'>,
|
|
23
|
+
* unitAmountIn?: Amount<'nat'>,
|
|
24
|
+
* }>} zcf
|
|
25
|
+
* @param {{
|
|
26
|
+
* initialPoserInvitation: Invitation,
|
|
27
|
+
* marshaller: Marshaller,
|
|
28
|
+
* namesByAddressAdmin: ERef<import('@agoric/vats').NameAdmin>,
|
|
29
|
+
* quoteMint?: ERef<Mint<'set'>>,
|
|
30
|
+
* storageNode: ERef<StorageNode>,
|
|
31
|
+
* }} privateArgs
|
|
32
|
+
* @param {Baggage} baggage
|
|
33
|
+
*/
|
|
34
|
+
export const start = async (zcf, privateArgs, baggage) => {
|
|
35
|
+
trace('start');
|
|
36
|
+
const { timer: timerP } = zcf.getTerms();
|
|
37
|
+
|
|
38
|
+
const quoteMintP =
|
|
39
|
+
privateArgs.quoteMint || makeIssuerKit('quote', AssetKind.SET).mint;
|
|
40
|
+
const [quoteMint, quoteIssuerRecord] = await Promise.all([
|
|
41
|
+
quoteMintP,
|
|
42
|
+
zcf.saveIssuer(E(quoteMintP).getIssuer(), 'Quote'),
|
|
43
|
+
]);
|
|
44
|
+
const quoteKit = {
|
|
45
|
+
...quoteIssuerRecord,
|
|
46
|
+
mint: quoteMint,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const {
|
|
50
|
+
initialPoserInvitation,
|
|
51
|
+
marshaller,
|
|
52
|
+
namesByAddressAdmin,
|
|
53
|
+
storageNode: storageNodeP,
|
|
54
|
+
} = privateArgs;
|
|
55
|
+
assertAllDefined({ initialPoserInvitation, marshaller, storageNodeP });
|
|
56
|
+
|
|
57
|
+
const timer = await timerP;
|
|
58
|
+
const storageNode = await storageNodeP;
|
|
59
|
+
|
|
60
|
+
trace('awaited args');
|
|
61
|
+
|
|
62
|
+
const fa = provideFluxAggregator(
|
|
63
|
+
baggage,
|
|
64
|
+
zcf,
|
|
65
|
+
timer,
|
|
66
|
+
quoteKit,
|
|
67
|
+
storageNode,
|
|
68
|
+
marshaller,
|
|
69
|
+
);
|
|
70
|
+
trace('got fa', fa);
|
|
71
|
+
|
|
72
|
+
const { makeGovernorFacet } = await handleParamGovernance(
|
|
73
|
+
// @ts-expect-error FIXME include Governance params
|
|
74
|
+
zcf,
|
|
75
|
+
initialPoserInvitation,
|
|
76
|
+
{
|
|
77
|
+
// No governed parameters. Governance just for API methods.
|
|
78
|
+
},
|
|
79
|
+
storageNode,
|
|
80
|
+
marshaller,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Initialize a new oracle and send an invitation to administer it.
|
|
85
|
+
*
|
|
86
|
+
* @param {string} addr
|
|
87
|
+
*/
|
|
88
|
+
const addOracle = async addr => {
|
|
89
|
+
const invitation = await E(fa.creatorFacet).makeOracleInvitation(addr);
|
|
90
|
+
// XXX imported from 'proposals' path
|
|
91
|
+
await reserveThenDeposit(
|
|
92
|
+
`fluxAggregator oracle ${addr}`,
|
|
93
|
+
namesByAddressAdmin,
|
|
94
|
+
addr,
|
|
95
|
+
[invitation],
|
|
96
|
+
);
|
|
97
|
+
return `added ${addr}`;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const governedApis = {
|
|
101
|
+
/**
|
|
102
|
+
* Add the specified oracles. May partially fail, such that some oracles are added and others aren't.
|
|
103
|
+
*
|
|
104
|
+
* @param {string[]} oracleIds
|
|
105
|
+
* @returns {Promise<Array<PromiseSettledResult<string>>>}
|
|
106
|
+
*/
|
|
107
|
+
addOracles: oracleIds => {
|
|
108
|
+
return Promise.allSettled(oracleIds.map(addOracle));
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const governorFacet = makeGovernorFacet(fa.creatorFacet, governedApis);
|
|
113
|
+
return harden({
|
|
114
|
+
creatorFacet: governorFacet,
|
|
115
|
+
publicFacet: fa.publicFacet,
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
harden(start);
|
|
@@ -75,9 +75,13 @@ const validRoundId = roundId => {
|
|
|
75
75
|
* @property {number} roundTimeout
|
|
76
76
|
*/
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* @typedef {IssuerRecord<'set'> & { mint: Mint<'set'> }} QuoteKit
|
|
80
|
+
*/
|
|
81
|
+
|
|
78
82
|
/**
|
|
79
83
|
* @typedef {Readonly<import('./fluxAggregator.js').ChainlinkConfig & {
|
|
80
|
-
* quoteKit:
|
|
84
|
+
* quoteKit: QuoteKit,
|
|
81
85
|
* answerPublisher: Publisher<void>,
|
|
82
86
|
* brandIn: Brand<'nat'>,
|
|
83
87
|
* brandOut: Brand<'nat'>,
|
|
@@ -8,9 +8,10 @@ import {
|
|
|
8
8
|
import { deeplyFulfilledObject, makeTracer } from '@agoric/internal';
|
|
9
9
|
|
|
10
10
|
import { unitAmount } from '@agoric/zoe/src/contractSupport/priceQuote.js';
|
|
11
|
+
import { CONTRACT_ELECTORATE, ParamTypes } from '@agoric/governance';
|
|
11
12
|
import { reserveThenDeposit, reserveThenGetNames } from './utils.js';
|
|
12
13
|
|
|
13
|
-
const trace = makeTracer('RunPriceFeed');
|
|
14
|
+
const trace = makeTracer('RunPriceFeed', false);
|
|
14
15
|
|
|
15
16
|
/** @type {(name: string) => string} */
|
|
16
17
|
const sanitizePathSegment = name => {
|
|
@@ -92,17 +93,17 @@ export const createPriceFeed = async (
|
|
|
92
93
|
{
|
|
93
94
|
consume: {
|
|
94
95
|
agoricNamesAdmin,
|
|
95
|
-
aggregators,
|
|
96
96
|
board,
|
|
97
97
|
chainStorage,
|
|
98
98
|
chainTimerService,
|
|
99
99
|
client,
|
|
100
|
+
econCharterKit,
|
|
101
|
+
economicCommitteeCreatorFacet,
|
|
100
102
|
namesByAddressAdmin,
|
|
101
103
|
priceAuthority,
|
|
102
104
|
priceAuthorityAdmin,
|
|
103
105
|
zoe,
|
|
104
106
|
},
|
|
105
|
-
produce: { aggregators: produceAggregators },
|
|
106
107
|
},
|
|
107
108
|
{
|
|
108
109
|
options: {
|
|
@@ -119,8 +120,6 @@ export const createPriceFeed = async (
|
|
|
119
120
|
trace('createPriceFeed');
|
|
120
121
|
const STORAGE_PATH = 'priceFeed';
|
|
121
122
|
|
|
122
|
-
// Default to an empty Map and home.priceAuthority.
|
|
123
|
-
produceAggregators.resolve(new Map());
|
|
124
123
|
void E(client).assignBundle([_addr => ({ priceAuthority })]);
|
|
125
124
|
|
|
126
125
|
const timer = await chainTimerService;
|
|
@@ -128,62 +127,111 @@ export const createPriceFeed = async (
|
|
|
128
127
|
/**
|
|
129
128
|
* Values come from economy-template.json, which at this writing had IN:ATOM, OUT:USD
|
|
130
129
|
*
|
|
131
|
-
* @type {[[Brand<'nat'>, Brand<'nat'>], [Installation<import('@agoric/inter-protocol/src/price/
|
|
130
|
+
* @type {[[Brand<'nat'>, Brand<'nat'>], [Installation<import('@agoric/governance/src/contractGovernor.js').start>, Installation<import('@agoric/inter-protocol/src/price/fluxAggregatorContract.js').start>]]}
|
|
132
131
|
*/
|
|
133
|
-
const [[brandIn, brandOut], [priceAggregator]] =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
'
|
|
140
|
-
|
|
141
|
-
|
|
132
|
+
const [[brandIn, brandOut], [contractGovernor, priceAggregator]] =
|
|
133
|
+
await Promise.all([
|
|
134
|
+
reserveThenGetNames(E(agoricNamesAdmin).lookupAdmin('oracleBrand'), [
|
|
135
|
+
IN_BRAND_NAME,
|
|
136
|
+
OUT_BRAND_NAME,
|
|
137
|
+
]),
|
|
138
|
+
reserveThenGetNames(E(agoricNamesAdmin).lookupAdmin('installation'), [
|
|
139
|
+
'contractGovernor',
|
|
140
|
+
'priceAggregator',
|
|
141
|
+
]),
|
|
142
|
+
]);
|
|
143
|
+
|
|
144
|
+
trace('getPoserInvitation');
|
|
145
|
+
const poserInvitationP = E(
|
|
146
|
+
economicCommitteeCreatorFacet,
|
|
147
|
+
).getPoserInvitation();
|
|
148
|
+
const [initialPoserInvitation, electorateInvitationAmount] =
|
|
149
|
+
await Promise.all([
|
|
150
|
+
poserInvitationP,
|
|
151
|
+
E(E(zoe).getInvitationIssuer()).getAmountOf(poserInvitationP),
|
|
152
|
+
]);
|
|
153
|
+
trace('got initialPoserInvitation');
|
|
142
154
|
|
|
143
155
|
const unitAmountIn = await unitAmount(brandIn);
|
|
144
|
-
const terms =
|
|
156
|
+
const terms = harden({
|
|
157
|
+
...contractTerms,
|
|
158
|
+
description: AGORIC_INSTANCE_NAME,
|
|
159
|
+
brandIn,
|
|
160
|
+
brandOut,
|
|
161
|
+
timer,
|
|
162
|
+
unitAmountIn,
|
|
163
|
+
governedParams: {
|
|
164
|
+
[CONTRACT_ELECTORATE]: {
|
|
165
|
+
type: ParamTypes.INVITATION,
|
|
166
|
+
value: electorateInvitationAmount,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
trace('got terms');
|
|
171
|
+
|
|
172
|
+
const governorTerms = await deeplyFulfilledObject(
|
|
145
173
|
harden({
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
unitAmountIn,
|
|
174
|
+
timer: chainTimerService,
|
|
175
|
+
governedContractInstallation: priceAggregator,
|
|
176
|
+
governed: {
|
|
177
|
+
terms,
|
|
178
|
+
},
|
|
152
179
|
}),
|
|
153
180
|
);
|
|
181
|
+
trace('got governorTerms', governorTerms);
|
|
154
182
|
|
|
155
183
|
const storageNode = await makeStorageNodeChild(chainStorage, STORAGE_PATH);
|
|
156
184
|
const marshaller = E(board).getReadonlyMarshaller();
|
|
157
185
|
|
|
186
|
+
trace('got contractGovernor', contractGovernor);
|
|
187
|
+
|
|
188
|
+
trace('awaiting startInstance');
|
|
158
189
|
// Create the price feed.
|
|
159
|
-
|
|
160
|
-
|
|
190
|
+
/** @type {{ creatorFacet: import('@agoric/governance/src/contractGovernor.js').GovernedContractFnFacetAccess<import('@agoric/inter-protocol/src/price/fluxAggregator.contract.js').start>, publicFacet: GovernorPublic, instance: Instance, adminFacet: AdminFacet }} */
|
|
191
|
+
const aggregatorGovernor = await E(zoe).startInstance(
|
|
192
|
+
contractGovernor,
|
|
161
193
|
undefined,
|
|
162
|
-
|
|
194
|
+
governorTerms,
|
|
163
195
|
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
196
|
+
governed: {
|
|
197
|
+
initialPoserInvitation,
|
|
198
|
+
marshaller,
|
|
199
|
+
namesByAddressAdmin,
|
|
200
|
+
storageNode: E(storageNode).makeChildNode(
|
|
201
|
+
sanitizePathSegment(AGORIC_INSTANCE_NAME),
|
|
202
|
+
),
|
|
203
|
+
},
|
|
168
204
|
},
|
|
169
205
|
);
|
|
170
|
-
await E(
|
|
206
|
+
const faCreatorFacet = await E(
|
|
207
|
+
aggregatorGovernor.creatorFacet,
|
|
208
|
+
).getCreatorFacet();
|
|
209
|
+
trace('got aggregator', faCreatorFacet);
|
|
210
|
+
|
|
211
|
+
const faPublic = await E(aggregatorGovernor.creatorFacet).getPublicFacet();
|
|
212
|
+
const faInstance = await E(aggregatorGovernor.creatorFacet).getInstance();
|
|
213
|
+
trace('got', { faInstance, faPublic });
|
|
171
214
|
|
|
172
215
|
E(E(agoricNamesAdmin).lookupAdmin('instance')).update(
|
|
173
216
|
AGORIC_INSTANCE_NAME,
|
|
174
|
-
|
|
217
|
+
faInstance,
|
|
175
218
|
);
|
|
176
219
|
|
|
220
|
+
E(E.get(econCharterKit).creatorFacet).addInstance(
|
|
221
|
+
faInstance,
|
|
222
|
+
aggregatorGovernor.creatorFacet,
|
|
223
|
+
AGORIC_INSTANCE_NAME,
|
|
224
|
+
);
|
|
225
|
+
trace('registered', AGORIC_INSTANCE_NAME, faInstance);
|
|
226
|
+
|
|
177
227
|
// Publish price feed in home.priceAuthority.
|
|
178
228
|
const forceReplace = true;
|
|
179
|
-
void E(priceAuthorityAdmin)
|
|
180
|
-
.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
)
|
|
186
|
-
.then(deleter => E(aggregators).set(terms, { aggregator, deleter }));
|
|
229
|
+
void E(priceAuthorityAdmin).registerPriceAuthority(
|
|
230
|
+
E(faPublic).getPriceAuthority(),
|
|
231
|
+
brandIn,
|
|
232
|
+
brandOut,
|
|
233
|
+
forceReplace,
|
|
234
|
+
);
|
|
187
235
|
|
|
188
236
|
/**
|
|
189
237
|
* Initialize a new oracle and send an invitation to administer it.
|
|
@@ -191,9 +239,7 @@ export const createPriceFeed = async (
|
|
|
191
239
|
* @param {string} addr
|
|
192
240
|
*/
|
|
193
241
|
const addOracle = async addr => {
|
|
194
|
-
const invitation = await E(
|
|
195
|
-
addr,
|
|
196
|
-
);
|
|
242
|
+
const invitation = await E(faCreatorFacet).makeOracleInvitation(addr);
|
|
197
243
|
await reserveThenDeposit(
|
|
198
244
|
`${AGORIC_INSTANCE_NAME} member ${addr}`,
|
|
199
245
|
namesByAddressAdmin,
|
|
@@ -222,18 +268,19 @@ export const getManifestForPriceFeed = async (
|
|
|
222
268
|
manifest: {
|
|
223
269
|
[createPriceFeed.name]: {
|
|
224
270
|
consume: {
|
|
225
|
-
aggregators: t,
|
|
226
271
|
agoricNamesAdmin: t,
|
|
227
272
|
board: t,
|
|
228
273
|
chainStorage: t,
|
|
229
274
|
chainTimerService: t,
|
|
230
275
|
client: t,
|
|
276
|
+
contractGovernor: t,
|
|
277
|
+
econCharterKit: t,
|
|
278
|
+
economicCommitteeCreatorFacet: t,
|
|
231
279
|
namesByAddressAdmin: t,
|
|
232
280
|
priceAuthority: t,
|
|
233
281
|
priceAuthorityAdmin: t,
|
|
234
282
|
zoe: t,
|
|
235
283
|
},
|
|
236
|
-
produce: { aggregators: t },
|
|
237
284
|
},
|
|
238
285
|
[ensureOracleBrands.name]: {
|
|
239
286
|
consume: {
|
|
@@ -321,22 +368,3 @@ export const startPriceFeeds = async (
|
|
|
321
368
|
trace('startPriceFeeds complete');
|
|
322
369
|
};
|
|
323
370
|
harden(startPriceFeeds);
|
|
324
|
-
|
|
325
|
-
export const PRICE_FEEDS_MANIFEST = harden({
|
|
326
|
-
[startPriceFeeds.name]: {
|
|
327
|
-
consume: {
|
|
328
|
-
agoricNamesAdmin: true,
|
|
329
|
-
aggregators: true,
|
|
330
|
-
board: true,
|
|
331
|
-
chainStorage: true,
|
|
332
|
-
chainTimerService: true,
|
|
333
|
-
client: true,
|
|
334
|
-
namesByAddressAdmin: true,
|
|
335
|
-
priceAuthority: true,
|
|
336
|
-
priceAuthorityAdmin: true,
|
|
337
|
-
zoe: true,
|
|
338
|
-
},
|
|
339
|
-
produce: { aggregators: true },
|
|
340
|
-
installation: { consume: { priceAggregator: true } },
|
|
341
|
-
},
|
|
342
|
-
});
|
package/src/proposals/utils.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
+
import { WalletName } from '@agoric/internal';
|
|
1
2
|
import { getCopyMapEntries, makeCopyMap } from '@agoric/store';
|
|
2
3
|
import { E } from '@endo/far';
|
|
3
4
|
|
|
4
|
-
// must match packages/wallet/api/src/lib-wallet.js
|
|
5
|
-
export const DEPOSIT_FACET = 'depositFacet';
|
|
6
|
-
|
|
7
5
|
const { Fail } = assert;
|
|
8
6
|
|
|
9
7
|
/**
|
|
@@ -52,6 +50,12 @@ export const reserveThenGetNames = async (nameAdmin, names) =>
|
|
|
52
50
|
names.map(name => [name]),
|
|
53
51
|
);
|
|
54
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @param {string} debugName
|
|
55
|
+
* @param {ERef<import('@agoric/vats').NameAdmin>} namesByAddressAdmin
|
|
56
|
+
* @param {string} addr
|
|
57
|
+
* @param {Array<ERef<Payment>>} payments
|
|
58
|
+
*/
|
|
55
59
|
export const reserveThenDeposit = async (
|
|
56
60
|
debugName,
|
|
57
61
|
namesByAddressAdmin,
|
|
@@ -60,7 +64,7 @@ export const reserveThenDeposit = async (
|
|
|
60
64
|
) => {
|
|
61
65
|
console.info('awaiting depositFacet for', debugName);
|
|
62
66
|
const [depositFacet] = await reserveThenGetNamePaths(namesByAddressAdmin, [
|
|
63
|
-
[addr,
|
|
67
|
+
[addr, WalletName.depositFacet],
|
|
64
68
|
]);
|
|
65
69
|
console.info('depositing to', debugName);
|
|
66
70
|
await Promise.allSettled(
|