@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.
Files changed (140) hide show
  1. package/README.md +26 -20
  2. package/bundles/bundle-auctioneer-js-meta.json +722 -0
  3. package/bundles/bundle-auctioneer.js +1 -0
  4. package/bundles/bundle-econCommitteeCharter-js-meta.json +514 -0
  5. package/bundles/bundle-econCommitteeCharter.js +1 -0
  6. package/bundles/bundle-feeDistributor-js-meta.json +458 -0
  7. package/bundles/bundle-feeDistributor.js +1 -1
  8. package/bundles/bundle-fluxAggregatorKit-js-meta.json +674 -0
  9. package/bundles/bundle-fluxAggregatorKit.js +1 -0
  10. package/bundles/bundle-psm-js-meta.json +666 -0
  11. package/bundles/bundle-psm.js +1 -1
  12. package/bundles/bundle-reserve-js-meta.json +662 -0
  13. package/bundles/bundle-reserve.js +1 -1
  14. package/bundles/bundle-scaledPriceAuthority-js-meta.json +542 -0
  15. package/bundles/bundle-scaledPriceAuthority.js +1 -1
  16. package/bundles/bundle-vaultFactory-js-meta.json +786 -0
  17. package/bundles/bundle-vaultFactory.js +1 -1
  18. package/exported.js +0 -2
  19. package/package.json +34 -31
  20. package/scripts/add-collateral-core.js +14 -4
  21. package/scripts/build-bundles.js +9 -2
  22. package/scripts/deploy-contracts.js +1 -4
  23. package/scripts/init-core.js +20 -38
  24. package/scripts/invite-committee-core.js +1 -1
  25. package/scripts/manual-price-feed.js +2 -2
  26. package/scripts/price-feed-core.js +7 -6
  27. package/scripts/start-local-chain.sh +84 -0
  28. package/src/auction/auctionBook.js +755 -0
  29. package/src/auction/auctioneer.js +720 -0
  30. package/src/auction/offerBook.js +221 -0
  31. package/src/auction/params.js +174 -0
  32. package/src/auction/scheduleMath.js +167 -0
  33. package/src/auction/scheduler.js +370 -0
  34. package/src/auction/sortedOffers.js +136 -0
  35. package/src/auction/util.js +55 -0
  36. package/src/clientSupport.js +324 -0
  37. package/src/collectFees.js +8 -14
  38. package/src/contractSupport.js +24 -68
  39. package/src/econCommitteeCharter.js +161 -77
  40. package/src/feeDistributor.js +60 -20
  41. package/src/index.js +2 -0
  42. package/src/interest-math.js +1 -4
  43. package/src/interest.js +20 -13
  44. package/src/price/README.md +57 -0
  45. package/src/price/fluxAggregatorContract.js +190 -0
  46. package/src/price/fluxAggregatorKit.js +375 -0
  47. package/src/price/priceOracleKit.js +127 -0
  48. package/src/price/roundsManager.js +726 -0
  49. package/src/proposals/addAssetToVault.js +89 -94
  50. package/src/proposals/committee-proposal.js +141 -40
  51. package/src/proposals/core-proposal.js +100 -167
  52. package/src/proposals/econ-behaviors.js +320 -564
  53. package/src/proposals/price-feed-proposal.js +175 -78
  54. package/src/proposals/startEconCommittee.js +25 -12
  55. package/src/proposals/startPSM.js +231 -211
  56. package/src/proposals/utils.js +31 -17
  57. package/src/psm/README.md +71 -0
  58. package/src/psm/psm.js +272 -160
  59. package/src/psm/types.js +2 -0
  60. package/src/reserve/assetReserve.js +56 -413
  61. package/src/reserve/assetReserveKit.js +303 -0
  62. package/src/reserve/doc.md +1 -3
  63. package/src/reserve/params.js +2 -5
  64. package/src/typeGuards.js +13 -0
  65. package/src/vaultFactory/Liquidation.md +100 -0
  66. package/src/vaultFactory/burn.js +2 -1
  67. package/src/vaultFactory/liquidation.js +270 -108
  68. package/src/vaultFactory/math.js +95 -0
  69. package/src/vaultFactory/orderedVaultStore.js +0 -1
  70. package/src/vaultFactory/params.js +133 -112
  71. package/src/vaultFactory/prioritizedVaults.js +36 -79
  72. package/src/vaultFactory/storeUtils.js +67 -9
  73. package/src/vaultFactory/type-imports.js +2 -0
  74. package/src/vaultFactory/types.js +22 -26
  75. package/src/vaultFactory/vault.js +772 -709
  76. package/src/vaultFactory/vaultDirector.js +480 -483
  77. package/src/vaultFactory/vaultFactory.js +99 -60
  78. package/src/vaultFactory/vaultHolder.js +121 -95
  79. package/src/vaultFactory/vaultKit.js +39 -31
  80. package/src/vaultFactory/vaultManager.js +1249 -868
  81. package/bundles/bundle-amm-meta.js +0 -618
  82. package/bundles/bundle-amm.js +0 -1
  83. package/bundles/bundle-feeDistributor-meta.js +0 -346
  84. package/bundles/bundle-interchainPool-meta.js +0 -534
  85. package/bundles/bundle-interchainPool.js +0 -1
  86. package/bundles/bundle-liquidateIncrementally-meta.js +0 -442
  87. package/bundles/bundle-liquidateIncrementally.js +0 -1
  88. package/bundles/bundle-liquidateMinimum-meta.js +0 -442
  89. package/bundles/bundle-liquidateMinimum.js +0 -1
  90. package/bundles/bundle-psm-meta.js +0 -538
  91. package/bundles/bundle-psmCharter-meta.js +0 -418
  92. package/bundles/bundle-psmCharter.js +0 -1
  93. package/bundles/bundle-reserve-meta.js +0 -542
  94. package/bundles/bundle-scaledPriceAuthority-meta.js +0 -442
  95. package/bundles/bundle-stakeFactory-meta.js +0 -574
  96. package/bundles/bundle-stakeFactory.js +0 -1
  97. package/bundles/bundle-vaultFactory-meta.js +0 -598
  98. package/scripts/add-initial-liquidity.js +0 -180
  99. package/src/collect.js +0 -13
  100. package/src/interchainPool.js +0 -135
  101. package/src/makeTracer.js +0 -36
  102. package/src/my-lien.js +0 -85
  103. package/src/proposals/demoIssuers.js +0 -685
  104. package/src/proposals/sim-behaviors.js +0 -40
  105. package/src/psm/psmCharter.js +0 -139
  106. package/src/stakeFactory/README.md +0 -62
  107. package/src/stakeFactory/attestation.js +0 -267
  108. package/src/stakeFactory/attestationTool.js +0 -66
  109. package/src/stakeFactory/constants.js +0 -16
  110. package/src/stakeFactory/params.js +0 -31
  111. package/src/stakeFactory/stakeFactory.js +0 -236
  112. package/src/stakeFactory/stakeFactoryKit.js +0 -455
  113. package/src/stakeFactory/stakeFactoryManager.js +0 -296
  114. package/src/stakeFactory/types.js +0 -42
  115. package/src/vaultFactory/liquidateIncrementally.js +0 -350
  116. package/src/vaultFactory/liquidateMinimum.js +0 -100
  117. package/src/vpool-xyk-amm/AttackersGuide.md +0 -89
  118. package/src/vpool-xyk-amm/addLiquidity.js +0 -222
  119. package/src/vpool-xyk-amm/addPool.js +0 -197
  120. package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
  121. package/src/vpool-xyk-amm/constantProduct/README.md +0 -204
  122. package/src/vpool-xyk-amm/constantProduct/calcFees.js +0 -99
  123. package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +0 -85
  124. package/src/vpool-xyk-amm/constantProduct/core.js +0 -153
  125. package/src/vpool-xyk-amm/constantProduct/defaults.js +0 -5
  126. package/src/vpool-xyk-amm/constantProduct/getXY.js +0 -52
  127. package/src/vpool-xyk-amm/constantProduct/internal-types.js +0 -116
  128. package/src/vpool-xyk-amm/constantProduct/invariants.js +0 -43
  129. package/src/vpool-xyk-amm/constantProduct/swap.js +0 -272
  130. package/src/vpool-xyk-amm/constantProduct/types.js +0 -32
  131. package/src/vpool-xyk-amm/doublePool.js +0 -194
  132. package/src/vpool-xyk-amm/estimate.js +0 -155
  133. package/src/vpool-xyk-amm/multipoolMarketMaker.js +0 -520
  134. package/src/vpool-xyk-amm/params.js +0 -61
  135. package/src/vpool-xyk-amm/pool.js +0 -396
  136. package/src/vpool-xyk-amm/priceAuthority.js +0 -94
  137. package/src/vpool-xyk-amm/removeLiquidity.js +0 -31
  138. package/src/vpool-xyk-amm/singlePool.js +0 -73
  139. package/src/vpool-xyk-amm/swap.js +0 -69
  140. package/src/vpool-xyk-amm/types.js +0 -154
