@agoric/inter-protocol 0.13.3 → 0.13.4-dev-d32a66a.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/README.md +26 -20
- package/bundles/bundle-auctioneer-js-meta.json +722 -0
- package/bundles/bundle-auctioneer.js +1 -0
- package/bundles/bundle-econCommitteeCharter-js-meta.json +514 -0
- package/bundles/bundle-econCommitteeCharter.js +1 -0
- package/bundles/bundle-feeDistributor-js-meta.json +458 -0
- package/bundles/bundle-feeDistributor.js +1 -1
- package/bundles/bundle-fluxAggregatorKit-js-meta.json +674 -0
- package/bundles/bundle-fluxAggregatorKit.js +1 -0
- package/bundles/bundle-psm-js-meta.json +666 -0
- package/bundles/bundle-psm.js +1 -1
- package/bundles/bundle-reserve-js-meta.json +662 -0
- package/bundles/bundle-reserve.js +1 -1
- package/bundles/bundle-scaledPriceAuthority-js-meta.json +542 -0
- package/bundles/bundle-scaledPriceAuthority.js +1 -1
- package/bundles/bundle-vaultFactory-js-meta.json +786 -0
- package/bundles/bundle-vaultFactory.js +1 -1
- package/exported.js +0 -2
- package/package.json +34 -31
- package/scripts/add-collateral-core.js +14 -4
- package/scripts/build-bundles.js +9 -2
- package/scripts/deploy-contracts.js +1 -4
- package/scripts/init-core.js +20 -38
- package/scripts/invite-committee-core.js +1 -1
- package/scripts/manual-price-feed.js +2 -2
- package/scripts/price-feed-core.js +7 -6
- package/scripts/start-local-chain.sh +84 -0
- package/src/auction/auctionBook.js +755 -0
- package/src/auction/auctioneer.js +720 -0
- package/src/auction/offerBook.js +221 -0
- package/src/auction/params.js +174 -0
- package/src/auction/scheduleMath.js +167 -0
- package/src/auction/scheduler.js +370 -0
- package/src/auction/sortedOffers.js +136 -0
- package/src/auction/util.js +55 -0
- package/src/clientSupport.js +324 -0
- package/src/collectFees.js +8 -14
- package/src/contractSupport.js +24 -68
- package/src/econCommitteeCharter.js +161 -77
- package/src/feeDistributor.js +60 -20
- package/src/index.js +2 -0
- package/src/interest-math.js +1 -4
- package/src/interest.js +20 -13
- package/src/price/README.md +57 -0
- package/src/price/fluxAggregatorContract.js +190 -0
- package/src/price/fluxAggregatorKit.js +375 -0
- package/src/price/priceOracleKit.js +127 -0
- package/src/price/roundsManager.js +726 -0
- package/src/proposals/addAssetToVault.js +89 -94
- package/src/proposals/committee-proposal.js +141 -40
- package/src/proposals/core-proposal.js +100 -167
- package/src/proposals/econ-behaviors.js +320 -564
- package/src/proposals/price-feed-proposal.js +175 -78
- package/src/proposals/startEconCommittee.js +25 -12
- package/src/proposals/startPSM.js +231 -211
- package/src/proposals/utils.js +31 -17
- package/src/psm/README.md +71 -0
- package/src/psm/psm.js +272 -160
- package/src/psm/types.js +2 -0
- package/src/reserve/assetReserve.js +56 -413
- package/src/reserve/assetReserveKit.js +303 -0
- package/src/reserve/doc.md +1 -3
- package/src/reserve/params.js +2 -5
- package/src/typeGuards.js +13 -0
- package/src/vaultFactory/Liquidation.md +100 -0
- package/src/vaultFactory/burn.js +2 -1
- package/src/vaultFactory/liquidation.js +270 -108
- package/src/vaultFactory/math.js +95 -0
- package/src/vaultFactory/orderedVaultStore.js +0 -1
- package/src/vaultFactory/params.js +133 -112
- package/src/vaultFactory/prioritizedVaults.js +36 -79
- package/src/vaultFactory/storeUtils.js +67 -9
- package/src/vaultFactory/type-imports.js +2 -0
- package/src/vaultFactory/types.js +22 -26
- package/src/vaultFactory/vault.js +772 -709
- package/src/vaultFactory/vaultDirector.js +480 -483
- package/src/vaultFactory/vaultFactory.js +99 -60
- package/src/vaultFactory/vaultHolder.js +121 -95
- package/src/vaultFactory/vaultKit.js +39 -31
- package/src/vaultFactory/vaultManager.js +1249 -868
- package/bundles/bundle-amm-meta.js +0 -618
- package/bundles/bundle-amm.js +0 -1
- package/bundles/bundle-feeDistributor-meta.js +0 -346
- package/bundles/bundle-interchainPool-meta.js +0 -534
- package/bundles/bundle-interchainPool.js +0 -1
- package/bundles/bundle-liquidateIncrementally-meta.js +0 -442
- package/bundles/bundle-liquidateIncrementally.js +0 -1
- package/bundles/bundle-liquidateMinimum-meta.js +0 -442
- package/bundles/bundle-liquidateMinimum.js +0 -1
- package/bundles/bundle-psm-meta.js +0 -538
- package/bundles/bundle-psmCharter-meta.js +0 -418
- package/bundles/bundle-psmCharter.js +0 -1
- package/bundles/bundle-reserve-meta.js +0 -542
- package/bundles/bundle-scaledPriceAuthority-meta.js +0 -442
- package/bundles/bundle-stakeFactory-meta.js +0 -574
- package/bundles/bundle-stakeFactory.js +0 -1
- package/bundles/bundle-vaultFactory-meta.js +0 -598
- package/scripts/add-initial-liquidity.js +0 -180
- package/src/collect.js +0 -13
- package/src/interchainPool.js +0 -135
- package/src/makeTracer.js +0 -36
- package/src/my-lien.js +0 -85
- package/src/proposals/demoIssuers.js +0 -685
- package/src/proposals/sim-behaviors.js +0 -40
- package/src/psm/psmCharter.js +0 -139
- package/src/stakeFactory/README.md +0 -62
- package/src/stakeFactory/attestation.js +0 -267
- package/src/stakeFactory/attestationTool.js +0 -66
- package/src/stakeFactory/constants.js +0 -16
- package/src/stakeFactory/params.js +0 -31
- package/src/stakeFactory/stakeFactory.js +0 -236
- package/src/stakeFactory/stakeFactoryKit.js +0 -455
- package/src/stakeFactory/stakeFactoryManager.js +0 -296
- package/src/stakeFactory/types.js +0 -42
- package/src/vaultFactory/liquidateIncrementally.js +0 -350
- package/src/vaultFactory/liquidateMinimum.js +0 -100
- package/src/vpool-xyk-amm/AttackersGuide.md +0 -89
- package/src/vpool-xyk-amm/addLiquidity.js +0 -222
- package/src/vpool-xyk-amm/addPool.js +0 -197
- package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
- package/src/vpool-xyk-amm/constantProduct/README.md +0 -204
- package/src/vpool-xyk-amm/constantProduct/calcFees.js +0 -99
- package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +0 -85
- package/src/vpool-xyk-amm/constantProduct/core.js +0 -153
- package/src/vpool-xyk-amm/constantProduct/defaults.js +0 -5
- package/src/vpool-xyk-amm/constantProduct/getXY.js +0 -52
- package/src/vpool-xyk-amm/constantProduct/internal-types.js +0 -116
- package/src/vpool-xyk-amm/constantProduct/invariants.js +0 -43
- package/src/vpool-xyk-amm/constantProduct/swap.js +0 -272
- package/src/vpool-xyk-amm/constantProduct/types.js +0 -32
- package/src/vpool-xyk-amm/doublePool.js +0 -194
- package/src/vpool-xyk-amm/estimate.js +0 -155
- package/src/vpool-xyk-amm/multipoolMarketMaker.js +0 -520
- package/src/vpool-xyk-amm/params.js +0 -61
- package/src/vpool-xyk-amm/pool.js +0 -396
- package/src/vpool-xyk-amm/priceAuthority.js +0 -94
- package/src/vpool-xyk-amm/removeLiquidity.js +0 -31
- package/src/vpool-xyk-amm/singlePool.js +0 -73
- package/src/vpool-xyk-amm/swap.js +0 -69
- package/src/vpool-xyk-amm/types.js +0 -154
|
@@ -1,102 +1,186 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
2
|
|
|
3
|
-
import '@agoric/governance/
|
|
3
|
+
import '@agoric/governance/exported.js';
|
|
4
|
+
import { M, mustMatch } from '@agoric/store';
|
|
5
|
+
import { TimestampShape } from '@agoric/time';
|
|
6
|
+
import { prepareExo, provideDurableMapStore } from '@agoric/vat-data';
|
|
4
7
|
import '@agoric/zoe/exported.js';
|
|
5
8
|
import '@agoric/zoe/src/contracts/exported.js';
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
import {
|
|
10
|
+
InstallationShape,
|
|
11
|
+
InstanceHandleShape,
|
|
12
|
+
} from '@agoric/zoe/src/typeGuards.js';
|
|
13
|
+
import { E } from '@endo/far';
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* @file
|
|
11
17
|
*
|
|
12
|
-
* This
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
* This contract makes it possible for those who govern contracts to call for
|
|
19
|
+
* votes on changes. A more complete implementation would validate parameters,
|
|
20
|
+
* constrain deadlines and possibly split the ability to call for votes into
|
|
21
|
+
* separate capabilities for finer grain encapsulation.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export const INVITATION_MAKERS_DESC = 'charter member invitation';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {object} ParamChangesOfferArgs
|
|
28
|
+
* @property {bigint} deadline
|
|
29
|
+
* @property {Instance} instance
|
|
30
|
+
* @property {Record<string, unknown>} params
|
|
31
|
+
* @property {{paramPath: { key: string }}} [path]
|
|
18
32
|
*/
|
|
33
|
+
const ParamChangesOfferArgsShape = M.splitRecord(
|
|
34
|
+
{
|
|
35
|
+
deadline: TimestampShape,
|
|
36
|
+
instance: InstanceHandleShape,
|
|
37
|
+
params: M.recordOf(M.string(), M.any()),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
path: { paramPath: { key: M.any() } },
|
|
41
|
+
},
|
|
42
|
+
);
|
|
19
43
|
|
|
20
44
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @param {{reserve:GovernedContractFacetAccess<{},{}>, amm:GovernedCreatorFacet<{}>, vaults:GovernedCreatorFacet<{}>}} privateArgs
|
|
45
|
+
* A pattern for Zoe to check custom terms before `start()`ing the contract.
|
|
23
46
|
*/
|
|
24
|
-
export const
|
|
47
|
+
export const customTermsShape = harden({
|
|
48
|
+
binaryVoteCounterInstallation: InstallationShape,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {ZCF<{binaryVoteCounterInstallation: Installation}>} zcf
|
|
53
|
+
* @param {undefined} privateArgs
|
|
54
|
+
* @param {import('@agoric/vat-data').Baggage} baggage
|
|
55
|
+
*/
|
|
56
|
+
export const prepare = async (zcf, privateArgs, baggage) => {
|
|
25
57
|
const { binaryVoteCounterInstallation: counter } = zcf.getTerms();
|
|
26
|
-
|
|
58
|
+
/** @type {MapStore<Instance, GovernorCreatorFacet<any>>} */
|
|
59
|
+
const instanceToGovernor = provideDurableMapStore(
|
|
60
|
+
baggage,
|
|
61
|
+
'instanceToGovernor',
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const makeParamInvitation = () => {
|
|
65
|
+
/**
|
|
66
|
+
* @param {ZCFSeat} seat
|
|
67
|
+
* @param {ParamChangesOfferArgs} args
|
|
68
|
+
*/
|
|
69
|
+
const voteOnParamChanges = (seat, args) => {
|
|
70
|
+
mustMatch(args, ParamChangesOfferArgsShape);
|
|
71
|
+
seat.exit();
|
|
72
|
+
|
|
73
|
+
const {
|
|
74
|
+
params,
|
|
75
|
+
instance,
|
|
76
|
+
deadline,
|
|
77
|
+
path = { paramPath: { key: 'governedApi' } },
|
|
78
|
+
} = args;
|
|
79
|
+
const governor = instanceToGovernor.get(instance);
|
|
80
|
+
return E(governor).voteOnParamChanges(counter, deadline, {
|
|
81
|
+
...path,
|
|
82
|
+
changes: params,
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return zcf.makeInvitation(voteOnParamChanges, 'vote on param changes');
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const makeOfferFilterInvitation = (instance, strings, deadline) => {
|
|
90
|
+
const voteOnOfferFilterHandler = seat => {
|
|
91
|
+
seat.exit();
|
|
92
|
+
|
|
93
|
+
const governor = instanceToGovernor.get(instance);
|
|
94
|
+
return E(governor).voteOnOfferFilter(counter, deadline, strings);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return zcf.makeInvitation(voteOnOfferFilterHandler, 'vote on offer filter');
|
|
98
|
+
};
|
|
27
99
|
|
|
28
100
|
/**
|
|
29
|
-
* @param {
|
|
30
|
-
* @param {
|
|
31
|
-
* @param {
|
|
32
|
-
* @param {
|
|
101
|
+
* @param {Instance} instance
|
|
102
|
+
* @param {string} methodName
|
|
103
|
+
* @param {string[]} methodArgs
|
|
104
|
+
* @param {import('@agoric/time').TimestampValue} deadline
|
|
33
105
|
*/
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
106
|
+
const makeApiInvocationInvitation = (
|
|
107
|
+
instance,
|
|
108
|
+
methodName,
|
|
109
|
+
methodArgs,
|
|
37
110
|
deadline,
|
|
38
|
-
path = { paramPath: { key: 'governedApi' } },
|
|
39
111
|
) => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
changes: params,
|
|
43
|
-
});
|
|
44
|
-
};
|
|
112
|
+
const handler = seat => {
|
|
113
|
+
seat.exit();
|
|
45
114
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
115
|
+
const governor = instanceToGovernor.get(instance);
|
|
116
|
+
return E(governor).voteOnApiInvocation(
|
|
117
|
+
methodName,
|
|
118
|
+
methodArgs,
|
|
119
|
+
counter,
|
|
120
|
+
deadline,
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
return zcf.makeInvitation(handler, 'vote on API invocation');
|
|
54
124
|
};
|
|
55
125
|
|
|
56
|
-
const
|
|
57
|
-
|
|
126
|
+
const MakerI = M.interface('Charter InvitationMakers', {
|
|
127
|
+
VoteOnParamChange: M.call().returns(M.promise()),
|
|
128
|
+
VoteOnPauseOffers: M.call(
|
|
129
|
+
InstanceHandleShape,
|
|
130
|
+
M.arrayOf(M.string()),
|
|
131
|
+
TimestampShape,
|
|
132
|
+
).returns(M.promise()),
|
|
133
|
+
VoteOnApiCall: M.call(
|
|
134
|
+
InstanceHandleShape,
|
|
135
|
+
M.string(),
|
|
136
|
+
M.arrayOf(M.any()),
|
|
137
|
+
TimestampShape,
|
|
138
|
+
).returns(M.promise()),
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// durable so that when this contract is upgraded this ocap held
|
|
142
|
+
// by committee members (from their invitations) stay capable
|
|
143
|
+
const invitationMakers = prepareExo(
|
|
144
|
+
baggage,
|
|
145
|
+
'Charter Invitation Makers',
|
|
146
|
+
MakerI,
|
|
147
|
+
{
|
|
148
|
+
VoteOnParamChange: makeParamInvitation,
|
|
149
|
+
VoteOnPauseOffers: makeOfferFilterInvitation,
|
|
150
|
+
VoteOnApiCall: makeApiInvocationInvitation,
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const charterMemberHandler = seat => {
|
|
155
|
+
seat.exit();
|
|
156
|
+
return harden({ invitationMakers });
|
|
58
157
|
};
|
|
59
158
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
voteOnAmmParamChanges: (params, deadline) =>
|
|
66
|
-
voteOnParamChanges(amm, params, deadline),
|
|
67
|
-
/**
|
|
68
|
-
* @param {Record<string, unknown>} params
|
|
69
|
-
* @param {bigint} deadline
|
|
70
|
-
*/
|
|
71
|
-
voteOnReserveParamChanges: (params, deadline) =>
|
|
72
|
-
voteOnParamChanges(reserve, params, deadline),
|
|
73
|
-
/**
|
|
74
|
-
* vote on param changes for a vaultManager
|
|
75
|
-
*
|
|
76
|
-
* @param {Record<string, unknown>} params
|
|
77
|
-
* @param {{collateralBrand: Brand}} brand
|
|
78
|
-
* @param {bigint} deadline
|
|
79
|
-
*/
|
|
80
|
-
voteOnVaultParamChanges: (params, brand, deadline) =>
|
|
81
|
-
voteOnParamChanges(vaults, params, deadline, {
|
|
82
|
-
paramPath: { key: brand },
|
|
83
|
-
}),
|
|
84
|
-
/**
|
|
85
|
-
* vote on param changes across the vaultFactory
|
|
86
|
-
*
|
|
87
|
-
* @param {Record<string, unknown>} params
|
|
88
|
-
* @param {bigint} deadline
|
|
89
|
-
*/
|
|
90
|
-
voteOnVaultFactoryParamChanges: (params, deadline) =>
|
|
91
|
-
voteOnParamChanges(vaults, params, deadline),
|
|
92
|
-
/**
|
|
93
|
-
* @param {Amount[]} amounts
|
|
94
|
-
* @param {bigint} deadline
|
|
95
|
-
*/
|
|
96
|
-
voteOnReserveApiInvocation: (amounts, deadline) =>
|
|
97
|
-
voteOnApiInvocation(reserve, 'addLiquidityToAmmPool', amounts, deadline),
|
|
98
|
-
makeNullInvitation,
|
|
159
|
+
const charterCreatorI = M.interface('Charter creatorFacet', {
|
|
160
|
+
addInstance: M.call(InstanceHandleShape, M.any())
|
|
161
|
+
.optional(M.string())
|
|
162
|
+
.returns(),
|
|
163
|
+
makeCharterMemberInvitation: M.call().returns(M.promise()),
|
|
99
164
|
});
|
|
100
165
|
|
|
101
|
-
|
|
166
|
+
const creatorFacet = prepareExo(
|
|
167
|
+
baggage,
|
|
168
|
+
'Charter creatorFacet',
|
|
169
|
+
charterCreatorI,
|
|
170
|
+
{
|
|
171
|
+
/**
|
|
172
|
+
* @param {Instance} governedInstance
|
|
173
|
+
* @param {GovernorCreatorFacet<any>} governorFacet
|
|
174
|
+
* @param {string} [label] for diagnostic use only
|
|
175
|
+
*/
|
|
176
|
+
addInstance: (governedInstance, governorFacet, label) => {
|
|
177
|
+
console.log('charter: adding instance', label);
|
|
178
|
+
instanceToGovernor.init(governedInstance, governorFacet);
|
|
179
|
+
},
|
|
180
|
+
makeCharterMemberInvitation: () =>
|
|
181
|
+
zcf.makeInvitation(charterMemberHandler, INVITATION_MAKERS_DESC),
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
return harden({ creatorFacet });
|
|
102
186
|
};
|
package/src/feeDistributor.js
CHANGED
|
@@ -1,16 +1,32 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
1
|
import { AmountMath } from '@agoric/ertp';
|
|
2
|
+
import { splitMany } from '@agoric/ertp/src/legacy-payment-helpers.js';
|
|
4
3
|
import { E, Far } from '@endo/far';
|
|
4
|
+
import { Nat } from '@endo/nat';
|
|
5
5
|
import { observeNotifier } from '@agoric/notifier';
|
|
6
|
-
import { makeScalarSetStore } from '@agoric/store';
|
|
6
|
+
import { mustMatch, makeScalarSetStore, M } from '@agoric/store';
|
|
7
|
+
import { RelativeTimeShape } from '@agoric/time';
|
|
8
|
+
import { KeywordShape } from '@agoric/zoe/src/typeGuards.js';
|
|
9
|
+
|
|
10
|
+
const KeywordSharesShape = M.recordOf(KeywordShape, M.nat());
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A pattern for Zoe to check custom terms before `start()`ing the contract.
|
|
14
|
+
*/
|
|
15
|
+
export const customTermsShape = harden({
|
|
16
|
+
keywordShares: KeywordSharesShape,
|
|
17
|
+
timerService: M.eref(M.remotable('TimerService')),
|
|
18
|
+
collectionInterval: RelativeTimeShape,
|
|
19
|
+
});
|
|
7
20
|
|
|
8
|
-
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {import('@agoric/time/src/types').RelativeTime} RelativeTime
|
|
23
|
+
* @typedef {import('@agoric/time/src/types').TimerService} TimerService
|
|
24
|
+
*/
|
|
9
25
|
|
|
10
26
|
/**
|
|
11
27
|
* @typedef {object} FeeCollector
|
|
12
28
|
*
|
|
13
|
-
* @property {() => ERef<Payment
|
|
29
|
+
* @property {() => ERef<Payment<'nat'>>} collectFees
|
|
14
30
|
*/
|
|
15
31
|
|
|
16
32
|
/**
|
|
@@ -22,11 +38,11 @@ const { details: X } = assert;
|
|
|
22
38
|
|
|
23
39
|
/**
|
|
24
40
|
* @typedef {object} CollectibleContractFacet
|
|
25
|
-
* @property {() => Promise<Invitation
|
|
41
|
+
* @property {() => Promise<Invitation<string, never>>} makeCollectFeesInvitation
|
|
26
42
|
*/
|
|
27
43
|
|
|
28
44
|
/**
|
|
29
|
-
* wrapper to take the
|
|
45
|
+
* wrapper to take the a creatorFacet (e.g. vaultFactory) and make a call that
|
|
30
46
|
* will request an invitation and return a promise for a payment.
|
|
31
47
|
*
|
|
32
48
|
* @param {ERef<ZoeService>} zoe
|
|
@@ -86,15 +102,14 @@ export const startDistributing = (
|
|
|
86
102
|
* @typedef {{ pushPayment: (payment: Payment, issuer: ERef<Issuer>) => Promise<Amount>}} FeeDestination
|
|
87
103
|
*
|
|
88
104
|
* @param {Record<Keyword, ERef<FeeDestination>>} [destinations]
|
|
89
|
-
* @param {Record<Keyword,
|
|
105
|
+
* @param {Record<Keyword, NatValue>} [keywordShares]
|
|
90
106
|
*/
|
|
91
107
|
export const makeShareConfig = (destinations = {}, keywordShares = {}) => {
|
|
92
108
|
let totalShares = 0n;
|
|
93
109
|
const shares = Object.entries(destinations)
|
|
94
110
|
.filter(([_, dst]) => dst)
|
|
95
111
|
.map(([kw, destination]) => {
|
|
96
|
-
const share = keywordShares[kw];
|
|
97
|
-
assert.typeof(share, 'bigint', X`${kw} must be a bigint; got ${share}`);
|
|
112
|
+
const share = Nat(keywordShares[kw]);
|
|
98
113
|
totalShares += share;
|
|
99
114
|
return {
|
|
100
115
|
share,
|
|
@@ -109,8 +124,8 @@ export const makeShareConfig = (destinations = {}, keywordShares = {}) => {
|
|
|
109
124
|
/**
|
|
110
125
|
* Split and deposit a payment given a share configuration.
|
|
111
126
|
*
|
|
112
|
-
* @param {Payment} payment
|
|
113
|
-
* @param {ERef<Issuer
|
|
127
|
+
* @param {Payment<'nat'>} payment
|
|
128
|
+
* @param {ERef<Issuer<'nat'>>} issuer
|
|
114
129
|
* @param {ShareConfig} shareConfig
|
|
115
130
|
*/
|
|
116
131
|
export const sharePayment = async (
|
|
@@ -145,8 +160,25 @@ export const sharePayment = async (
|
|
|
145
160
|
})
|
|
146
161
|
.filter(([_, amt]) => !AmountMath.isEmpty(amt));
|
|
147
162
|
|
|
163
|
+
/**
|
|
164
|
+
* If the `sharedPayment[i]` payments that are sent to the fee
|
|
165
|
+
* `destination` with `pushPayment` never arrive, or never get deposited
|
|
166
|
+
* (or otherwise used up), then they remain in the recovery set of the
|
|
167
|
+
* `recoveryPurse`. The purpose of this, and of recovery sets in general,
|
|
168
|
+
* is to be able, in emergencies, to recover the assets of payments in flight
|
|
169
|
+
* that seem to be stuck. This is much like cancelling a check that may still
|
|
170
|
+
* be undeposited.
|
|
171
|
+
*
|
|
172
|
+
* TODO: However, for this to be possible, the `recoveryPurse` holding that
|
|
173
|
+
* recovery set must remain accessible to someone that should legitimately
|
|
174
|
+
* be able to recover those payments. But this `recoveryPurse` is currently
|
|
175
|
+
* dropped on the floor instead.
|
|
176
|
+
*/
|
|
177
|
+
const recoveryPurse = E(issuer).makeEmptyPurse();
|
|
178
|
+
|
|
148
179
|
// Split the payment, which asserts conservation of the total.
|
|
149
|
-
const sharedPayment = await
|
|
180
|
+
const sharedPayment = await splitMany(
|
|
181
|
+
recoveryPurse,
|
|
150
182
|
payment,
|
|
151
183
|
destinedAmountEntries.map(([_dst, amt]) => amt),
|
|
152
184
|
);
|
|
@@ -160,20 +192,21 @@ export const sharePayment = async (
|
|
|
160
192
|
};
|
|
161
193
|
|
|
162
194
|
/**
|
|
163
|
-
* @param {ERef<Issuer
|
|
164
|
-
* @param {{ keywordShares: Record<Keyword,
|
|
195
|
+
* @param {ERef<Issuer<'nat'>>} feeIssuer
|
|
196
|
+
* @param {{ keywordShares: Record<Keyword, NatValue>, timerService: ERef<TimerService>, collectionInterval: RelativeTime}} terms
|
|
165
197
|
*/
|
|
166
198
|
export const makeFeeDistributor = (feeIssuer, terms) => {
|
|
167
199
|
const { timerService, collectionInterval } = terms;
|
|
168
200
|
|
|
169
201
|
/** @type {Record<string, ERef<FeeDestination>>} */
|
|
170
202
|
let destinations = {};
|
|
171
|
-
let
|
|
203
|
+
let { keywordShares } = terms;
|
|
204
|
+
let shareConfig = makeShareConfig(destinations, keywordShares);
|
|
172
205
|
|
|
173
206
|
/** @type {SetStore<FeeCollector>} */
|
|
174
207
|
const collectors = makeScalarSetStore();
|
|
175
208
|
|
|
176
|
-
/** @param {Payment} payment */
|
|
209
|
+
/** @param {Payment<'nat'>} payment */
|
|
177
210
|
const distributeFees = payment =>
|
|
178
211
|
sharePayment(payment, feeIssuer, shareConfig);
|
|
179
212
|
|
|
@@ -190,6 +223,7 @@ export const makeFeeDistributor = (feeIssuer, terms) => {
|
|
|
190
223
|
|
|
191
224
|
const publicFacet = Far('feeDistributor publicFacet', {
|
|
192
225
|
distributeFees,
|
|
226
|
+
getKeywordShares: () => keywordShares,
|
|
193
227
|
});
|
|
194
228
|
|
|
195
229
|
const creatorFacet = Far('feeDistributor creatorFacet', {
|
|
@@ -228,7 +262,7 @@ export const makeFeeDistributor = (feeIssuer, terms) => {
|
|
|
228
262
|
},
|
|
229
263
|
|
|
230
264
|
/**
|
|
231
|
-
* @param {EOnly<DepositFacet>} depositFacet
|
|
265
|
+
* @param {import('@endo/far').EOnly<DepositFacet>} depositFacet
|
|
232
266
|
*/
|
|
233
267
|
makeDepositFacetDestination: depositFacet => {
|
|
234
268
|
return Far(`DepositFacetDestination`, {
|
|
@@ -282,14 +316,20 @@ export const makeFeeDistributor = (feeIssuer, terms) => {
|
|
|
282
316
|
},
|
|
283
317
|
|
|
284
318
|
/**
|
|
285
|
-
* @param {Record<Keyword, FeeDestination
|
|
319
|
+
* @param {Record<Keyword, ERef<FeeDestination>>} newDestinations
|
|
286
320
|
*/
|
|
287
321
|
setDestinations: async newDestinations => {
|
|
288
322
|
destinations = newDestinations;
|
|
289
|
-
shareConfig = makeShareConfig(destinations,
|
|
323
|
+
shareConfig = makeShareConfig(destinations, keywordShares);
|
|
290
324
|
// Run once immediately for these destinations.
|
|
291
325
|
await schedulePayments();
|
|
292
326
|
},
|
|
327
|
+
|
|
328
|
+
/** @param {Record<Keyword, bigint>} newShares */
|
|
329
|
+
setKeywordShares: newShares => {
|
|
330
|
+
mustMatch(newShares, KeywordSharesShape);
|
|
331
|
+
keywordShares = newShares;
|
|
332
|
+
},
|
|
293
333
|
});
|
|
294
334
|
|
|
295
335
|
// Start processing collections.
|
package/src/index.js
CHANGED
package/src/interest-math.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
divideBy,
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
} from '@agoric/zoe/src/contractSupport/ratio.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
12
|
* @param {Ratio} currentCompoundedInterest as coefficient
|
|
14
13
|
* @param {Ratio} previousCompoundedInterest as coefficient
|
|
15
14
|
* @returns {Ratio} additional compounding since the previous
|
|
@@ -26,7 +25,6 @@ const calculateRelativeCompounding = (
|
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
|
-
*
|
|
30
28
|
* @param {Amount<'nat'>} debtSnapshot
|
|
31
29
|
* @param {Ratio} interestSnapshot as coefficient
|
|
32
30
|
* @param {Ratio} currentCompoundedInterest as coefficient
|
|
@@ -50,7 +48,6 @@ export const calculateCurrentDebt = (
|
|
|
50
48
|
};
|
|
51
49
|
|
|
52
50
|
/**
|
|
53
|
-
*
|
|
54
51
|
* @param {Amount<'nat'>} debt
|
|
55
52
|
* @param {Ratio} interestApplied
|
|
56
53
|
* @returns {Amount<'nat'>}
|
package/src/interest.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
2
|
|
|
3
3
|
import { AmountMath } from '@agoric/ertp';
|
|
4
4
|
import { natSafeMath } from '@agoric/zoe/src/contractSupport/index.js';
|
|
@@ -7,8 +7,13 @@ import {
|
|
|
7
7
|
multiplyRatios,
|
|
8
8
|
quantize,
|
|
9
9
|
} from '@agoric/zoe/src/contractSupport/ratio.js';
|
|
10
|
-
import {
|
|
11
|
-
import { TimeMath } from '@agoric/
|
|
10
|
+
import { Fail } from '@agoric/assert';
|
|
11
|
+
import { TimeMath } from '@agoric/time';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {import('@agoric/time/src/types').Timestamp} Timestamp
|
|
15
|
+
* @typedef {import('@agoric/time/src/types').RelativeTime} RelativeTime
|
|
16
|
+
*/
|
|
12
17
|
|
|
13
18
|
export const SECONDS_PER_YEAR = 60n * 60n * 24n * 365n;
|
|
14
19
|
const BASIS_POINTS = 10000;
|
|
@@ -126,18 +131,15 @@ export const calculateCompoundedInterest = (
|
|
|
126
131
|
};
|
|
127
132
|
|
|
128
133
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* @param {
|
|
132
|
-
* @param {Amount} debt
|
|
134
|
+
* @template {AssetKind} K
|
|
135
|
+
* @param {ZCFMint<K>} mint
|
|
136
|
+
* @param {Amount<K>} debt
|
|
133
137
|
*/
|
|
134
138
|
const validatedBrand = (mint, debt) => {
|
|
135
139
|
const { brand: debtBrand } = debt;
|
|
136
140
|
const { brand: issuerBrand } = mint.getIssuerRecord();
|
|
137
141
|
debtBrand === issuerBrand ||
|
|
138
|
-
|
|
139
|
-
X`Debt and issuer brands differ: ${debtBrand} != ${issuerBrand}`,
|
|
140
|
-
);
|
|
142
|
+
Fail`Debt and issuer brands differ: ${debtBrand} != ${issuerBrand}`;
|
|
141
143
|
return issuerBrand;
|
|
142
144
|
};
|
|
143
145
|
|
|
@@ -145,8 +147,8 @@ const validatedBrand = (mint, debt) => {
|
|
|
145
147
|
* Charge interest accrued between `latestInterestUpdate` and `accruedUntil`.
|
|
146
148
|
*
|
|
147
149
|
* @param {{
|
|
148
|
-
* mint: ZCFMint
|
|
149
|
-
*
|
|
150
|
+
* mint: ZCFMint<'nat'>,
|
|
151
|
+
* mintAndTransferWithFee: MintAndTransfer,
|
|
150
152
|
* poolIncrementSeat: ZCFSeat,
|
|
151
153
|
* seatAllocationKeyword: Keyword }} powers
|
|
152
154
|
* @param {{
|
|
@@ -208,7 +210,12 @@ export const chargeInterest = (powers, params, prior, accruedUntil) => {
|
|
|
208
210
|
|
|
209
211
|
// mint that much of brand for the reward pool
|
|
210
212
|
const rewarded = AmountMath.make(brand, interestAccrued);
|
|
211
|
-
powers.
|
|
213
|
+
powers.mintAndTransferWithFee(
|
|
214
|
+
powers.poolIncrementSeat,
|
|
215
|
+
rewarded,
|
|
216
|
+
rewarded,
|
|
217
|
+
[],
|
|
218
|
+
);
|
|
212
219
|
|
|
213
220
|
return {
|
|
214
221
|
compoundedInterest,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Price oracles
|
|
2
|
+
|
|
3
|
+
This directory contains the `fluxAggregatorKit.js` contract which takes prices as
|
|
4
|
+
input and outputs a best known price. There are multiple ways to get the price,
|
|
5
|
+
including a PriceAuthority interface.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
See the [Smart Wallet integration test](/packages/inter-protocol/test/smartWallet/test-oracle-integration.js) for how it's used.
|
|
10
|
+
|
|
11
|
+
Oracle operates can make PushPrice offers in the CLI. There is no GUI.
|
|
12
|
+
|
|
13
|
+
### CLI
|
|
14
|
+
|
|
15
|
+
See [oracle.js command file](/packages/agoric-cli/src/commands/oracle.js) and its [integration test script](/packages/agoric-cli/test/agops-oracle-smoketest.sh).
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
sequenceDiagram
|
|
19
|
+
|
|
20
|
+
actor user
|
|
21
|
+
|
|
22
|
+
participant cli as Oracle
|
|
23
|
+
participant disk
|
|
24
|
+
participant B as Cosmos / Swingset <br/> bridge
|
|
25
|
+
participant C as smart-wallet<br/>contract
|
|
26
|
+
participant flux as Flux Aggregator<br/>contract
|
|
27
|
+
|
|
28
|
+
user ->> cli: create a PushPrice offer
|
|
29
|
+
user -->> disk: write offer data
|
|
30
|
+
user ->> cli: sign and send PushPrice offer
|
|
31
|
+
disk -->> cli: read offer data
|
|
32
|
+
cli ->> B: spending transaction
|
|
33
|
+
B ->> C: unpack ocap data
|
|
34
|
+
C ->> flux: route offer
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Reading feed
|
|
38
|
+
|
|
39
|
+
Once a new price has been determined, it's published on the aggregator's public topics.
|
|
40
|
+
|
|
41
|
+
```mermaid
|
|
42
|
+
sequenceDiagram
|
|
43
|
+
|
|
44
|
+
actor user
|
|
45
|
+
|
|
46
|
+
participant cli as Oracle<br>query command
|
|
47
|
+
participant flux as Flux Aggregator<br/>contract
|
|
48
|
+
participant B as Cosmos / Swingset <br/> bridge
|
|
49
|
+
participant RPC as validator RPC
|
|
50
|
+
|
|
51
|
+
flux ->> B: publish a PriceDescription
|
|
52
|
+
B ->> RPC: write into Merkle tree
|
|
53
|
+
user ->> cli: query the current price
|
|
54
|
+
cli ->> RPC: request head of vstorage for the feed's path
|
|
55
|
+
RPC -->> cli: return the value
|
|
56
|
+
cli -->> user: display pretty version
|
|
57
|
+
```
|