@agoric/inter-protocol 0.13.2-dev-0e039d9.0 → 0.13.2-dev-ed5ee58.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 (71) hide show
  1. package/bundles/bundle-econCommitteeCharter-meta.js +78 -78
  2. package/bundles/bundle-econCommitteeCharter.js +1 -1
  3. package/bundles/bundle-feeDistributor-meta.js +61 -61
  4. package/bundles/bundle-feeDistributor.js +1 -1
  5. package/bundles/bundle-fluxAggregator-meta.js +114 -114
  6. package/bundles/bundle-fluxAggregator.js +1 -1
  7. package/bundles/bundle-psm-meta.js +112 -112
  8. package/bundles/bundle-psm.js +1 -1
  9. package/bundles/bundle-reserve-meta.js +110 -114
  10. package/bundles/bundle-reserve.js +1 -1
  11. package/bundles/bundle-scaledPriceAuthority-meta.js +78 -78
  12. package/bundles/bundle-scaledPriceAuthority.js +1 -1
  13. package/bundles/bundle-stakeFactory-meta.js +118 -118
  14. package/bundles/bundle-stakeFactory.js +1 -1
  15. package/bundles/bundle-vaultFactory-meta.js +128 -128
  16. package/bundles/bundle-vaultFactory.js +1 -1
  17. package/exported.js +0 -1
  18. package/package.json +16 -16
  19. package/scripts/deploy-contracts.js +0 -2
  20. package/scripts/init-core.js +0 -16
  21. package/src/feeDistributor.js +1 -1
  22. package/src/proposals/addAssetToVault.js +4 -57
  23. package/src/proposals/committee-proposal.js +3 -6
  24. package/src/proposals/core-proposal.js +1 -73
  25. package/src/proposals/demoIssuers.js +1 -232
  26. package/src/proposals/econ-behaviors.js +10 -193
  27. package/src/proposals/sim-behaviors.js +1 -1
  28. package/src/reserve/assetReserve.js +9 -170
  29. package/src/reserve/params.js +1 -4
  30. package/src/vaultFactory/liquidateIncrementally.js +16 -141
  31. package/src/vaultFactory/liquidateMinimum.js +19 -21
  32. package/src/vaultFactory/params.js +0 -29
  33. package/src/vaultFactory/types.js +0 -6
  34. package/src/vaultFactory/vault.js +1 -3
  35. package/src/vaultFactory/vaultDirector.js +1 -33
  36. package/src/vaultFactory/vaultFactory.js +2 -12
  37. package/src/vaultFactory/vaultManager.js +10 -217
  38. package/bundles/bundle-amm-meta.js +0 -686
  39. package/bundles/bundle-amm.js +0 -1
  40. package/bundles/bundle-interchainPool-meta.js +0 -606
  41. package/bundles/bundle-interchainPool.js +0 -1
  42. package/bundles/bundle-liquidateIncrementally-meta.js +0 -470
  43. package/bundles/bundle-liquidateIncrementally.js +0 -1
  44. package/bundles/bundle-liquidateMinimum-meta.js +0 -470
  45. package/bundles/bundle-liquidateMinimum.js +0 -1
  46. package/scripts/add-initial-liquidity.js +0 -179
  47. package/src/interchainPool.js +0 -134
  48. package/src/vpool-xyk-amm/AttackersGuide.md +0 -89
  49. package/src/vpool-xyk-amm/addLiquidity.js +0 -221
  50. package/src/vpool-xyk-amm/addPool.js +0 -200
  51. package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
  52. package/src/vpool-xyk-amm/constantProduct/README.md +0 -204
  53. package/src/vpool-xyk-amm/constantProduct/calcFees.js +0 -93
  54. package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +0 -83
  55. package/src/vpool-xyk-amm/constantProduct/core.js +0 -145
  56. package/src/vpool-xyk-amm/constantProduct/defaults.js +0 -3
  57. package/src/vpool-xyk-amm/constantProduct/getXY.js +0 -48
  58. package/src/vpool-xyk-amm/constantProduct/internal-types.js +0 -114
  59. package/src/vpool-xyk-amm/constantProduct/invariants.js +0 -39
  60. package/src/vpool-xyk-amm/constantProduct/swap.js +0 -270
  61. package/src/vpool-xyk-amm/constantProduct/types.js +0 -30
  62. package/src/vpool-xyk-amm/doublePool.js +0 -200
  63. package/src/vpool-xyk-amm/estimate.js +0 -175
  64. package/src/vpool-xyk-amm/multipoolMarketMaker.js +0 -530
  65. package/src/vpool-xyk-amm/params.js +0 -59
  66. package/src/vpool-xyk-amm/pool.js +0 -398
  67. package/src/vpool-xyk-amm/priceAuthority.js +0 -92
  68. package/src/vpool-xyk-amm/removeLiquidity.js +0 -29
  69. package/src/vpool-xyk-amm/singlePool.js +0 -88
  70. package/src/vpool-xyk-amm/swap.js +0 -68
  71. package/src/vpool-xyk-amm/types.js +0 -152