@@ -1,16 +1,17 @@
1
- // @ts-check
1
+ // @jessie-check
2
2
 
3
3
  import './types.js';
4
4
 
5
5
  import {
6
6
  CONTRACT_ELECTORATE,
7
7
  makeParamManagerSync,
8
- makeParamManager,
9
8
  ParamTypes,
10
9
  } from '@agoric/governance';
11
10
  import { makeStoredPublisherKit } from '@agoric/notifier';
12
- import { M } from '@agoric/store';
13
- import { TimeMath } from '@agoric/swingset-vat/src/vats/timer/timeMath.js';
11
+ import { M, makeScalarMapStore } from '@agoric/store';
12
+ import { TimeMath } from '@agoric/time';
13
+ import { provideDurableMapStore } from '@agoric/vat-data';
14
+ import { subtractRatios } from '@agoric/zoe/src/contractSupport/ratio.js';
14
15
  import { amountPattern, ratioPattern } from '../contractSupport.js';
15
16
 
16
17
  export const CHARGING_PERIOD_KEY = 'ChargingPeriod';
@@ -18,41 +19,41 @@ export const RECORDING_PERIOD_KEY = 'RecordingPeriod';
18
19
 
19
20
  export const DEBT_LIMIT_KEY = 'DebtLimit';
