@agoric/inter-protocol 0.13.4-dev-d32a66a.0 → 0.13.4-pismo-dev-f760927.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 +20 -26
- package/bundles/bundle-amm-meta.js +618 -0
- package/bundles/bundle-amm.js +1 -0
- package/bundles/bundle-feeDistributor-meta.js +346 -0
- package/bundles/bundle-feeDistributor.js +1 -1
- package/bundles/bundle-interchainPool-meta.js +534 -0
- package/bundles/bundle-interchainPool.js +1 -0
- package/bundles/bundle-liquidateIncrementally-meta.js +442 -0
- package/bundles/bundle-liquidateIncrementally.js +1 -0
- package/bundles/bundle-liquidateMinimum-meta.js +442 -0
- package/bundles/bundle-liquidateMinimum.js +1 -0
- package/bundles/bundle-psm-meta.js +538 -0
- package/bundles/bundle-psm.js +1 -1
- package/bundles/bundle-psmCharter-meta.js +418 -0
- package/bundles/bundle-psmCharter.js +1 -0
- package/bundles/bundle-reserve-meta.js +542 -0
- package/bundles/bundle-reserve.js +1 -1
- package/bundles/bundle-scaledPriceAuthority-meta.js +442 -0
- package/bundles/bundle-scaledPriceAuthority.js +1 -1
- package/bundles/bundle-stakeFactory-meta.js +574 -0
- package/bundles/bundle-stakeFactory.js +1 -0
- package/bundles/bundle-vaultFactory-meta.js +598 -0
- package/bundles/bundle-vaultFactory.js +1 -1
- package/exported.js +2 -0
- package/package.json +31 -34
- package/scripts/add-collateral-core.js +4 -14
- package/scripts/add-initial-liquidity.js +180 -0
- package/scripts/build-bundles.js +2 -9
- package/scripts/deploy-contracts.js +4 -1
- package/scripts/init-core.js +38 -20
- package/scripts/invite-committee-core.js +1 -1
- package/scripts/manual-price-feed.js +2 -2
- package/scripts/price-feed-core.js +6 -7
- package/src/collect.js +13 -0
- package/src/collectFees.js +14 -8
- package/src/contractSupport.js +68 -24
- package/src/econCommitteeCharter.js +77 -161
- package/src/feeDistributor.js +20 -60
- package/src/index.js +0 -2
- package/src/interchainPool.js +135 -0
- package/src/interest-math.js +4 -1
- package/src/interest.js +13 -20
- package/src/makeTracer.js +36 -0
- package/src/my-lien.js +85 -0
- package/src/proposals/addAssetToVault.js +94 -89
- package/src/proposals/committee-proposal.js +40 -141
- package/src/proposals/core-proposal.js +167 -100
- package/src/proposals/demoIssuers.js +685 -0
- package/src/proposals/econ-behaviors.js +564 -320
- package/src/proposals/price-feed-proposal.js +78 -175
- package/src/proposals/sim-behaviors.js +40 -0
- package/src/proposals/startEconCommittee.js +12 -25
- package/src/proposals/startPSM.js +211 -231
- package/src/proposals/utils.js +17 -31
- package/src/psm/psm.js +160 -272
- package/src/psm/psmCharter.js +139 -0
- package/src/psm/types.js +0 -2
- package/src/reserve/assetReserve.js +413 -56
- package/src/reserve/doc.md +3 -1
- package/src/reserve/params.js +5 -2
- package/src/stakeFactory/README.md +62 -0
- package/src/stakeFactory/attestation.js +267 -0
- package/src/stakeFactory/attestationTool.js +66 -0
- package/src/stakeFactory/constants.js +16 -0
- package/src/stakeFactory/params.js +31 -0
- package/src/stakeFactory/stakeFactory.js +236 -0
- package/src/stakeFactory/stakeFactoryKit.js +455 -0
- package/src/stakeFactory/stakeFactoryManager.js +296 -0
- package/src/stakeFactory/types.js +42 -0
- package/src/vaultFactory/burn.js +1 -2
- package/src/vaultFactory/liquidateIncrementally.js +350 -0
- package/src/vaultFactory/liquidateMinimum.js +100 -0
- package/src/vaultFactory/liquidation.js +108 -270
- package/src/vaultFactory/orderedVaultStore.js +1 -0
- package/src/vaultFactory/params.js +112 -133
- package/src/vaultFactory/prioritizedVaults.js +79 -36
- package/src/vaultFactory/storeUtils.js +9 -67
- package/src/vaultFactory/type-imports.js +0 -2
- package/src/vaultFactory/types.js +26 -22
- package/src/vaultFactory/vault.js +709 -772
- package/src/vaultFactory/vaultDirector.js +483 -480
- package/src/vaultFactory/vaultFactory.js +60 -99
- package/src/vaultFactory/vaultHolder.js +95 -121
- package/src/vaultFactory/vaultKit.js +31 -39
- package/src/vaultFactory/vaultManager.js +868 -1249
- package/src/vpool-xyk-amm/AttackersGuide.md +89 -0
- package/src/vpool-xyk-amm/addLiquidity.js +222 -0
- package/src/vpool-xyk-amm/addPool.js +197 -0
- package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
- package/src/vpool-xyk-amm/constantProduct/README.md +204 -0
- package/src/vpool-xyk-amm/constantProduct/calcFees.js +99 -0
- package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +85 -0
- package/src/vpool-xyk-amm/constantProduct/core.js +153 -0
- package/src/vpool-xyk-amm/constantProduct/defaults.js +5 -0
- package/src/vpool-xyk-amm/constantProduct/getXY.js +52 -0
- package/src/vpool-xyk-amm/constantProduct/internal-types.js +116 -0
- package/src/vpool-xyk-amm/constantProduct/invariants.js +43 -0
- package/src/vpool-xyk-amm/constantProduct/swap.js +272 -0
- package/src/vpool-xyk-amm/constantProduct/types.js +32 -0
- package/src/vpool-xyk-amm/doublePool.js +194 -0
- package/src/vpool-xyk-amm/estimate.js +155 -0
- package/src/vpool-xyk-amm/multipoolMarketMaker.js +520 -0
- package/src/vpool-xyk-amm/params.js +61 -0
- package/src/vpool-xyk-amm/pool.js +396 -0
- package/src/vpool-xyk-amm/priceAuthority.js +94 -0
- package/src/vpool-xyk-amm/removeLiquidity.js +31 -0
- package/src/vpool-xyk-amm/singlePool.js +73 -0
- package/src/vpool-xyk-amm/swap.js +69 -0
- package/src/vpool-xyk-amm/types.js +154 -0
- package/bundles/bundle-auctioneer-js-meta.json +0 -722
- package/bundles/bundle-auctioneer.js +0 -1
- package/bundles/bundle-econCommitteeCharter-js-meta.json +0 -514
- package/bundles/bundle-econCommitteeCharter.js +0 -1
- package/bundles/bundle-feeDistributor-js-meta.json +0 -458
- package/bundles/bundle-fluxAggregatorKit-js-meta.json +0 -674
- package/bundles/bundle-fluxAggregatorKit.js +0 -1
- package/bundles/bundle-psm-js-meta.json +0 -666
- package/bundles/bundle-reserve-js-meta.json +0 -662
- package/bundles/bundle-scaledPriceAuthority-js-meta.json +0 -542
- package/bundles/bundle-vaultFactory-js-meta.json +0 -786
- package/scripts/start-local-chain.sh +0 -84
- package/src/auction/auctionBook.js +0 -755
- package/src/auction/auctioneer.js +0 -720
- package/src/auction/offerBook.js +0 -221
- package/src/auction/params.js +0 -174
- package/src/auction/scheduleMath.js +0 -167
- package/src/auction/scheduler.js +0 -370
- package/src/auction/sortedOffers.js +0 -136
- package/src/auction/util.js +0 -55
- package/src/clientSupport.js +0 -324
- package/src/price/README.md +0 -57
- package/src/price/fluxAggregatorContract.js +0 -190
- package/src/price/fluxAggregatorKit.js +0 -375
- package/src/price/priceOracleKit.js +0 -127
- package/src/price/roundsManager.js +0 -726
- package/src/psm/README.md +0 -71
- package/src/reserve/assetReserveKit.js +0 -303
- package/src/typeGuards.js +0 -13
- package/src/vaultFactory/Liquidation.md +0 -100
- package/src/vaultFactory/math.js +0 -95
package/src/proposals/utils.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { WalletName } from '@agoric/internal';
|
|
2
1
|
import { getCopyMapEntries, makeCopyMap } from '@agoric/store';
|
|
3
2
|
import { E } from '@endo/far';
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
// must match packages/wallet/api/src/lib-wallet.js
|
|
5
|
+
export const DEPOSIT_FACET = 'depositFacet';
|
|
6
|
+
|
|
7
|
+
const { details: X } = assert;
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
|
-
* @param {ERef<
|
|
10
|
+
* @param {ERef<NameAdmin>} nameAdmin
|
|
9
11
|
* @param {string[][]} paths
|
|
10
12
|
*/
|
|
11
13
|
export const reserveThenGetNamePaths = async (nameAdmin, paths) => {
|
|
12
14
|
/**
|
|
13
15
|
*
|
|
14
|
-
* @param {ERef<
|
|
16
|
+
* @param {ERef<NameAdmin>} nextAdmin
|
|
15
17
|
* @param {string[]} path
|
|
16
18
|
*/
|
|
17
19
|
const nextPath = async (nextAdmin, path) => {
|
|
@@ -34,14 +36,14 @@ export const reserveThenGetNamePaths = async (nameAdmin, paths) => {
|
|
|
34
36
|
|
|
35
37
|
return Promise.all(
|
|
36
38
|
paths.map(async path => {
|
|
37
|
-
Array.isArray(path)
|
|
39
|
+
assert(Array.isArray(path), X`path ${path} is not an array`);
|
|
38
40
|
return nextPath(nameAdmin, path);
|
|
39
41
|
}),
|
|
40
42
|
);
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
/**
|
|
44
|
-
* @param {ERef<
|
|
46
|
+
* @param {ERef<NameAdmin>} nameAdmin
|
|
45
47
|
* @param {string[]} names
|
|
46
48
|
*/
|
|
47
49
|
export const reserveThenGetNames = async (nameAdmin, names) =>
|
|
@@ -50,36 +52,22 @@ export const reserveThenGetNames = async (nameAdmin, names) =>
|
|
|
50
52
|
names.map(name => [name]),
|
|
51
53
|
);
|
|
52
54
|
|
|
53
|
-
/**
|
|
54
|
-
* @param {string} debugName
|
|
55
|
-
* @param {ERef<import('@agoric/vats').NameAdmin>} namesByAddressAdmin
|
|
56
|
-
* @param {string} addr
|
|
57
|
-
* @param {Array<ERef<Payment>>} payments
|
|
58
|
-
*/
|
|
59
55
|
export const reserveThenDeposit = async (
|
|
60
56
|
debugName,
|
|
61
57
|
namesByAddressAdmin,
|
|
62
58
|
addr,
|
|
63
59
|
payments,
|
|
64
60
|
) => {
|
|
65
|
-
console.info('
|
|
61
|
+
console.info('waiting for', debugName);
|
|
66
62
|
const [depositFacet] = await reserveThenGetNamePaths(namesByAddressAdmin, [
|
|
67
|
-
[addr,
|
|
63
|
+
[addr, DEPOSIT_FACET],
|
|
68
64
|
]);
|
|
69
65
|
console.info('depositing to', debugName);
|
|
70
|
-
await Promise.
|
|
71
|
-
|
|
72
|
-
const payment = await paymentP;
|
|
73
|
-
await E(depositFacet).receive(payment);
|
|
74
|
-
console.info(
|
|
75
|
-
`confirmed deposit ${i + 1}/${payments.length} for`,
|
|
76
|
-
debugName,
|
|
77
|
-
);
|
|
78
|
-
}),
|
|
79
|
-
);
|
|
66
|
+
await Promise.all(payments.map(payment => E(depositFacet).receive(payment)));
|
|
67
|
+
console.info('confirmed deposit for', debugName);
|
|
80
68
|
};
|
|
81
69
|
|
|
82
|
-
/** @type {<T>(store: ERef<
|
|
70
|
+
/** @type {<T>(store: ERef<MapStore>, key: string, make: () => T) => Promise<T>} */
|
|
83
71
|
const provideWhen = async (store, key, make) => {
|
|
84
72
|
const found = await E(store).get(key);
|
|
85
73
|
if (found) {
|
|
@@ -91,7 +79,8 @@ const provideWhen = async (store, key, make) => {
|
|
|
91
79
|
};
|
|
92
80
|
|
|
93
81
|
/**
|
|
94
|
-
*
|
|
82
|
+
*
|
|
83
|
+
* @param {{ scratch: ERef<MapStore<string, unknown>> }} homeP
|
|
95
84
|
* @param {object} opts
|
|
96
85
|
* @param {(specifier: string) => Promise<{default: Bundle}>} opts.loadBundle
|
|
97
86
|
* @param {string} [opts.installCacheKey]
|
|
@@ -119,12 +108,9 @@ export const makeInstallCache = async (
|
|
|
119
108
|
};
|
|
120
109
|
|
|
121
110
|
const wrapInstall = install => async (mPath, bPath, opts) => {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
'endoZipBase64Sha512' in bundle,
|
|
125
|
-
'bundle must be EndoZipBase64Bundle',
|
|
111
|
+
const { endoZipBase64Sha512: sha512 } = await loadBundle(bPath).then(
|
|
112
|
+
m => m.default,
|
|
126
113
|
);
|
|
127
|
-
const { endoZipBase64Sha512: sha512 } = bundle;
|
|
128
114
|
const detail = await provideWhen(working, sha512, () =>
|
|
129
115
|
install(mPath, bPath, opts).then(installation => ({
|
|
130
116
|
installation,
|
package/src/psm/psm.js
CHANGED
|
@@ -1,43 +1,27 @@
|
|
|
1
|
-
// @
|
|
2
|
-
|
|
3
|
-
import '@agoric/governance/exported.js';
|
|
1
|
+
// @ts-check
|
|
4
2
|
import '@agoric/zoe/exported.js';
|
|
5
3
|
import '@agoric/zoe/src/contracts/exported.js';
|
|
4
|
+
import '@agoric/governance/src/exported.js';
|
|
6
5
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
CONTRACT_ELECTORATE,
|
|
10
|
-
handleParamGovernance,
|
|
11
|
-
ParamTypes,
|
|
12
|
-
publicMixinAPI,
|
|
13
|
-
} from '@agoric/governance';
|
|
14
|
-
import { StorageNodeShape } from '@agoric/internal';
|
|
15
|
-
import { M, prepareExo, provide } from '@agoric/vat-data';
|
|
6
|
+
import { E } from '@endo/eventual-send';
|
|
16
7
|
import {
|
|
17
|
-
atomicRearrange,
|
|
18
|
-
atomicTransfer,
|
|
19
8
|
ceilMultiplyBy,
|
|
20
9
|
floorDivideBy,
|
|
21
10
|
floorMultiplyBy,
|
|
22
|
-
makeRecorderTopic,
|
|
23
|
-
prepareRecorderKitMakers,
|
|
24
|
-
provideAll,
|
|
25
|
-
provideEmptySeat,
|
|
26
|
-
TopicsRecordShape,
|
|
27
11
|
} from '@agoric/zoe/src/contractSupport/index.js';
|
|
12
|
+
import { Far } from '@endo/marshal';
|
|
28
13
|
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} from '@agoric/
|
|
34
|
-
import {
|
|
14
|
+
handleParamGovernance,
|
|
15
|
+
ParamTypes,
|
|
16
|
+
publicMixinAPI,
|
|
17
|
+
} from '@agoric/governance';
|
|
18
|
+
import { M, provide, vivifyFarInstance } from '@agoric/vat-data';
|
|
19
|
+
import { AmountMath } from '@agoric/ertp';
|
|
35
20
|
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import { makeNatAmountShape } from '../contractSupport.js';
|
|
21
|
+
import { makeMakeCollectFeesInvitation } from '../collectFees.js';
|
|
22
|
+
import { makeMetricsPublishKit } from '../contractSupport.js';
|
|
39
23
|
|
|
40
|
-
const {
|
|
24
|
+
const { details: X } = assert;
|
|
41
25
|
|
|
42
26
|
/**
|
|
43
27
|
* @file The Parity Stability Module supports efficiently minting/burning a
|
|
@@ -45,6 +29,7 @@ const { Fail } = assert;
|
|
|
45
29
|
* thereby acts as an anchor to provide additional stability. For flexible
|
|
46
30
|
* economic policies, the fee percentage for trading into and out of the stable
|
|
47
31
|
* token are specified separately.
|
|
32
|
+
*
|
|
48
33
|
*/
|
|
49
34
|
|
|
50
35
|
/**
|
|
@@ -54,8 +39,6 @@ const { Fail } = assert;
|
|
|
54
39
|
*
|
|
55
40
|
* @property {Amount<'nat'>} anchorPoolBalance amount of Anchor token
|
|
56
41
|
* available to be swapped
|
|
57
|
-
* @property {Amount<'nat'>} mintedPoolBalance amount of Minted token
|
|
58
|
-
* outstanding (the amount minted minus the amount burned).
|
|
59
42
|
* @property {Amount<'nat'>} feePoolBalance amount of Minted token
|
|
60
43
|
* fees available to be collected
|
|
61
44
|
*
|
|
@@ -65,42 +48,22 @@ const { Fail } = assert;
|
|
|
65
48
|
* ever given by this contract
|
|
66
49
|
*/
|
|
67
50
|
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
value: RatioShape,
|
|
82
|
-
},
|
|
83
|
-
GiveMintedFee: {
|
|
84
|
-
type: ParamTypes.RATIO,
|
|
85
|
-
value: RatioShape,
|
|
86
|
-
},
|
|
87
|
-
MintLimit: { type: ParamTypes.AMOUNT, value: AmountShape },
|
|
88
|
-
},
|
|
51
|
+
/**
|
|
52
|
+
* Stage a transfer of a single asset from one seat to another, with an optional
|
|
53
|
+
* remapping of the Keywords. Check that the remapping is for the same amount.
|
|
54
|
+
*
|
|
55
|
+
* @param {ZCFSeat} from
|
|
56
|
+
* @param {ZCFSeat} to
|
|
57
|
+
* @param {AmountKeywordRecord} txFrom
|
|
58
|
+
* @param {AmountKeywordRecord} txTo
|
|
59
|
+
*/
|
|
60
|
+
const stageTransfer = (from, to, txFrom, txTo = txFrom) => {
|
|
61
|
+
assert(AmountMath.isEqual(Object.values(txFrom)[0], Object.values(txTo)[0]));
|
|
62
|
+
from.decrementBy(txFrom);
|
|
63
|
+
to.incrementBy(txTo);
|
|
89
64
|
};
|
|
90
|
-
harden(customTermsShape);
|
|
91
65
|
|
|
92
|
-
|
|
93
|
-
harden({
|
|
94
|
-
marshaller: M.remotable('Marshaller'),
|
|
95
|
-
storageNode: StorageNodeShape,
|
|
96
|
-
}),
|
|
97
|
-
harden({
|
|
98
|
-
// only necessary on first invocation, not subsequent
|
|
99
|
-
feeMintAccess: FeeMintAccessShape,
|
|
100
|
-
initialPoserInvitation: InvitationShape,
|
|
101
|
-
}),
|
|
102
|
-
);
|
|
103
|
-
harden(privateArgsShape);
|
|
66
|
+
/** @typedef {import('@agoric/vat-data').Baggage} Baggage */
|
|
104
67
|
|
|
105
68
|
/**
|
|
106
69
|
* @param {ZCF<GovernanceTerms<{
|
|
@@ -108,28 +71,26 @@ harden(privateArgsShape);
|
|
|
108
71
|
* WantMintedFee: 'ratio',
|
|
109
72
|
* MintLimit: 'amount',
|
|
110
73
|
* }> & {
|
|
111
|
-
* anchorBrand: Brand
|
|
74
|
+
* anchorBrand: Brand,
|
|
112
75
|
* anchorPerMinted: Ratio,
|
|
113
76
|
* }>} zcf
|
|
114
77
|
* @param {{feeMintAccess: FeeMintAccess, initialPoserInvitation: Invitation, storageNode: StorageNode, marshaller: Marshaller}} privateArgs
|
|
115
78
|
* @param {Baggage} baggage
|
|
116
79
|
*/
|
|
117
|
-
export const
|
|
80
|
+
export const start = async (zcf, privateArgs, baggage) => {
|
|
118
81
|
const { anchorBrand, anchorPerMinted } = zcf.getTerms();
|
|
119
82
|
console.log('PSM Starting', anchorBrand, anchorPerMinted);
|
|
120
83
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
privateArgs.
|
|
84
|
+
const stableMint = await zcf.registerFeeMint(
|
|
85
|
+
'Minted',
|
|
86
|
+
privateArgs.feeMintAccess,
|
|
124
87
|
);
|
|
125
|
-
|
|
126
|
-
const { stableMint } = await provideAll(baggage, {
|
|
127
|
-
stableMint: () => zcf.registerFeeMint('Minted', privateArgs.feeMintAccess),
|
|
128
|
-
});
|
|
129
88
|
const { brand: stableBrand } = stableMint.getIssuerRecord();
|
|
130
|
-
(
|
|
131
|
-
anchorPerMinted.
|
|
132
|
-
|
|
89
|
+
assert(
|
|
90
|
+
anchorPerMinted.numerator.brand === anchorBrand &&
|
|
91
|
+
anchorPerMinted.denominator.brand === stableBrand,
|
|
92
|
+
X`Ratio ${anchorPerMinted} is not consistent with brands ${anchorBrand} and ${stableBrand}`,
|
|
93
|
+
);
|
|
133
94
|
|
|
134
95
|
zcf.setTestJig(() => ({
|
|
135
96
|
stableIssuerRecord: stableMint.getIssuerRecord(),
|
|
@@ -137,7 +98,7 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
137
98
|
const emptyStable = AmountMath.makeEmpty(stableBrand);
|
|
138
99
|
const emptyAnchor = AmountMath.makeEmpty(anchorBrand);
|
|
139
100
|
|
|
140
|
-
const { publicMixin,
|
|
101
|
+
const { publicMixin, creatorMixin, makeFarGovernorFacet, params } =
|
|
141
102
|
await handleParamGovernance(
|
|
142
103
|
zcf,
|
|
143
104
|
privateArgs.initialPoserInvitation,
|
|
@@ -150,113 +111,60 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
150
111
|
privateArgs.marshaller,
|
|
151
112
|
);
|
|
152
113
|
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
114
|
+
const provideEmptyZcfSeat = name => {
|
|
115
|
+
return provide(baggage, name, () => zcf.makeEmptySeatKit().zcfSeat);
|
|
116
|
+
};
|
|
156
117
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
118
|
+
const anchorPool = provideEmptyZcfSeat('anchorPoolSeat');
|
|
119
|
+
const feePool = provideEmptyZcfSeat('feePoolSeat');
|
|
120
|
+
const stage = provideEmptyZcfSeat('stageSeat');
|
|
121
|
+
|
|
122
|
+
let mintedPoolBalance = provide(baggage, 'mintedPoolBalance', () =>
|
|
160
123
|
AmountMath.makeEmpty(stableBrand),
|
|
161
124
|
);
|
|
162
|
-
|
|
125
|
+
|
|
126
|
+
let totalAnchorProvided = provide(baggage, 'totalAnchorProvided', () =>
|
|
163
127
|
AmountMath.makeEmpty(anchorBrand),
|
|
164
128
|
);
|
|
165
|
-
provide(baggage, 'totalMintedProvided', () =>
|
|
129
|
+
let totalMintedProvided = provide(baggage, 'totalMintedProvided', () =>
|
|
166
130
|
AmountMath.makeEmpty(stableBrand),
|
|
167
131
|
);
|
|
168
132
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
/** @type {import('@agoric/zoe/src/contractSupport/recorder.js').TypedMatcher<MetricsNotification>} */ (
|
|
175
|
-
M.any()
|
|
176
|
-
),
|
|
177
|
-
),
|
|
178
|
-
),
|
|
179
|
-
});
|
|
180
|
-
const topics = harden({
|
|
181
|
-
metrics: makeRecorderTopic('PSM metrics', metricsKit),
|
|
182
|
-
});
|
|
183
|
-
|
|
133
|
+
/** @type {import('../contractSupport.js').MetricsPublishKit<MetricsNotification>} */
|
|
134
|
+
const { metricsPublisher, metricsSubscriber } = makeMetricsPublishKit(
|
|
135
|
+
privateArgs.storageNode,
|
|
136
|
+
privateArgs.marshaller,
|
|
137
|
+
);
|
|
184
138
|
const updateMetrics = () => {
|
|
185
|
-
|
|
139
|
+
metricsPublisher.publish(
|
|
186
140
|
harden({
|
|
187
141
|
anchorPoolBalance: anchorPool.getAmountAllocated('Anchor', anchorBrand),
|
|
188
142
|
feePoolBalance: feePool.getAmountAllocated('Minted', stableBrand),
|
|
189
|
-
mintedPoolBalance
|
|
190
|
-
totalAnchorProvided
|
|
191
|
-
totalMintedProvided
|
|
143
|
+
mintedPoolBalance,
|
|
144
|
+
totalAnchorProvided,
|
|
145
|
+
totalMintedProvided,
|
|
192
146
|
}),
|
|
193
147
|
);
|
|
194
148
|
};
|
|
195
149
|
updateMetrics();
|
|
196
150
|
|
|
197
|
-
const AnchorAmountShape = makeNatAmountShape(anchorBrand);
|
|
198
|
-
const StableAmountShape = makeNatAmountShape(stableBrand);
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* @param {ZCFSeat} seat
|
|
202
|
-
* @param {Omit<MetricsNotification, 'anchorPoolBalance'>} target
|
|
203
|
-
*/
|
|
204
|
-
const restoreMetricsHook = (seat, target) => {
|
|
205
|
-
assert(
|
|
206
|
-
AmountMath.isEmpty(anchorPool.getAmountAllocated('Anchor', anchorBrand)),
|
|
207
|
-
'cannot restoreMetrics: anchorPool is not empty',
|
|
208
|
-
);
|
|
209
|
-
assert(
|
|
210
|
-
AmountMath.isEmpty(feePool.getAmountAllocated('Minted', stableBrand)),
|
|
211
|
-
'cannot restoreMetrics: feePool is not empty',
|
|
212
|
-
);
|
|
213
|
-
mustMatch(
|
|
214
|
-
target,
|
|
215
|
-
harden({
|
|
216
|
-
feePoolBalance: StableAmountShape,
|
|
217
|
-
mintedPoolBalance: StableAmountShape,
|
|
218
|
-
totalAnchorProvided: AnchorAmountShape,
|
|
219
|
-
totalMintedProvided: StableAmountShape,
|
|
220
|
-
}),
|
|
221
|
-
);
|
|
222
|
-
const {
|
|
223
|
-
give: { Anchor },
|
|
224
|
-
} = seat.getProposal();
|
|
225
|
-
stableMint.mintGains({ Minted: target.feePoolBalance }, feePool);
|
|
226
|
-
atomicTransfer(zcf, seat, anchorPool, { Anchor });
|
|
227
|
-
baggage.set('mintedPoolBalance', target.mintedPoolBalance);
|
|
228
|
-
baggage.set('totalAnchorProvided', target.totalAnchorProvided);
|
|
229
|
-
baggage.set('totalMintedProvided', target.totalMintedProvided);
|
|
230
|
-
seat.exit();
|
|
231
|
-
updateMetrics();
|
|
232
|
-
};
|
|
233
|
-
|
|
234
151
|
/**
|
|
235
152
|
* @param {Amount<'nat'>} toMint
|
|
236
153
|
*/
|
|
237
154
|
const assertUnderLimit = toMint => {
|
|
238
|
-
const mintedAfter = AmountMath.add(
|
|
239
|
-
baggage.get('mintedPoolBalance'),
|
|
240
|
-
toMint,
|
|
241
|
-
);
|
|
155
|
+
const mintedAfter = AmountMath.add(mintedPoolBalance, toMint);
|
|
242
156
|
AmountMath.isGTE(params.getMintLimit(), mintedAfter) ||
|
|
243
|
-
|
|
157
|
+
assert.fail(X`Request would exceed mint limit`);
|
|
244
158
|
};
|
|
245
159
|
|
|
246
160
|
const burnMinted = toBurn => {
|
|
247
161
|
stableMint.burnLosses({ Minted: toBurn }, stage);
|
|
248
|
-
|
|
249
|
-
'mintedPoolBalance',
|
|
250
|
-
AmountMath.subtract(baggage.get('mintedPoolBalance'), toBurn),
|
|
251
|
-
);
|
|
162
|
+
mintedPoolBalance = AmountMath.subtract(mintedPoolBalance, toBurn);
|
|
252
163
|
};
|
|
253
164
|
|
|
254
165
|
const mintMinted = toMint => {
|
|
255
166
|
stableMint.mintGains({ Minted: toMint }, stage);
|
|
256
|
-
|
|
257
|
-
'mintedPoolBalance',
|
|
258
|
-
AmountMath.add(baggage.get('mintedPoolBalance'), toMint),
|
|
259
|
-
);
|
|
167
|
+
mintedPoolBalance = AmountMath.add(mintedPoolBalance, toMint);
|
|
260
168
|
};
|
|
261
169
|
|
|
262
170
|
/**
|
|
@@ -269,23 +177,26 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
269
177
|
const afterFee = AmountMath.subtract(given, fee);
|
|
270
178
|
const maxAnchor = floorMultiplyBy(afterFee, anchorPerMinted);
|
|
271
179
|
AmountMath.isGTE(maxAnchor, wanted) ||
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
180
|
+
assert.fail(X`wanted ${wanted} is more than ${given} minus fees ${fee}`);
|
|
181
|
+
try {
|
|
182
|
+
stageTransfer(seat, stage, { In: afterFee }, { Minted: afterFee });
|
|
183
|
+
stageTransfer(seat, feePool, { In: fee }, { Minted: fee });
|
|
184
|
+
stageTransfer(
|
|
185
|
+
anchorPool,
|
|
186
|
+
seat,
|
|
187
|
+
{ Anchor: maxAnchor },
|
|
188
|
+
{ Out: maxAnchor },
|
|
189
|
+
);
|
|
190
|
+
zcf.reallocate(seat, anchorPool, stage, feePool);
|
|
191
|
+
burnMinted(afterFee);
|
|
192
|
+
} catch (e) {
|
|
193
|
+
stage.clear();
|
|
194
|
+
anchorPool.clear();
|
|
195
|
+
feePool.clear();
|
|
196
|
+
// TODO(#6116) someday, reallocate should guarantee that this case cannot happen
|
|
197
|
+
throw e;
|
|
198
|
+
}
|
|
199
|
+
totalAnchorProvided = AmountMath.add(totalAnchorProvided, maxAnchor);
|
|
289
200
|
};
|
|
290
201
|
|
|
291
202
|
/**
|
|
@@ -299,28 +210,22 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
299
210
|
const fee = ceilMultiplyBy(asStable, params.getWantMintedFee());
|
|
300
211
|
const afterFee = AmountMath.subtract(asStable, fee);
|
|
301
212
|
AmountMath.isGTE(afterFee, wanted) ||
|
|
302
|
-
|
|
213
|
+
assert.fail(X`wanted ${wanted} is more than ${given} minus fees ${fee}`);
|
|
303
214
|
mintMinted(asStable);
|
|
304
215
|
try {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
[stage, seat, { Minted: afterFee }, { Out: afterFee }],
|
|
310
|
-
[stage, feePool, { Minted: fee }],
|
|
311
|
-
]),
|
|
312
|
-
);
|
|
216
|
+
stageTransfer(seat, anchorPool, { In: given }, { Anchor: given });
|
|
217
|
+
stageTransfer(stage, seat, { Minted: afterFee }, { Out: afterFee });
|
|
218
|
+
stageTransfer(stage, feePool, { Minted: fee });
|
|
219
|
+
zcf.reallocate(seat, anchorPool, stage, feePool);
|
|
313
220
|
} catch (e) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
221
|
+
stage.clear();
|
|
222
|
+
anchorPool.clear();
|
|
223
|
+
feePool.clear();
|
|
224
|
+
// TODO(#6116) someday, reallocate should guarantee that this case cannot happen
|
|
317
225
|
burnMinted(asStable);
|
|
318
226
|
throw e;
|
|
319
227
|
}
|
|
320
|
-
|
|
321
|
-
'totalMintedProvided',
|
|
322
|
-
AmountMath.add(baggage.get('totalMintedProvided'), asStable),
|
|
323
|
-
);
|
|
228
|
+
totalMintedProvided = AmountMath.add(totalMintedProvided, asStable);
|
|
324
229
|
};
|
|
325
230
|
|
|
326
231
|
/** @param {ZCFSeat} seat */
|
|
@@ -335,7 +240,7 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
335
240
|
};
|
|
336
241
|
|
|
337
242
|
/** @param {ZCFSeat} seat */
|
|
338
|
-
const
|
|
243
|
+
const wantmintedHook = seat => {
|
|
339
244
|
const {
|
|
340
245
|
give: { In: given },
|
|
341
246
|
want: { Out: wanted } = { Out: undefined },
|
|
@@ -345,100 +250,83 @@ export const prepare = async (zcf, privateArgs, baggage) => {
|
|
|
345
250
|
updateMetrics();
|
|
346
251
|
};
|
|
347
252
|
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
253
|
+
const [anchorAmountShape, stableAmountShape] = await Promise.all([
|
|
254
|
+
E(anchorBrand).getAmountShape(),
|
|
255
|
+
E(stableBrand).getAmountShape(),
|
|
256
|
+
]);
|
|
257
|
+
|
|
258
|
+
const PSMI = M.interface('PSM', {
|
|
259
|
+
getMetrics: M.call().returns(M.remotable('MetricsSubscriber')),
|
|
260
|
+
getPoolBalance: M.call().returns(anchorAmountShape),
|
|
261
|
+
makeWantMintedInvitation: M.call().returns(M.promise()),
|
|
262
|
+
makeGiveMintedInvitation: M.call().returns(M.promise()),
|
|
263
|
+
...publicMixinAPI,
|
|
351
264
|
});
|
|
352
265
|
|
|
353
|
-
const
|
|
266
|
+
const methods = {
|
|
267
|
+
getMetrics() {
|
|
268
|
+
return metricsSubscriber;
|
|
269
|
+
},
|
|
270
|
+
getPoolBalance() {
|
|
271
|
+
return anchorPool.getAmountAllocated('Anchor', anchorBrand);
|
|
272
|
+
},
|
|
273
|
+
makeWantMintedInvitation() {
|
|
274
|
+
return zcf.makeInvitation(
|
|
275
|
+
wantmintedHook,
|
|
276
|
+
'wantMinted',
|
|
277
|
+
undefined,
|
|
278
|
+
M.split({
|
|
279
|
+
give: { In: anchorAmountShape },
|
|
280
|
+
want: M.or({ Out: stableAmountShape }, {}),
|
|
281
|
+
}),
|
|
282
|
+
);
|
|
283
|
+
},
|
|
284
|
+
makeGiveMintedInvitation() {
|
|
285
|
+
return zcf.makeInvitation(
|
|
286
|
+
giveMintedHook,
|
|
287
|
+
'giveMinted',
|
|
288
|
+
undefined,
|
|
289
|
+
M.split({
|
|
290
|
+
give: { In: stableAmountShape },
|
|
291
|
+
want: M.or({ Out: anchorAmountShape }, {}),
|
|
292
|
+
}),
|
|
293
|
+
);
|
|
294
|
+
},
|
|
295
|
+
...publicMixin,
|
|
296
|
+
};
|
|
297
|
+
const publicFacet = vivifyFarInstance(
|
|
354
298
|
baggage,
|
|
355
299
|
'Parity Stability Module',
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
getPoolBalance: M.call().returns(anchorAmountShape),
|
|
359
|
-
getPublicTopics: M.call().returns(TopicsRecordShape),
|
|
360
|
-
makeWantMintedInvitation: M.call().returns(M.promise()),
|
|
361
|
-
makeGiveMintedInvitation: M.call().returns(M.promise()),
|
|
362
|
-
...publicMixinAPI,
|
|
363
|
-
}),
|
|
364
|
-
{
|
|
365
|
-
getMetrics() {
|
|
366
|
-
return metricsKit.subscriber;
|
|
367
|
-
},
|
|
368
|
-
getPoolBalance() {
|
|
369
|
-
return anchorPool.getAmountAllocated('Anchor', anchorBrand);
|
|
370
|
-
},
|
|
371
|
-
getPublicTopics() {
|
|
372
|
-
return topics;
|
|
373
|
-
},
|
|
374
|
-
makeWantMintedInvitation() {
|
|
375
|
-
return zcf.makeInvitation(
|
|
376
|
-
wantMintedHook,
|
|
377
|
-
'wantMinted',
|
|
378
|
-
undefined,
|
|
379
|
-
M.splitRecord({
|
|
380
|
-
give: { In: anchorAmountShape },
|
|
381
|
-
want: M.or({ Out: stableAmountShape }, {}),
|
|
382
|
-
}),
|
|
383
|
-
);
|
|
384
|
-
},
|
|
385
|
-
makeGiveMintedInvitation() {
|
|
386
|
-
return zcf.makeInvitation(
|
|
387
|
-
giveMintedHook,
|
|
388
|
-
'giveMinted',
|
|
389
|
-
undefined,
|
|
390
|
-
M.splitRecord({
|
|
391
|
-
give: { In: stableAmountShape },
|
|
392
|
-
want: M.or({ Out: anchorAmountShape }, {}),
|
|
393
|
-
}),
|
|
394
|
-
);
|
|
395
|
-
},
|
|
396
|
-
...publicMixin,
|
|
397
|
-
},
|
|
300
|
+
PSMI,
|
|
301
|
+
methods,
|
|
398
302
|
);
|
|
399
303
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
M.promise(/* InvitationShape */),
|
|
407
|
-
),
|
|
408
|
-
makeRestoreMetricsInvitation: M.call().returns(
|
|
409
|
-
M.promise(/* InvitationShape */),
|
|
410
|
-
),
|
|
411
|
-
}),
|
|
412
|
-
{
|
|
413
|
-
getRewardAllocation() {
|
|
414
|
-
return feePool.getCurrentAllocation();
|
|
415
|
-
},
|
|
416
|
-
makeCollectFeesInvitation() {
|
|
417
|
-
return makeCollectFeesInvitation(zcf, feePool, stableBrand, 'Minted');
|
|
418
|
-
},
|
|
419
|
-
makeRestoreMetricsInvitation() {
|
|
420
|
-
return zcf.makeInvitation(
|
|
421
|
-
restoreMetricsHook,
|
|
422
|
-
'restoreMetrics',
|
|
423
|
-
undefined,
|
|
424
|
-
M.splitRecord({
|
|
425
|
-
give: {
|
|
426
|
-
Anchor: AnchorAmountShape,
|
|
427
|
-
},
|
|
428
|
-
}),
|
|
429
|
-
);
|
|
430
|
-
},
|
|
431
|
-
},
|
|
304
|
+
// TODO why does this operation return an object with a single operation?
|
|
305
|
+
const { makeCollectFeesInvitation } = makeMakeCollectFeesInvitation(
|
|
306
|
+
zcf,
|
|
307
|
+
feePool,
|
|
308
|
+
stableBrand,
|
|
309
|
+
'Minted',
|
|
432
310
|
);
|
|
433
311
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
312
|
+
// The creator facets are only accessibly to governance and bootstrap,
|
|
313
|
+
// and so do not need interface protection at this time. Additionally,
|
|
314
|
+
// all the operations take no arguments and so are largely defensive as is.
|
|
315
|
+
const limitedCreatorFacet = Far('Parity Stability Module', {
|
|
316
|
+
getRewardAllocation() {
|
|
317
|
+
return feePool.getCurrentAllocation();
|
|
318
|
+
},
|
|
319
|
+
makeCollectFeesInvitation() {
|
|
320
|
+
return makeCollectFeesInvitation();
|
|
321
|
+
},
|
|
322
|
+
...creatorMixin,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const governorFacet = makeFarGovernorFacet(limitedCreatorFacet);
|
|
438
326
|
return harden({
|
|
439
327
|
creatorFacet: governorFacet,
|
|
440
328
|
publicFacet,
|
|
441
329
|
});
|
|
442
330
|
};
|
|
443
331
|
|
|
444
|
-
/** @typedef {Awaited<ReturnType<typeof
|
|
332
|
+
/** @typedef {Awaited<ReturnType<typeof start>>['publicFacet']} PsmPublicFacet */
|