@@ -1,398 +0,0 @@
1
- import '@agoric/zoe/exported.js';
2
-
3
- import { AmountMath, isNatValue } from '@agoric/ertp';
4
- import { makeStoredPublishKit } from '@agoric/notifier';
5
- import { prepareKindMulti } from '@agoric/vat-data';
6
- import {
7
- calcLiqValueToMint,
8
- calcSecondaryRequired,
9
- calcValueToRemove,
10
- atomicRearrange,
11
- } from '@agoric/zoe/src/contractSupport/index.js';
12
-
13
- import { E } from '@endo/eventual-send';
14
- import { makeMetricsPublisherKit } from '../contractSupport.js';
15
- import { makePriceAuthority } from './priceAuthority.js';
16
- import { makeSinglePool } from './singlePool.js';
17
-
18
- // Pools represent a single pool of liquidity. Price calculations and trading
19
- // happen in a wrapper class that knows whether the proposed trade involves a
20
- // single pool or multiple hops.
21
-
22
- export const publicPrices = prices => {
23
- return { amountIn: prices.swapperGives, amountOut: prices.swapperGets };
24
- };
25
-
26
- /** @typedef {{ liquidityIssuerRecord: IssuerRecord<'nat'> }} InitPublication */
27
-
28
- /** @typedef {{ central: Amount, secondary: Amount }} NotificationState */
29
-
30
- /**
31
- * @typedef {Readonly<{
32
- * poolSeat: ZCFSeat,
33
- * secondaryBrand: Brand<'nat'>,
34
- * liquidityZcfMint: ZCFMint,
35
- * }>} ImmutableState
36
- */
37
-
38
- /** @typedef {{liqTokenSupply: bigint}} MutableState */
39
-
40
- /**
41
- * @typedef {{
42
- * addLiquidityInternal: AddLiquidityInternal,
43
- * addLiquidityActual: AddLiquidityActual,
44
- * updateMetrics: () => void,
45
- * }} HelperFacet
46
- */
47
-
48
- /**
49
- * @typedef {{
50
- * state: ImmutableState & MutableState,
51
- * facets: {
52
- * helper: HelperFacet,
53
- * pool: XYKPool,
54
- * singlePool: VirtualPool,
55
- * },
56
- * }} MethodContext
57
- *
58
- * @typedef {object} PoolMetricsNotification
59
- * @property {Amount} centralAmount
60
- * @property {Amount} secondaryAmount
61
- * @property {Amount} liquidityTokens - outstanding tokens
62
- */
63
-
64
- /** @typedef {import('@agoric/vat-data').Baggage} Baggage */
65
- /** @typedef {import('./multipoolMarketMaker.js').AmmPowers} AmmPowers */
66
-
67
- /**
68
- * @param {Baggage} baggage
69
- * @param {AmmPowers} ammPowers
70
- * @param {ERef<StorageNode>} storageNode
71
- * @param {ERef<Marshaller>} marshaller
72
- */
73
- export const definePoolKind = (baggage, ammPowers, storageNode, marshaller) => {
74
- /** @type {StoredPublishKit<NotificationState>} */
75
- const { subscriber, publisher } = makeStoredPublishKit(
76
- storageNode,
77
- marshaller,
78
- );
79
- /** @type {import('../contractSupport.js').MetricsPublisherKit<PoolMetricsNotification>} */
80
- const { metricsPublication, metricsSubscription } = makeMetricsPublisherKit(
81
- storageNode,
82
- marshaller,
83
- );
84
-
85
- /**
86
- * @param {ZCFMint<'nat'>} liquidityZcfMint
87
- * @param {ZCFSeat} poolSeat
88
- * @param {Brand<'nat'>} secondaryBrand
89
- * @returns {ImmutableState & MutableState}
90
- */
91
- const poolInit = (liquidityZcfMint, poolSeat, secondaryBrand) => {
92
- /** @type {StoredPublishKit<InitPublication>} */
93
- const { publisher: initPublisher } = makeStoredPublishKit(
94
- E(storageNode).makeChildNode('init'),
95
- marshaller,
96
- );
97
- initPublisher.finish({
98
- liquidityIssuerRecord: liquidityZcfMint.getIssuerRecord(),
99
- });
100
-
101
- return {
102
- liqTokenSupply: 0n,
103
- poolSeat,
104
- secondaryBrand,
105
- liquidityZcfMint,
106
- };
107
- };
108
-
109
- /** @param {MethodContext} context */
110
- const makePriceGetters = context => {
111
- const getPAInputPrice = (amountIn, brandOut) => {
112
- return publicPrices(
113
- context.facets.singlePool.getPriceForInput(
114
- amountIn,
115
- AmountMath.makeEmpty(brandOut),
116
- ),
117
- );
118
- };
119
- const getPAOutputPrice = (brandIn, amountout) =>
120
- publicPrices(
121
- context.facets.singlePool.getPriceForOutput(
122
- AmountMath.makeEmpty(brandIn),
123
- amountout,
124
- ),
125
- );
126
- return { getPAInputPrice, getPAOutputPrice };
127
- };
128
-
129
- let toCentralPriceAuthority;
130
- const provideToCentralPriceAuthority = context => {
131
- if (!toCentralPriceAuthority) {
132
- const { getPAInputPrice, getPAOutputPrice } = makePriceGetters(context);
133
- const { secondaryBrand } = context.state;
134
- const { quoteIssuerKit } = ammPowers;
135
- toCentralPriceAuthority = makePriceAuthority(
136
- getPAInputPrice,
137
- getPAOutputPrice,
138
- secondaryBrand,
139
- ammPowers.centralBrand,
140
- ammPowers.timer,
141
- subscriber,
142
- quoteIssuerKit,
143
- );
144
- }
145
- return toCentralPriceAuthority;
146
- };
147
-
148
- let fromCentralPriceAuthority;
149
- const provideFromCentralPriceAuthority = context => {
150
- if (!fromCentralPriceAuthority) {
151
- const { getPAInputPrice, getPAOutputPrice } = makePriceGetters(context);
152
- const { secondaryBrand } = context.state;
153
- const quoteIssuerKit = ammPowers.quoteIssuerKit;
154
- fromCentralPriceAuthority = makePriceAuthority(
155
- getPAInputPrice,
156
- getPAOutputPrice,
157
- ammPowers.centralBrand,
158
- secondaryBrand,
159
- ammPowers.timer,
160
- subscriber,
161
- quoteIssuerKit,
162
- );
163
- }
164
- return fromCentralPriceAuthority;
165
- };
166
-
167
- const poolBehavior = {
168
- getLiquiditySupply: ({ state: { liqTokenSupply } }) => liqTokenSupply,
169
- getLiquidityIssuer: ({ state: { liquidityZcfMint } }) =>
170
- liquidityZcfMint.getIssuerRecord().issuer,
171
- getPoolSeat: ({ state: { poolSeat } }) => poolSeat,
172
- getCentralAmount: ({ state: { poolSeat } }) =>
173
- poolSeat.getAmountAllocated('Central', ammPowers.centralBrand),
174
- getSecondaryAmount: ({ state }) =>
175
- state.poolSeat.getAmountAllocated('Secondary', state.secondaryBrand),
176
-
177
- /**
178
- * @param {MethodContext} context
179
- * @param {ZCFSeat} zcfSeat
180
- * @returns {string}
181
- */
182
- addLiquidity: ({ state, facets }, zcfSeat) => {
183
- const { helper, pool } = facets;
184
- const centralIn = zcfSeat.getStagedAllocation().Central;
185
- assert(isNatValue(centralIn.value), 'User Central');
186
- const secondaryIn = zcfSeat.getStagedAllocation().Secondary;
187
- assert(isNatValue(secondaryIn.value), 'User Secondary');
188
-
189
- if (state.liqTokenSupply === 0n) {
190
- return helper.addLiquidityActual(pool, zcfSeat, secondaryIn, centralIn);
191
- }
192
-
193
- const centralPoolAmount = pool.getCentralAmount();
194
- const secondaryPoolAmount = pool.getSecondaryAmount();
195
- assert(isNatValue(centralPoolAmount.value), 'Pool Central');
196
- assert(isNatValue(secondaryPoolAmount.value), 'Pool Secondary');
197
-
198
- // To calculate liquidity, we'll need to calculate alpha from the primary
199
- // token's value before, and the value that will be added to the pool
200
- const secondaryRequired = AmountMath.make(
201
- state.secondaryBrand,
202
- calcSecondaryRequired(
203
- centralIn.value,
204
- centralPoolAmount.value,
205
- secondaryPoolAmount.value,
206
- secondaryIn.value,
207
- ),
208
- );
209
-
210
- // Central was specified precisely so offer must provide enough secondary.
211
- assert(
212
- AmountMath.isGTE(secondaryIn, secondaryRequired),
213
- 'insufficient Secondary deposited',
214
- );
215
-
216
- return helper.addLiquidityActual(
217
- pool,
218
- zcfSeat,
219
- secondaryRequired,
220
- centralPoolAmount,
221
- );
222
- },
223
- removeLiquidity: ({ state, facets }, userSeat) => {
224
- const { liquidityZcfMint, poolSeat, secondaryBrand } = state;
225
- const liquidityBrand = liquidityZcfMint.getIssuerRecord().brand;
226
- const liquidityIn = userSeat.getAmountAllocated(
227
- 'Liquidity',
228
- liquidityBrand,
229
- );
230
- if (AmountMath.isEmpty(liquidityIn)) {
231
- // prevent divide-by-zero. If the caller has tokens, the pool is not empty
232
- userSeat.exit();
233
- return 'request to remove zero liquidity';
234
- }
235
-
236
- const liquidityValueIn = liquidityIn.value;
237
- assert(isNatValue(liquidityValueIn), 'User Liquidity');
238
- const centralTokenAmountOut = AmountMath.make(
239
- ammPowers.centralBrand,
240
- calcValueToRemove(
241
- state.liqTokenSupply,
242
- facets.pool.getCentralAmount().value,
243
- liquidityValueIn,
244
- ),
245
- );
246
-
247
- const tokenKeywordAmountOut = AmountMath.make(
248
- secondaryBrand,
249
- calcValueToRemove(
250
- state.liqTokenSupply,
251
- facets.pool.getSecondaryAmount().value,
252
- liquidityValueIn,
253
- ),
254
- );
255
-
256
- atomicRearrange(
257
- ammPowers.zcf,
258
- harden([
259
- [userSeat, poolSeat, { Liquidity: liquidityIn }],
260
- [
261
- poolSeat,
262
- userSeat,
263
- {
264
- Central: centralTokenAmountOut,
265
- Secondary: tokenKeywordAmountOut,
266
- },
267
- ],
268
- ]),
269
- );
270
-
271
- state.liqTokenSupply -= liquidityValueIn;
272
-
273
- userSeat.exit();
274
- facets.pool.updateState();
275
- return 'Liquidity successfully removed.';
276
- },
277
- getSubscriber: () => subscriber,
278
- /**
279
- * Update metrics and primary state
280
- *
281
- * @param {MethodContext} context
282
- */
283
- updateState: ({ facets: { pool, helper } }) => {
284
- helper.updateMetrics();
285
- publisher.publish({
286
- central: pool.getCentralAmount(),
287
- secondary: pool.getSecondaryAmount(),
288
- });
289
- },
290
-
291
- /** @deprecated priceAuthorities will not be provided by the AMM */
292
- getToCentralPriceAuthority: provideToCentralPriceAuthority,
293
- /** @deprecated priceAuthorities will not be provided by the AMM */
294
- getFromCentralPriceAuthority: provideFromCentralPriceAuthority,
295
-
296
- /** @param {MethodContext} context */
297
- getVPool: ({ facets }) => facets.singlePool,
298
- getMetrics: () => metricsSubscription,
299
- };
300
-
301
- /** @param {MethodContext} context */
302
- const finish = context => {
303
- context.facets.helper.updateMetrics();
304
- };
305
-
306
- const helperBehavior = {
307
- /** @type {import('@agoric/vat-data/src/types').PlusContext<MethodContext, AddLiquidityInternal>} */
308
- addLiquidityInternal: (
309
- { state },
310
- zcfSeat,
311
- secondaryAmount,
312
- poolCentralAmount,
313
- feeSeat,
314
- ) => {
315
- const { poolSeat, liquidityZcfMint } = state;
316
- // addLiquidity can't be called until the pool has been created. We verify
317
- // that the asset is NAT before creating a pool.
318
-
319
- const liquidityValueOut = calcLiqValueToMint(
320
- state.liqTokenSupply,
321
- // @ts-expect-error value could be not Nat
322
- zcfSeat.getStagedAllocation().Central.value,
323
- poolCentralAmount.value,
324
- );
325
-
326
- const liquidityAmountOut = AmountMath.make(
327
- liquidityZcfMint.getIssuerRecord().brand,
328
- liquidityValueOut,
329
- );
330
- liquidityZcfMint.mintGains(
331
- harden({ Liquidity: liquidityAmountOut }),
332
- poolSeat,
333
- );
334
- state.liqTokenSupply += liquidityValueOut;
335
-
336
- poolSeat.incrementBy(
337
- zcfSeat.decrementBy(
338
- harden({
339
- Central: zcfSeat.getStagedAllocation().Central,
340
- Secondary: secondaryAmount,
341
- }),
342
- ),
343
- );
344
-
345
- zcfSeat.incrementBy(
346
- poolSeat.decrementBy(harden({ Liquidity: liquidityAmountOut })),
347
- );
348
- if (feeSeat) {
349
- ammPowers.zcf.reallocate(poolSeat, zcfSeat, feeSeat);
350
- } else {
351
- ammPowers.zcf.reallocate(poolSeat, zcfSeat);
352
- }
353
- },
354
- /** @type {import('@agoric/vat-data/src/types').PlusContext<MethodContext, AddLiquidityActual>} */
355
- addLiquidityActual: (
356
- { facets },
357
- pool,
358
- zcfSeat,
359
- secondaryAmount,
360
- poolCentralAmount,
361
- feeSeat,
362
- ) => {
363
- const { helper } = facets;
364
-
365
- helper.addLiquidityInternal(
366
- zcfSeat,
367
- secondaryAmount,
368
- poolCentralAmount,
369
- feeSeat,
370
- );
371
- zcfSeat.exit();
372
- facets.pool.updateState();
373
- return 'Added liquidity.';
374
- },
375
- /** @param {MethodContext} context */
376
- updateMetrics: context => {
377
- const { state, facets } = context;
378
- const payload = harden({
379
- centralAmount: facets.pool.getCentralAmount(),
380
- secondaryAmount: facets.pool.getSecondaryAmount(),
381
- liquidityTokens: AmountMath.make(
382
- state.liquidityZcfMint.getIssuerRecord().brand,
383
- state.liqTokenSupply,
384
- ),
385
- });
386
-
387
- metricsPublication.updateState(payload);
388
- },
389
- };
390
-
391
- const facets = harden({
392
- helper: helperBehavior,
393
- pool: poolBehavior,
394
- singlePool: makeSinglePool(ammPowers),
395
- });
396
-
397
- return prepareKindMulti(baggage, 'pool', poolInit, facets, { finish });
398
- };
@@ -1,92 +0,0 @@
1
- import { AmountMath } from '@agoric/ertp';
2
- import {
3
- makeNotifierFromSubscriber,
4
- observeIteration,
5
- subscribeLatest,
6
- } from '@agoric/notifier';
7
- import { E } from '@endo/eventual-send';
8
- import { Far } from '@endo/marshal';
9
-
10
- import { makeOnewayPriceAuthorityKit } from '@agoric/zoe/src/contractSupport/index.js';
11
-
12
- /**
13
- *
14
- * @param {*} getOutputForGivenInput
15
- * @param {*} getInputForWantedOutput
16
- * @param {Brand<'nat'>} actualBrandIn
17
- * @param {Brand<'nat'>} actualBrandOut
18
- * @param {import('@agoric/time/src/types').TimerService} timer
19
- * @param {Subscriber<import('./pool').NotificationState>} subscriber
20
- * @param {IssuerKit<'set'>} quoteIssuerKit
21
- * @returns {PriceAuthority}
22
- */
23
- export const makePriceAuthority = (
24
- getOutputForGivenInput,
25
- getInputForWantedOutput,
26
- actualBrandIn,
27
- actualBrandOut,
28
- timer,
29
- subscriber,
30
- quoteIssuerKit,
31
- ) => {
32
- const { brand, issuer: quoteIssuer } = quoteIssuerKit;
33
-
34
- /** @param {PriceQuoteValue} quote */
35
- const authenticateQuote = quote => {
36
- const quoteAmount = AmountMath.make(brand, harden(quote));
37
- const quotePayment = quoteIssuerKit.mint.mintPayment(quoteAmount);
38
- return harden({ quoteAmount, quotePayment });
39
- };
40
-
41
- // called by createQuote for each trigger to compare price to trigger level
42
- const calcAmountOut = amountIn =>
43
- getOutputForGivenInput(amountIn, actualBrandOut).amountOut;
44
- const calcAmountIn = amountOut =>
45
- getInputForWantedOutput(actualBrandIn, amountOut).amountIn;
46
-
47
- /**
48
- * @param {PriceQuery} priceQuery
49
- * @returns {ERef<PriceQuote> | undefined}
50
- */
51
- function createQuote(priceQuery) {
52
- const quote = priceQuery(calcAmountOut, calcAmountIn);
53
- if (!quote) {
54
- return undefined;
55
- }
56
-
57
- const { amountIn, amountOut } = quote;
58
- return E(timer)
59
- .getCurrentTimestamp()
60
- .then(now =>
61
- authenticateQuote([{ amountIn, amountOut, timer, timestamp: now }]),
62
- );
63
- }
64
-
65
- const priceAuthorityOptions = harden({
66
- timer,
67
- createQuote,
68
- actualBrandIn,
69
- actualBrandOut,
70
- quoteIssuer,
71
- notifier: makeNotifierFromSubscriber(subscriber),
72
- });
73
-
74
- const {
75
- priceAuthority,
76
- adminFacet: { fireTriggers },
77
- } = makeOnewayPriceAuthorityKit(priceAuthorityOptions);
78
-
79
- // An observer on a notifier that gets updated when the pool's balances
80
- // change via swap or liquidity operations. It checks the comparison predicate
81
- // for each active trigger. Due to `subscribeLatest` below it may drop
82
- // intermediate values.
83
- const priceObserver = Far('priceObserver', {
84
- updateState: () => {
85
- void fireTriggers(createQuote);
86
- },
87
- });
88
-
89
- void observeIteration(subscribeLatest(subscriber), priceObserver);
90
-
91
- return priceAuthority;
92
- };
@@ -1,29 +0,0 @@
1
- import { assertProposalShape } from '@agoric/zoe/src/contractSupport/index.js';
2
-
3
- import '@agoric/zoe/exported.js';
4
-
5
- /**
6
- * @param {ZCF} zcf
7
- * @param {(brand: Brand) => XYKPool} getPool
8
- */
9
- export const makeMakeRemoveLiquidityInvitation = (zcf, getPool) => {
10
- const removeLiquidity = seat => {
11
- assertProposalShape(seat, {
12
- want: {
13
- Central: null,
14
- Secondary: null,
15
- },
16
- give: {
17
- Liquidity: null,
18
- },
19
- });
20
- // Get the brand of the secondary token so we can identify the liquidity pool.
21
- const secondaryBrand = seat.getProposal().want.Secondary.brand;
22
- const pool = getPool(secondaryBrand);
23
- return pool.removeLiquidity(seat);
24
- };
25
-
26
- const makeRemoveLiquidityInvitation = () =>
27
- zcf.makeInvitation(removeLiquidity, 'autoswap remove liquidity');
28
- return makeRemoveLiquidityInvitation;
29
- };
@@ -1,88 +0,0 @@
1
- import {
2
- atomicRearrange,
3
- fromOnly,
4
- toOnly,
5
- } from '@agoric/zoe/src/contractSupport/index.js';
6
- import { makeFeeRatio } from './constantProduct/calcFees.js';
7
- import {
8
- pricesForStatedInput,
9
- pricesForStatedOutput,
10
- } from './constantProduct/calcSwapPrices.js';
11
-
12
- const getSecondaryBrand = pool => pool.getSecondaryAmount().brand;
13
- const getCentralBrand = pool => pool.getCentralAmount().brand;
14
-
15
- const getPools = pool => ({
16
- Central: pool.getCentralAmount(),
17
- Secondary: pool.getSecondaryAmount(),
18
- });
19
-
20
- export const makeSinglePool = ammPowers => ({
21
- allocateGainsAndLosses: (context, seat, prices) => {
22
- const { pool } = context.facets;
23
- const { poolSeat } = context.state;
24
- const { zcf, protocolSeat } = ammPowers;
25
- const inBrand = prices.swapperGives.brand;
26
-
27
- /** @type {import('@agoric/zoe/src/contractSupport/atomicTransfer.js').TransferPart[]} */
28
- const xfer = harden(
29
- inBrand === getSecondaryBrand(pool)
30
- ? [
31
- fromOnly(poolSeat, { Central: prices.yDecrement }),
32
- toOnly(poolSeat, { Secondary: prices.xIncrement }),
33
- ]
34
- : [
35
- fromOnly(poolSeat, { Secondary: prices.yDecrement }),
36
- toOnly(poolSeat, { Central: prices.xIncrement }),
37
- ],
38
- );
39
-
40
- atomicRearrange(
41
- zcf,
42
- harden([
43
- fromOnly(seat, { In: prices.swapperGives }),
44
-
45
- toOnly(seat, { Out: prices.swapperGets }),
46
- toOnly(protocolSeat, { Fee: prices.protocolFee }),
47
-
48
- ...xfer,
49
- ]),
50
- );
51
- seat.exit();
52
- pool.updateState();
53
- return `Swap successfully completed.`;
54
- },
55
-
56
- /**
57
- * @param {import('./pool').MethodContext} context
58
- * @param {Amount} amountIn
59
- * @param {Amount} amountOut
60
- */
61
- getPriceForInput: ({ facets }, amountIn, amountOut) => {
62
- const { params } = ammPowers;
63
- return pricesForStatedInput(
64
- amountIn,
65
- getPools(facets.pool),
66
- amountOut,
67
- makeFeeRatio(params.getProtocolFee(), getCentralBrand(facets.pool)),
68
- makeFeeRatio(params.getPoolFee(), amountOut.brand),
69
- );
70
- },
71
-
72
- /**
73
- * @param {import('./pool').MethodContext} context
74
- * @param {Amount} amountIn
75
- * @param {Amount} amountOut
76
- */
77
- getPriceForOutput: ({ facets }, amountIn, amountOut) => {
78
- const { params } = ammPowers;
79
- return pricesForStatedOutput(
80
- amountIn,
81
- getPools(facets.pool),
82
- amountOut,
83
- makeFeeRatio(params.getProtocolFee(), getCentralBrand(facets.pool)),
84
- makeFeeRatio(params.getPoolFee(), amountIn.brand),
85
- );
86
- },
87
- });
88
- harden(makeSinglePool);
@@ -1,68 +0,0 @@
1
- import { assertProposalShape } from '@agoric/zoe/src/contractSupport/index.js';
2
-
3
- import '@agoric/zoe/exported.js';
4
- import { AmountMath } from '@agoric/ertp';
5
-
6
- /**
7
- * @param {ZCF} zcf
8
- * @param {(brandIn: Brand, brandOut: Brand) => VirtualPool} provideVPool
9
- */
10
- export const makeMakeSwapInvitation = (zcf, provideVPool) => {
11
- /**
12
- * trade with a stated amountIn.
13
- *
14
- * @param {ZCFSeat} seat
15
- * @param {{ stopAfter: Amount }} args
16
- */
17
- const swapIn = (seat, args) => {
18
- assertProposalShape(seat, {
19
- give: { In: null },
20
- want: { Out: null },
21
- });
22
- const {
23
- give: { In: amountIn },
24
- want: { Out: amountOut },
25
- } = seat.getProposal();
26
- if (args) {
27
- AmountMath.coerce(amountOut.brand, args.stopAfter);
28
- // TODO check that there are no other keys
29
- }
30
-
31
- const pool = provideVPool(amountIn.brand, amountOut.brand);
32
- let prices;
33
- const stopAfter = args && args.stopAfter;
34
- if (stopAfter) {
35
- AmountMath.coerce(amountOut.brand, stopAfter);
36
- prices = pool.getPriceForOutput(amountIn, stopAfter);
37
- }
38
- if (!prices || !AmountMath.isGTE(prices.swapperGets, stopAfter)) {
39
- // `amountIn` is not enough to sell for stopAfter so just sell it all
40
- prices = pool.getPriceForInput(amountIn, amountOut);
41
- }
42
- assert(amountIn.brand === prices.swapperGives.brand);
43
- return pool.allocateGainsAndLosses(seat, prices);
44
- };
45
-
46
- // trade with a stated amount out.
47
- const swapOut = seat => {
48
- assertProposalShape(seat, {
49
- give: { In: null },
50
- want: { Out: null },
51
- });
52
- const {
53
- give: { In: amountIn },
54
- want: { Out: amountOut },
55
- } = seat.getProposal();
56
- const pool = provideVPool(amountIn.brand, amountOut.brand);
57
- const prices = pool.getPriceForOutput(amountIn, amountOut);
58
- return pool.allocateGainsAndLosses(seat, prices);
59
- };
60
-
61
- const makeSwapInInvitation = () =>
62
- zcf.makeInvitation(swapIn, 'autoswap swapIn');
63
-
64
- const makeSwapOutInvitation = () =>
65
- zcf.makeInvitation(swapOut, 'autoswap swapOut');
66
-
67
- return { makeSwapInInvitation, makeSwapOutInvitation };
68
- };