20
21
  export const LIQUIDATION_MARGIN_KEY = 'LiquidationMargin';
22
+ export const LIQUIDATION_PADDING_KEY = 'LiquidationPadding';
21
23
  export const LIQUIDATION_PENALTY_KEY = 'LiquidationPenalty';
22
24
  export const INTEREST_RATE_KEY = 'InterestRate';
23
- export const LOAN_FEE_KEY = 'LoanFee';
24
- export const LIQUIDATION_INSTALL_KEY = 'LiquidationInstall';
25
- export const LIQUIDATION_TERMS_KEY = 'LiquidationTerms';
25
+ export const MINT_FEE_KEY = 'MintFee';
26
26
  export const MIN_INITIAL_DEBT_KEY = 'MinInitialDebt';
27
27
  export const SHORTFALL_INVITATION_KEY = 'ShortfallInvitation';
28
+ export const ENDORSED_UI_KEY = 'EndorsedUI';
29
+
30
+ export const vaultDirectorParamTypes = {
31
+ [MIN_INITIAL_DEBT_KEY]: ParamTypes.AMOUNT,
32
+ [CHARGING_PERIOD_KEY]: ParamTypes.NAT,
33
+ [RECORDING_PERIOD_KEY]: ParamTypes.NAT,
34
+ [ENDORSED_UI_KEY]: ParamTypes.STRING,
35
+ };
36
+ harden(vaultDirectorParamTypes);
28
37
 
29
38
  /**
30
- * @param {Amount} electorateInvitationAmount
31
- * @param {Installation} liquidationInstall
32
- * @param {import('./liquidation.js').LiquidationTerms} liquidationTerms
33
- * @param {Amount} minInitialDebt
34
- * @param {Amount} shortfallInvitationAmount
39
+ * @param {Amount<'set'>} electorateInvitationAmount
40
+ * @param {Amount<'nat'>} minInitialDebt
41
+ * @param {Amount<'set'>} shortfallInvitationAmount
42
+ * @param {string} endorsedUi
43
+ * @param {InterestTiming} interestTiming
35
44
  */
36
45
  const makeVaultDirectorParams = (
37
46
  electorateInvitationAmount,
38
- liquidationInstall,
39
- liquidationTerms,
40
47
  minInitialDebt,
41
48
  shortfallInvitationAmount,
49
+ endorsedUi,
50
+ interestTiming,
42
51
  ) => {
43
52
  return harden({
44
53
  [CONTRACT_ELECTORATE]: {
45
54
  type: ParamTypes.INVITATION,
46
55
  value: electorateInvitationAmount,
47
56
  },
48
- [LIQUIDATION_INSTALL_KEY]: {
49
- type: ParamTypes.INSTALLATION,
50
- value: liquidationInstall,
51
- },
52
- [LIQUIDATION_TERMS_KEY]: {
53
- type: ParamTypes.UNKNOWN,
54
- value: liquidationTerms,
55
- },
56
57
  [MIN_INITIAL_DEBT_KEY]: {
57
58
  type: ParamTypes.AMOUNT,
58
59
  value: minInitialDebt,
@@ -61,136 +62,156 @@ const makeVaultDirectorParams = (
61
62
  type: ParamTypes.INVITATION,
62
63
  value: shortfallInvitationAmount,
63
64
  },
65
+ [ENDORSED_UI_KEY]: { type: ParamTypes.STRING, value: endorsedUi },
66
+ [CHARGING_PERIOD_KEY]: {
67
+ type: ParamTypes.NAT,
68
+ value: TimeMath.relValue(interestTiming.chargingPeriod),
69
+ },
70
+ [RECORDING_PERIOD_KEY]: {
71
+ type: ParamTypes.NAT,
72
+ value: TimeMath.relValue(interestTiming.recordingPeriod),
73
+ },
64
74
  });
65
75
  };
76
+ harden(makeVaultDirectorParams);
66
77
 
67
78
  /** @typedef {import('@agoric/governance/src/contractGovernance/typedParamManager').ParamTypesMapFromRecord<ReturnType<typeof makeVaultDirectorParams>>} VaultDirectorParams */
68
79
 
80
+ /** @type {(liquidationMargin: Ratio) => Ratio} */
81
+ const zeroRatio = liquidationMargin =>
82
+ subtractRatios(liquidationMargin, liquidationMargin);
83
+
69
84
  /**
70
85
  * @param {import('@agoric/notifier').StoredPublisherKit<GovernanceSubscriptionState>} publisherKit
71
86
  * @param {VaultManagerParamValues} initial
72
87
  */
73
- const makeVaultParamManager = (publisherKit, initial) =>
88
+ export const makeVaultParamManager = (
89
+ publisherKit,
90
+ {
91
+ debtLimit,
92
+ interestRate,
93
+ liquidationMargin,
94
+ liquidationPadding = zeroRatio(liquidationMargin),
95
+ liquidationPenalty,
96
+ mintFee,
97
+ },
98
+ ) =>
74
99
  makeParamManagerSync(publisherKit, {
75
- [DEBT_LIMIT_KEY]: [ParamTypes.AMOUNT, initial.debtLimit],
76
- [LIQUIDATION_MARGIN_KEY]: [ParamTypes.RATIO, initial.liquidationMargin],
77
- [LIQUIDATION_PENALTY_KEY]: [ParamTypes.RATIO, initial.liquidationPenalty],
78
- [INTEREST_RATE_KEY]: [ParamTypes.RATIO, initial.interestRate],
79
- [LOAN_FEE_KEY]: [ParamTypes.RATIO, initial.loanFee],
100
+ [DEBT_LIMIT_KEY]: [ParamTypes.AMOUNT, debtLimit],
101
+ [INTEREST_RATE_KEY]: [ParamTypes.RATIO, interestRate],
102
+ [LIQUIDATION_PADDING_KEY]: [ParamTypes.RATIO, liquidationPadding],
103
+ [LIQUIDATION_MARGIN_KEY]: [ParamTypes.RATIO, liquidationMargin],
104
+ [LIQUIDATION_PENALTY_KEY]: [ParamTypes.RATIO, liquidationPenalty],
105
+ [MINT_FEE_KEY]: [ParamTypes.RATIO, mintFee],
80
106
  });
81
107
  /** @typedef {ReturnType<typeof makeVaultParamManager>} VaultParamManager */
82
108
 
83
- export const vaultParamPattern = M.split(
109
+ export const vaultParamPattern = M.splitRecord(
84
110
  {
85
111
  liquidationMargin: ratioPattern,
86
112
  liquidationPenalty: ratioPattern,
87
113
  interestRate: ratioPattern,
88
- loanFee: ratioPattern,
114
+ mintFee: ratioPattern,
89
115
  debtLimit: amountPattern,
90
116
  },
91
- M.any(),
117
+ {
118
+ // optional for backwards compatibility, e.g. with loadgen
119
+ liquidationPadding: ratioPattern,
120
+ },
92
121
  );
93
122
 
94
123
  /**
95
- * @param {import('@agoric/notifier').StoredPublisherKit<GovernanceSubscriptionState>} publisherKit
96
- * @param {ERef<ZoeService>} zoe
97
- * @param {Invitation} electorateInvitation
98
- * @param {Installation} liquidationInstall
99
- * @param {object} liquidationTerms
100
- * @param {Amount} minInitialDebt
101
- * @param {Invitation} shortfallInvitation
102
- */
103
- const makeVaultDirectorParamManager = async (
104
- publisherKit,
105
- zoe,
106
- electorateInvitation,
107
- liquidationInstall,
108
- liquidationTerms,
109
- minInitialDebt,
110
- shortfallInvitation,
111
- ) => {
112
- return makeParamManager(
113
- publisherKit,
114
- {
115
- [CONTRACT_ELECTORATE]: [ParamTypes.INVITATION, electorateInvitation],
116
- [LIQUIDATION_INSTALL_KEY]: [ParamTypes.INSTALLATION, liquidationInstall],
117
- [LIQUIDATION_TERMS_KEY]: [ParamTypes.UNKNOWN, liquidationTerms],
118
- [MIN_INITIAL_DEBT_KEY]: [ParamTypes.AMOUNT, minInitialDebt],
119
- [SHORTFALL_INVITATION_KEY]: [ParamTypes.INVITATION, shortfallInvitation],
120
- },
121
- zoe,
122
- );
123
- };
124
-
125
- /**
126
- * @param {{storageNode: ERef<StorageNode>, marshaller: ERef<Marshaller>}} caps
127
124
  * @param {{
128
- * electorateInvitationAmount: Amount,
129
- * minInitialDebt: Amount,
125
+ * auctioneerPublicFacet: ERef<AuctioneerPublicFacet>,
126
+ * electorateInvitationAmount: Amount<'set'>,
127
+ * minInitialDebt: Amount<'nat'>,
130
128
  * bootstrapPaymentValue: bigint,
131
129
  * priceAuthority: ERef<PriceAuthority>,
132
- * timer: ERef<TimerService>,
130
+ * timer: ERef<import('@agoric/time/src/types').TimerService>,
133
131
  * reservePublicFacet: AssetReservePublicFacet,
134
- * liquidationInstall: Installation,
135
- * loanTiming: LoanTiming,
136
- * liquidationTerms: import('./liquidation.js').LiquidationTerms,
137
- * ammPublicFacet: XYKAMMPublicFacet,
138
- * shortfallInvitationAmount: Amount,
132
+ * interestTiming: InterestTiming,
133
+ * shortfallInvitationAmount: Amount<'set'>,
134
+ * endorsedUi?: string,
139
135
  * }} opts
140
136
  */
141
- const makeGovernedTerms = (
142
- { storageNode, marshaller },
143
- {
144
- ammPublicFacet,
145
- bootstrapPaymentValue,
146
- electorateInvitationAmount,
147
- liquidationInstall,
148
- liquidationTerms,
149
- loanTiming,
150
- minInitialDebt,
151
- priceAuthority,
152
- reservePublicFacet,
153
- timer,
154
- shortfallInvitationAmount,
155
- },
156
- ) => {
157
- const loanTimingParams = makeParamManagerSync(
158
- makeStoredPublisherKit(storageNode, marshaller, 'timingParams'),
159
- {
160
- [CHARGING_PERIOD_KEY]: [
161
- 'nat',
162
- TimeMath.relValue(loanTiming.chargingPeriod),
163
- ],
164
- [RECORDING_PERIOD_KEY]: [
165
- 'nat',
166
- TimeMath.relValue(loanTiming.recordingPeriod),
167
- ],
168
- },
169
- ).getParams();
170
-
137
+ export const makeGovernedTerms = ({
138
+ auctioneerPublicFacet,
139
+ bootstrapPaymentValue,
140
+ electorateInvitationAmount,
141
+ interestTiming,
142
+ minInitialDebt,
143
+ priceAuthority,
144
+ reservePublicFacet,
145
+ timer,
146
+ shortfallInvitationAmount,
147
+ endorsedUi = 'NO ENDORSEMENT',
148
+ }) => {
171
149
  return harden({
172
- ammPublicFacet,
150
+ auctioneerPublicFacet,
173
151
  priceAuthority,
174
- loanTimingParams,
175
152
  reservePublicFacet,
176
153
  timerService: timer,
177
154
  governedParams: makeVaultDirectorParams(
178
155
  electorateInvitationAmount,
179
- liquidationInstall,
180
- liquidationTerms,
181
156
  minInitialDebt,
182
157
  shortfallInvitationAmount,
158
+ endorsedUi,
159
+ interestTiming,
183
160
  ),
184
161
  bootstrapPaymentValue,
185
162
  });
186
163
  };
187
-
188
- harden(makeVaultParamManager);
189
- harden(makeVaultDirectorParamManager);
190
164
  harden(makeGovernedTerms);
165
+ /**
166
+ * Stop-gap which restores initial param values
167
+ * UNTIL https://github.com/Agoric/agoric-sdk/issues/5200
168
+ *
169
+ * NB: changes from initial values will be lost upon restart
170
+ *
171
+ * @param {import('@agoric/vat-data').Baggage} baggage
172
+ * @param {ERef<Marshaller>} marshaller
173
+ */
174
+ export const provideVaultParamManagers = (baggage, marshaller) => {
175
+ /** @type {MapStore<Brand, VaultParamManager>} */
176
+ const managers = makeScalarMapStore();
177
+
178
+ // the managers aren't durable but their arguments are
179
+ /** @type {MapStore<Brand, {storageNode: StorageNode, initialParamValues: VaultManagerParamValues}>} */
180
+ const managerArgs = provideDurableMapStore(
181
+ baggage,
182
+ 'vault param manager parts',
183
+ );
184
+
185
+ const makeManager = (brand, { storageNode, initialParamValues }) => {
186
+ const manager = makeVaultParamManager(
187
+ makeStoredPublisherKit(storageNode, marshaller, 'governance'),
188
+ initialParamValues,
189
+ );
190
+ managers.init(brand, manager);
191
+ return manager;
192
+ };
193
+
194
+ // restore from baggage
195
+ [...managerArgs.entries()].map(([brand, args]) => makeManager(brand, args));
191
196
 
192
- export {
193
- makeVaultDirectorParamManager,
194
- makeVaultParamManager,
195
- makeGovernedTerms,
197
+ return {
198
+ /**
199
+ *
200
+ * @param {Brand} brand
201
+ * @param {StorageNode} storageNode
202
+ * @param {VaultManagerParamValues} initialParamValues
203
+ */
204
+ addParamManager(brand, storageNode, initialParamValues) {
205
+ const args = harden({ storageNode, initialParamValues });
206
+ managerArgs.init(brand, args);
207
+ return makeManager(brand, args);
208
+ },
209
+ /**
210
+ * @param {Brand} brand
211
+ */
212
+ get(brand) {
213
+ return managers.get(brand);
214
+ },
215
+ };
196
216
  };
217
+ harden(provideVaultParamManagers);
@@ -1,22 +1,24 @@
1
- // @ts-check
2
1
  // @jessie-check
3
2
 
3
+ import { makeTracer } from '@agoric/internal';
4
4
  import { makeRatioFromAmounts } from '@agoric/zoe/src/contractSupport/index.js';
5
5
  import { AmountMath } from '@agoric/ertp';
6
- import { ratioGTE } from '@agoric/zoe/src/contractSupport/ratio.js';
7
6
  import { Far } from '@endo/marshal';
8
- import { keyEQ, keyLT } from '@agoric/store';
7
+ import { M } from '@agoric/vat-data';
8
+ import { makeScalarMapStore } from '@agoric/store';
9
9
  import { makeOrderedVaultStore } from './orderedVaultStore.js';
10
- import { fromVaultKey, toVaultKey } from './storeUtils.js';
11
- import { makeTracer } from '../makeTracer.js';
12
-
13
- const trace = makeTracer('PV', false);
10
+ import {
11
+ toVaultKey,
12
+ normalizedCollRatioKey,
13
+ normalizedCollRatio,
14
+ } from './storeUtils.js';
14
15
 
15
16
  /** @typedef {import('./vault').Vault} Vault */
16
17
  /** @typedef {import('./storeUtils.js').NormalizedDebt} NormalizedDebt */
17
18
 
19
+ const trace = makeTracer('PVaults', true);
20
+
18
21
  /**
19
- *
20
22
  * @param {Amount<'nat'>} debtAmount
21
23
  * @param {Amount<'nat'>} collateralAmount
22
24
  * @returns {Ratio}
@@ -32,7 +34,6 @@ const calculateDebtToCollateral = (debtAmount, collateralAmount) => {
32
34
  };
33
35
 
34
36
  /**
35
- *
36
37
  * @param {Vault} vault
37
38
  * @returns {Ratio}
38
39
  */
@@ -47,43 +48,15 @@ export const currentDebtToCollateral = vault =>
47
48
  * can be quickly found and liquidated.
48
49
  *
49
50
  * @param {MapStore<string, Vault>} store
50
- * @param {(highestRatio: Ratio) => void} [higherHighestCb] called when a new
51
51
  * vault has a higher debt ratio than the previous highest
52
52
  */
53
- export const makePrioritizedVaults = (store, higherHighestCb = () => {}) => {
53
+ export const makePrioritizedVaults = store => {
54
54
  const vaults = makeOrderedVaultStore(store);
55
55
 
56
- /**
57
- * Called back when there's a new highestRatio and it's higher than the previous.
58
- *
59
- * In other words, when a new highestRatio results from adding a vault. Removing the
60
- * first vault also changes the highest, but necessarily to a lower highest,
61
- * for which there are no use cases requiring notification.
62
- *
63
- * @param {(highestRatio: Ratio) => void} callback
64
- */
65
- const onHigherHighest = callback => {
66
- higherHighestCb = callback;
67
- };
68
-
69
- // To deal with fluctuating prices and varying collateralization, we schedule a
70
- // new request to the priceAuthority when some vault's debtToCollateral ratio
71
- // surpasses the current high-water mark. When the request that is at the
72
- // current high-water mark fires, we reschedule at the new (presumably
73
- // lower) rate.
74
- // Without this we'd be calling reschedulePriceCheck() unnecessarily
75
- /** @type {string=} */
76
- let firstKey;
77
-
78
- // Check if this ratio of debt to collateral would be the highest known. If
79
- // so, reset our highest and invoke the callback. This can be called on new
80
- // vaults and when we get a state update for a vault changing balances.
81
- /** @param {Ratio} collateralToDebt */
82
-
83
56
  /**
84
57
  * Ratio of the least-collateralized vault, if there is one.
85
58
  *
86
- * @returns {Ratio=} actual debt over collateral
59
+ * @returns {Ratio | undefined} actual debt over collateral
87
60
  */
88
61
  const highestRatio = () => {
89
62
  if (vaults.getSize() === 0) {
@@ -99,7 +72,6 @@ export const makePrioritizedVaults = (store, higherHighestCb = () => {}) => {
99
72
  };
100
73
 
101
74
  /**
102
- *
103
75
  * @param {NormalizedDebt} oldDebt
104
76
  * @param {Amount<'nat'>} oldCollateral
105
77
  * @param {string} vaultId
@@ -115,16 +87,10 @@ export const makePrioritizedVaults = (store, higherHighestCb = () => {}) => {
115
87
  */
116
88
  const removeVault = key => {
117
89
  const vault = vaults.removeByKey(key);
118
- trace('removeVault', key, fromVaultKey(key), 'when first:', firstKey);
119
- if (keyEQ(key, firstKey)) {
120
- const [secondKey] = vaults.keys();
121
- firstKey = secondKey;
122
- }
123
90
  return vault;
124
91
  };
125
92
 
126
93
  /**
127
- *
128
94
  * @param {NormalizedDebt} oldDebt
129
95
  * @param {Amount<'nat'>} oldCollateral
130
96
  * @param {string} vaultId
@@ -135,7 +101,6 @@ export const makePrioritizedVaults = (store, higherHighestCb = () => {}) => {
135
101
  };
136
102
 
137
103
  /**
138
- *
139
104
  * @param {VaultId} vaultId
140
105
  * @param {Vault} vault
141
106
  */
@@ -145,50 +110,42 @@ export const makePrioritizedVaults = (store, higherHighestCb = () => {}) => {
145
110
  !AmountMath.isEmpty(vault.getCollateralAmount()),
146
111
  'Tracked vaults must have collateral (be liquidatable)',
147
112
  );
148
- trace('addVault', key, 'when first:', firstKey);
149
- if (!firstKey || keyLT(key, firstKey)) {
150
- firstKey = key;
151
- higherHighestCb(currentDebtToCollateral(vault));
152
- }
153
113
  return key;
154
114
  };
155
115
 
156
- /**
157
- * Invoke a function for vaults with debt to collateral at or above the ratio.
158
- *
159
- * Results are returned in order of priority, with highest debt to collateral first.
160
- *
161
- * Redundant tags until https://github.com/Microsoft/TypeScript/issues/23857
162
- *
163
- * @param {Ratio} ratio
164
- * @yields {[string, Vault]>}
165
- * @returns {IterableIterator<[string, Vault]>}
166
- */
167
- // Allow generator function
168
- // eslint-disable-next-line func-names
169
- // eslint-disable-next-line no-restricted-syntax
170
- function* entriesPrioritizedGTE(ratio) {
171
- // TODO use a Pattern to limit the query https://github.com/Agoric/agoric-sdk/issues/4550
172
- for (const [key, vault] of vaults.entries()) {
173
- const debtToCollateral = currentDebtToCollateral(vault);
174
- if (ratioGTE(debtToCollateral, ratio)) {
175
- yield [key, vault];
176
- } else {
177
- // stop once we are below the target ratio
178
- break;
179
- }
116
+ const removeVaultsBelow = ({ margin, quote, interest }) => {
117
+ // crKey represents a collateralizationRatio based on the locked price, the
118
+ // interest charged so far, and the liquidation margin.
119
+ // We'll remove all vaults below that ratio, and return them.
120
+ const crKey = normalizedCollRatioKey(quote, interest, margin);
121
+
122
+ trace(
123
+ `Liquidating vaults worse than`,
124
+ normalizedCollRatio(quote, interest, margin),
125
+ );
126
+
127
+ /** @type {MapStore<string, Vault>} */
128
+ const vaultsRemoved = makeScalarMapStore();
129
+
130
+ for (const [key, vault] of vaults.entries(M.lte(crKey))) {
131
+ vaultsRemoved.init(key, vault);
132
+ vaults.removeByKey(key);
180
133
  }
181
- }
134
+
135
+ return vaultsRemoved;
136
+ };
182
137
 
183
138
  return Far('PrioritizedVaults', {
184
139
  addVault,
185
140
  entries: vaults.entries,
186
- entriesPrioritizedGTE,
187
141
  getCount: vaults.getSize,
188
142
  hasVaultByAttributes,
189
143
  highestRatio,
190
144
  removeVault,
191
145
  removeVaultByAttributes,
192
- onHigherHighest,
146
+ removeVaultsBelow,
147
+
148
+ // visible for testing
149
+ countVaultsBelow: crKey => vaults.getSize(M.lte(crKey)),
193
150
  });
194
151
  };
@@ -1,4 +1,5 @@
1
- // @ts-check
1
+ // @jessie-check
2
+
2
3
  /**
3
4
  * Module to improvise composite keys for orderedVaultStore until Collections
4
5
  * API supports them.
@@ -6,7 +7,17 @@
6
7
 
7
8
  // XXX importing these that are declared to be used only for testing
8
9
  // until @agoric/store supports composite keys
9
- import { makeDecodePassable, makeEncodePassable } from '@agoric/store';
10
+ import { makeDecodePassable, makeEncodePassable } from '@endo/marshal';
11
+ import {
12
+ getAmountIn,
13
+ getAmountOut,
14
+ natSafeMath,
15
+ } from '@agoric/zoe/src/contractSupport/index.js';
16
+ import { makeTracer } from '@agoric/internal';
17
+
18
+ const { multiply } = natSafeMath;
19
+
20
+ const trace = makeTracer('Store', true);
10
21
 
11
22
  /**
12
23
  * @typedef {import('@endo/marshal').PureData} PureData
@@ -25,7 +36,7 @@ import { makeDecodePassable, makeEncodePassable } from '@agoric/store';
25
36
  * @param {PureData} key
26
37
  * @returns {string}
27
38
  */
28
- const encodeData = makeEncodePassable();
39
+ export const encodeData = makeEncodePassable();
29
40
 
30
41
  // `makeDecodePassable` has three named options:
31
42
  // `decodeRemotable`, `decodeError`, and `decodePromise`.
@@ -36,7 +47,7 @@ const encodeData = makeEncodePassable();
36
47
  * @param {string} encoded
37
48
  * @returns {PureData}
38
49
  */
39
- const decodeData = makeDecodePassable();
50
+ export const decodeData = makeDecodePassable();
40
51
 
41
52
  /**
42
53
  * @param {number} n
@@ -86,7 +97,7 @@ const collateralizationRatio = (normalizedDebt, collateral) => {
86
97
  * @returns {string} lexically sortable string in which highest
87
98
  * debt-to-collateral is earliest
88
99
  */
89
- const toVaultKey = (normalizedDebt, collateral, vaultId) => {
100
+ export const toVaultKey = (normalizedDebt, collateral, vaultId) => {
90
101
  assert(normalizedDebt);
91
102
  assert(collateral);
92
103
  assert(vaultId);
@@ -95,19 +106,66 @@ const toVaultKey = (normalizedDebt, collateral, vaultId) => {
95
106
  const numberPart = encodeNumber(
96
107
  collateralizationRatio(normalizedDebt, collateral),
97
108
  );
109
+
110
+ trace(`To Vault Key `, collateralizationRatio(normalizedDebt, collateral));
98
111
  return `${numberPart}:${vaultId}`;
99
112
  };
113
+ harden(toVaultKey);
100
114
 
101
115
  /**
102
116
  * @param {string} key
103
117
  * @returns {[normalizedCollateralization: number, vaultId: VaultId]}
104
118
  */
105
- const fromVaultKey = key => {
119
+ export const fromVaultKey = key => {
106
120
  const [numberPart, vaultIdPart] = key.split(':');
107
121
  return [decodeNumber(numberPart), vaultIdPart];
108
122
  };
109
-
110
123
  harden(fromVaultKey);
111
- harden(toVaultKey);
112
124
 
113
- export { fromVaultKey, toVaultKey };
125
+ /**
126
+ * Create a float representing a Normalized Collateralization Ratio that can be
127
+ * compared to the NCRs of vaults. We want a float with as much resolution as we
128
+ * can get, so we multiply out the numerator and the denominator, and only
129
+ * divide the results once.
130
+ *
131
+ * For use by `normalizedCollRatioKey` and tests.
132
+ *
133
+ * @param {PriceQuote} quote
134
+ * @param {Ratio} compoundedInterest
135
+ * @param {Ratio} margin
136
+ * @returns {number}
137
+ */
138
+ export const normalizedCollRatio = (quote, compoundedInterest, margin) => {
139
+ const amountIn = getAmountIn(quote).value;
140
+ const amountOut = getAmountOut(quote).value;
141
+ const interestNumerator = compoundedInterest.numerator.value;
142
+ const interestBase = compoundedInterest.denominator.value;
143
+ const numerator = multiply(
144
+ margin.numerator.value,
145
+ multiply(amountIn, interestNumerator),
146
+ );
147
+ const denominator = multiply(
148
+ amountOut,
149
+ multiply(interestBase, margin.denominator.value),
150
+ );
151
+
152
+ return Number(numerator) / Number(denominator);
153
+ };
154
+ harden(normalizedCollRatio);
155
+
156
+ /**
157
+ * Create a sort key for a normalized collateralization ratio. We want the key
158
+ * to be based on a float with as much resolution as we can get, so we multiply
159
+ * out the numerator and the denominator, and divide only once.
160
+ *
161
+ * @param {PriceQuote} quote
162
+ * @param {Ratio} compoundedInterest
163
+ * @param {Ratio} margin
164
+ * @returns {string} lexically sortable string in which highest
165
+ * debt-to-collateral is earliest
166
+ */
167
+ export const normalizedCollRatioKey = (quote, compoundedInterest, margin) => {
168
+ const collRatio = normalizedCollRatio(quote, compoundedInterest, margin);
169
+ return `${encodeNumber(collRatio)}:`;
170
+ };
171
+ harden(normalizedCollRatioKey);
@@ -1,2 +1,4 @@
1
+ // @jessie-check
2
+
1
3
  import '@agoric/zoe/exported.js';
2
4
  import './types.js';