@agoric/inter-protocol 0.13.2-dev-70ba9b0.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 (70) 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 +188 -188
  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-stakeFactory-meta.js +118 -118
  13. package/bundles/bundle-stakeFactory.js +1 -1
  14. package/bundles/bundle-vaultFactory-meta.js +130 -130
  15. package/bundles/bundle-vaultFactory.js +1 -1
  16. package/exported.js +0 -1
  17. package/package.json +16 -16
  18. package/scripts/deploy-contracts.js +0 -2
  19. package/scripts/init-core.js +0 -16
  20. package/src/feeDistributor.js +1 -1
  21. package/src/proposals/addAssetToVault.js +4 -57
  22. package/src/proposals/committee-proposal.js +3 -6
  23. package/src/proposals/core-proposal.js +1 -73
  24. package/src/proposals/demoIssuers.js +1 -232
  25. package/src/proposals/econ-behaviors.js +10 -193
  26. package/src/proposals/sim-behaviors.js +1 -1
  27. package/src/reserve/assetReserve.js +9 -170
  28. package/src/reserve/params.js +1 -4
  29. package/src/vaultFactory/liquidateIncrementally.js +16 -141
  30. package/src/vaultFactory/liquidateMinimum.js +19 -21
  31. package/src/vaultFactory/params.js +0 -29
  32. package/src/vaultFactory/types.js +0 -6
  33. package/src/vaultFactory/vault.js +1 -3
  34. package/src/vaultFactory/vaultDirector.js +1 -33
  35. package/src/vaultFactory/vaultFactory.js +2 -12
  36. package/src/vaultFactory/vaultManager.js +10 -217
  37. package/bundles/bundle-amm-meta.js +0 -686
  38. package/bundles/bundle-amm.js +0 -1
  39. package/bundles/bundle-interchainPool-meta.js +0 -606
  40. package/bundles/bundle-interchainPool.js +0 -1
  41. package/bundles/bundle-liquidateIncrementally-meta.js +0 -470
  42. package/bundles/bundle-liquidateIncrementally.js +0 -1
  43. package/bundles/bundle-liquidateMinimum-meta.js +0 -470
  44. package/bundles/bundle-liquidateMinimum.js +0 -1
  45. package/scripts/add-initial-liquidity.js +0 -179
  46. package/src/interchainPool.js +0 -134
  47. package/src/vpool-xyk-amm/AttackersGuide.md +0 -89
  48. package/src/vpool-xyk-amm/addLiquidity.js +0 -221
  49. package/src/vpool-xyk-amm/addPool.js +0 -200
  50. package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
  51. package/src/vpool-xyk-amm/constantProduct/README.md +0 -204
  52. package/src/vpool-xyk-amm/constantProduct/calcFees.js +0 -93
  53. package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +0 -83
  54. package/src/vpool-xyk-amm/constantProduct/core.js +0 -145
  55. package/src/vpool-xyk-amm/constantProduct/defaults.js +0 -3
  56. package/src/vpool-xyk-amm/constantProduct/getXY.js +0 -48
  57. package/src/vpool-xyk-amm/constantProduct/internal-types.js +0 -114
  58. package/src/vpool-xyk-amm/constantProduct/invariants.js +0 -39
  59. package/src/vpool-xyk-amm/constantProduct/swap.js +0 -270
  60. package/src/vpool-xyk-amm/constantProduct/types.js +0 -30
  61. package/src/vpool-xyk-amm/doublePool.js +0 -200
  62. package/src/vpool-xyk-amm/estimate.js +0 -175
  63. package/src/vpool-xyk-amm/multipoolMarketMaker.js +0 -530
  64. package/src/vpool-xyk-amm/params.js +0 -59
  65. package/src/vpool-xyk-amm/pool.js +0 -398
  66. package/src/vpool-xyk-amm/priceAuthority.js +0 -92
  67. package/src/vpool-xyk-amm/removeLiquidity.js +0 -29
  68. package/src/vpool-xyk-amm/singlePool.js +0 -88
  69. package/src/vpool-xyk-amm/swap.js +0 -68
  70. package/src/vpool-xyk-amm/types.js +0 -152
@@ -1,145 +0,0 @@
1
- import { AmountMath } from '@agoric/ertp';
2
-
3
- import { natSafeMath } from '@agoric/zoe/src/contractSupport/index.js';
4
- import { makeRatioFromAmounts } from '@agoric/zoe/src/contractSupport/ratio.js';
5
- import { getXY } from './getXY.js';
6
-
7
- const { Fail } = assert;
8
-
9
- const assertSingleBrand = ratio => {
10
- ratio.numerator.brand === ratio.denominator.brand ||
11
- Fail`Ratio was expected to have same brand in numerator ${ratio.numerator.brand} and denominator ${ratio.denominator.brand}`;
12
- };
13
-
14
- /**
15
- * Multiply an amount by a ratio using floorDivide, ignoring the ratio's brands
16
- * in favor of the amount brand. This is necessary because the ratio is produced
17
- * by dividing assets of the opposite brand.
18
- *
19
- * @param {Amount<'nat'>} amount
20
- * @param {Ratio} ratio
21
- * @returns {Amount<'nat'>}
22
- */
23
- const floorMultiplyKeepBrand = (amount, ratio) => {
24
- assertSingleBrand(ratio);
25
- const value = natSafeMath.floorDivide(
26
- natSafeMath.multiply(amount.value, ratio.numerator.value),
27
- ratio.denominator.value,
28
- );
29
- return AmountMath.make(amount.brand, value);
30
- };
31
-
32
- /**
33
- * Multiply an amount and a ratio using ceilDivide, ignoring the ratio's brands
34
- * in favor of the amount brand. This is necessary because the ratio is produced
35
- * by dividing assets of the opposite brand.
36
- *
37
- * @param {Amount<'nat'>} amount
38
- * @param {Ratio} ratio
39
- * @returns {Amount<'nat'>}
40
- */
41
- const ceilMultiplyKeepBrand = (amount, ratio) => {
42
- assertSingleBrand(ratio);
43
- const value = natSafeMath.ceilDivide(
44
- natSafeMath.multiply(amount.value, ratio.numerator.value),
45
- ratio.denominator.value,
46
- );
47
- return AmountMath.make(amount.brand, value);
48
- };
49
-
50
- /**
51
- * Calculate deltaY when the user is selling brand X. That is, whichever asset
52
- * the user is selling, this function is used to calculate the change in the
53
- * other asset, i.e. how much of brand Y to give the user in return.
54
- * swapOutImproved calls this function with the calculated amountIn to find out
55
- * if more than the wantedAmountOut can be gained for the necessary amountIn.
56
- *
57
- * deltaY = (deltaXOverX/(1 + deltaXOverX))*y
58
- * Equivalently: (deltaX / (deltaX + x)) * y
59
- *
60
- * @param {Amount<'nat'>} x - the amount of Brand X in pool
61
- * @param {Amount<'nat'>} y - the amount of Brand Y the pool
62
- * @param {Amount<'nat'>} deltaX - the amount of Brand X to be added
63
- * @returns {Amount<'nat'>} deltaY - the amount of Brand Y to be taken out
64
- */
65
- export const calcDeltaYSellingX = (x, y, deltaX) => {
66
- const deltaXPlusX = AmountMath.add(deltaX, x);
67
- const xRatio = makeRatioFromAmounts(deltaX, deltaXPlusX);
68
- // We want to err on the side of the pool, so this will use floorDivide to
69
- // round down the amount paid out.
70
- return floorMultiplyKeepBrand(y, xRatio);
71
- };
72
-
73
- /**
74
- * Calculate deltaX when the user is selling brand X. That is, whichever asset
75
- * the user is selling, this function is used to calculate the change to the
76
- * pool for that asset. swapInReduced calls this with the calculated amountOut
77
- * to find out if less than the offeredAmountIn would be sufficient.
78
- *
79
- * deltaX = (deltaYOverY/(1 - deltaYOverY))*x
80
- * Equivalently: (deltaY / (Y - deltaY )) * x
81
- *
82
- * @param {Amount<'nat'>} x - the amount of Brand X in the pool
83
- * @param {Amount<'nat'>} y - the amount of Brand Y in the pool
84
- * @param {Amount<'nat'>} deltaY - the amount of Brand Y to be taken out
85
- * @returns {Amount<'nat'>} deltaX - the amount of Brand X to be added
86
- */
87
- export const calcDeltaXSellingX = (x, y, deltaY) => {
88
- const yMinusDeltaY = AmountMath.subtract(y, deltaY);
89
- const yRatio = makeRatioFromAmounts(deltaY, yMinusDeltaY);
90
- // We want to err on the side of the pool, so this will use ceilMultiply to
91
- // round up the amount required.
92
- return ceilMultiplyKeepBrand(x, yRatio);
93
- };
94
-
95
- /**
96
- * The input contains the amounts in the pool and a maximum amount offered.
97
- * Calculate the most beneficial trade that satisfies the constant product
98
- * invariant.
99
- *
100
- * @param {GetXYResultDeltaX} obj
101
- * @returns {ImprovedNoFeeSwapResult}
102
- */
103
- const swapInReduced = ({ x, y, deltaX: offeredAmountIn }) => {
104
- const amountOut = calcDeltaYSellingX(x, y, offeredAmountIn);
105
- const reducedAmountIn = calcDeltaXSellingX(x, y, amountOut);
106
- AmountMath.isGTE(offeredAmountIn, reducedAmountIn) ||
107
- Fail`The trade would have required ${reducedAmountIn} more than was offered ${offeredAmountIn}`;
108
-
109
- return harden({
110
- amountIn: reducedAmountIn,
111
- amountOut,
112
- });
113
- };
114
-
115
- /**
116
- * The input contains the amounts in the pool and the minimum amount requested.
117
- * Calculate the most beneficial trade that satisfies the constant product
118
- * invariant.
119
- *
120
- * @param {GetXYResultDeltaY} obj
121
- * @returns {ImprovedNoFeeSwapResult}
122
- */
123
- const swapOutImproved = ({ x, y, deltaY: wantedAmountOut }) => {
124
- const amountIn = calcDeltaXSellingX(x, y, wantedAmountOut);
125
- const improvedAmountOut = calcDeltaYSellingX(x, y, amountIn);
126
- AmountMath.isGTE(improvedAmountOut, wantedAmountOut) ||
127
- Fail`The trade would have returned ${improvedAmountOut} less than was wanted ${wantedAmountOut}`;
128
-
129
- return harden({
130
- amountIn,
131
- amountOut: improvedAmountOut,
132
- });
133
- };
134
-
135
- /** @type {NoFeeSwapFn} */
136
- export const swapInNoFees = ({ amountGiven, poolAllocation }) => {
137
- const XY = getXY({ amountGiven, poolAllocation });
138
- return swapInReduced(XY);
139
- };
140
-
141
- /** @type {NoFeeSwapFn} */
142
- export const swapOutNoFees = ({ poolAllocation, amountWanted }) => {
143
- const XY = getXY({ poolAllocation, amountWanted });
144
- return swapOutImproved(XY);
145
- };
@@ -1,3 +0,0 @@
1
- export const BASIS_POINTS = 10000n;
2
- export const DEFAULT_POOL_FEE = 24n; // 0.0024 or .24%
3
- export const DEFAULT_PROTOCOL_FEE = 6n; // .0006 or .06%
@@ -1,48 +0,0 @@
1
- // This does not support secondary to secondary. That has to happen at
2
- // a higher abstraction
3
-
4
- const { Fail } = assert;
5
- /**
6
- * The caller provides poolAllocation, which has balances for both Central and
7
- * Secondary, and at least one of amountGiven and amountWanted. getXY treats
8
- * the amountGiven as the X pool, and amountWanted as Y. It figures out which
9
- * way to pair up X and Y with Central and Secondary, and returns the pool
10
- * balances as X and Y and given and wanted as deltaX and deltaY
11
- * { X, Y, deltaX, deltaY }.
12
- *
13
- * @type {GetXY}
14
- */
15
- export const getXY = ({ amountGiven, poolAllocation, amountWanted }) => {
16
- // Regardless of whether we are specifying the amountIn or the
17
- // amountOut, the xBrand is the brand of the amountIn.
18
- const xBrand = amountGiven && amountGiven.brand;
19
- const yBrand = amountWanted && amountWanted.brand;
20
- const secondaryBrand = poolAllocation.Secondary.brand;
21
- const centralBrand = poolAllocation.Central.brand;
22
- amountGiven ||
23
- amountWanted ||
24
- Fail`At least one of ${amountGiven} and ${amountWanted} must be specified`;
25
-
26
- const deltas = {
27
- deltaX: amountGiven,
28
- deltaY: amountWanted,
29
- };
30
-
31
- if (secondaryBrand === xBrand || centralBrand === yBrand) {
32
- // @ts-expect-error at least one of amountGiven and amountWanted is non-null
33
- return harden({
34
- x: poolAllocation.Secondary,
35
- y: poolAllocation.Central,
36
- ...deltas,
37
- });
38
- }
39
- if (centralBrand === xBrand || secondaryBrand === yBrand) {
40
- // @ts-expect-error at least one of amountGiven and amountWanted is non-null
41
- return harden({
42
- x: poolAllocation.Central,
43
- y: poolAllocation.Secondary,
44
- ...deltas,
45
- });
46
- }
47
- assert.fail(`brand ${xBrand} was not recognized as Central or Secondary`);
48
- };
@@ -1,114 +0,0 @@
1
- /**
2
- * @typedef {object} ImprovedNoFeeSwapResult
3
- * @property {Amount<'nat'>} amountIn
4
- * @property {Amount<'nat'>} amountOut
5
- */
6
-
7
- /**
8
- * @typedef {object} FeePair
9
- *
10
- * @property {Amount<'nat'>} poolFee
11
- * @property {Amount<'nat'>} protocolFee
12
- */
13
-
14
- /**
15
- * @typedef {object} PoolAllocation
16
- *
17
- * @property {Amount<'nat'>} Central
18
- * @property {Amount<'nat'>} Secondary
19
- */
20
-
21
- /**
22
- * @typedef {object} NoFeeSwapFnInput
23
- * @property {Amount} amountGiven
24
- * @property {Amount} amountWanted
25
- * @property {Brand} [brand]
26
- * @property {PoolAllocation} poolAllocation
27
- */
28
-
29
- /**
30
- * This is the type for swapInNoFees and swapOutNoFees. pricesForStatedInput()
31
- * uses swapInNoFees, while pricesForStatedOutput() uses swapOutNoFees.
32
- *
33
- * @callback NoFeeSwapFn
34
- * @param {NoFeeSwapFnInput} input
35
- * @returns {ImprovedNoFeeSwapResult}
36
- */
37
-
38
- /**
39
- * @typedef {FeePair & ImprovedNoFeeSwapResult} FeeEstimate
40
- */
41
-
42
- /**
43
- * @callback CalculateFees
44
- * @param {Amount<'nat'>} amountGiven
45
- * @param {PoolAllocation} poolAllocation
46
- * @param {Amount<'nat'>} amountWanted
47
- * @param {Ratio} protocolFeeRatio
48
- * @param {Ratio} poolFeeRatio
49
- * @param {NoFeeSwapFn} swapFn
50
- * @returns {FeeEstimate}
51
- */
52
-
53
- /**
54
- * @callback InternalSwap
55
- * @param {Amount<'nat'>} amountGiven
56
- * @param {PoolAllocation} poolAllocation
57
- * @param {Amount<'nat'>} amountWanted
58
- * @param {Ratio} protocolFeeRatio
59
- * @param {Ratio} poolFeeRatio
60
- * @param {NoFeeSwapFn} swapFn
61
- * @returns {SinglePoolSwapResult}
62
- */
63
-
64
- /**
65
- * @callback CalcSwapInPrices
66
- * @param {Amount} amountGiven
67
- * @param {PoolAllocation} poolAllocation
68
- * @param {Amount} [amountWanted]
69
- * @param {Ratio} protocolFeeRatio
70
- * @param {Ratio} poolFeeRatio
71
- * @returns {SinglePoolSwapResult}
72
- */
73
- /**
74
- * @callback CalcSwapOutPrices
75
- * @param {Amount} [amountGiven]
76
- * @param {PoolAllocation} poolAllocation
77
- * @param {Amount} amountWanted
78
- * @param {Ratio} protocolFeeRatio
79
- * @param {Ratio} poolFeeRatio
80
- * @returns {SinglePoolSwapResult}
81
- */
82
-
83
- /**
84
- * @typedef {object} GetXYParam
85
- * @property {Amount} [amountGiven]
86
- * @property {PoolAllocation} poolAllocation
87
- * @property {Amount} [amountWanted]
88
- */
89
-
90
- /**
91
- * @typedef {object} GetXYResultDeltaX
92
- * @property {Amount<'nat'>} x
93
- * @property {Amount<'nat'>} y
94
- * @property {Amount<'nat'>} deltaX
95
- * @property {Amount<'nat'>|undefined} deltaY
96
- */
97
-
98
- /**
99
- * @typedef {object} GetXYResultDeltaY
100
- * @property {Amount<'nat'>} x
101
- * @property {Amount<'nat'>} y
102
- * @property {Amount<'nat'>} deltaY
103
- * @property {Amount<'nat'>|undefined} deltaX
104
- */
105
-
106
- /**
107
- * @typedef {GetXYResultDeltaX & GetXYResultDeltaY} GetXYResult
108
- */
109
-
110
- /**
111
- * @callback GetXY
112
- * @param {GetXYParam} obj
113
- * @returns {GetXYResult}
114
- */
@@ -1,39 +0,0 @@
1
- import { Fail } from '@agoric/assert';
2
- import { AmountMath } from '@agoric/ertp';
3
-
4
- import { natSafeMath } from '@agoric/zoe/src/contractSupport/index.js';
5
-
6
- /**
7
- * xy <= (x + deltaX)(y - deltaY)
8
- *
9
- * @param {Amount<'nat'>} x - the amount of Brand X in pool, xPoolAllocation
10
- * @param {Amount<'nat'>} y - the amount of Brand Y in pool, yPoolAllocation
11
- * @param {Amount<'nat'>} deltaX - the amount of Brand X to be added
12
- * @param {Amount<'nat'>} deltaY - the amount of Brand Y to be taken out
13
- */
14
- export const checkKInvariantSellingX = (x, y, deltaX, deltaY) => {
15
- const oldK = natSafeMath.multiply(x.value, y.value);
16
- const newX = AmountMath.add(x, deltaX);
17
- const newY = AmountMath.subtract(y, deltaY);
18
- const newK = natSafeMath.multiply(newX.value, newY.value);
19
- return oldK <= newK;
20
- };
21
-
22
- /**
23
- * xy <= (x + deltaX)(y - deltaY)
24
- *
25
- * @param {Amount<'nat'>} x - the amount of Brand X in pool, xPoolAllocation
26
- * @param {Amount<'nat'>} y - the amount of Brand Y in pool, yPoolAllocation
27
- * @param {Amount<'nat'>} deltaX - the amount of Brand X to be added
28
- * @param {Amount<'nat'>} deltaY - the amount of Brand Y to be taken out
29
- */
30
- export const assertKInvariantSellingX = (x, y, deltaX, deltaY) => {
31
- checkKInvariantSellingX(x, y, deltaX, deltaY) ||
32
- Fail`the constant product invariant was violated, with x=${x}, y=${y}, deltaX=${deltaX}, deltaY=${deltaY}, oldK=${natSafeMath.multiply(
33
- x.value,
34
- y.value,
35
- )}, newK=${natSafeMath.multiply(
36
- AmountMath.add(x, deltaX).value,
37
- AmountMath.subtract(y, deltaY).value,
38
- )}`;
39
- };
@@ -1,270 +0,0 @@
1
- import { AmountMath } from '@agoric/ertp';
2
- import { calculateFees, amountGT } from './calcFees.js';
3
-
4
- const { Fail } = assert;
5
-
6
- /**
7
- * The fee might not be in the same brand as the amount. If they are the same,
8
- * subtract the fee from the amount. Otherwise return the unadjusted amount.
9
- *
10
- * We return empty if the fee is larger because an empty amount indicates that
11
- * the trader didn't place a limit on the inputAmount.
12
- *
13
- * @param {Amount<'nat'>} amount
14
- * @param {Amount<'nat'>} fee
15
- * @returns {Amount<'nat'>}
16
- */
17
- const subtractRelevantFees = (amount, fee) => {
18
- if (amount.brand === fee.brand) {
19
- if (AmountMath.isGTE(fee, amount)) {
20
- return AmountMath.makeEmptyFromAmount(amount);
21
- }
22
-
23
- return AmountMath.subtract(amount, fee);
24
- }
25
- return amount;
26
- };
27
-
28
- /**
29
- * PoolFee and ProtocolFee each identify their brand. If either (or both) match
30
- * the brand of the Amount, subtract it/them from the amount.
31
- *
32
- * @param {Amount<'nat'>} amount
33
- * @param {FeePair} fee
34
- * @returns {Amount<'nat'>}
35
- */
36
- const subtractFees = (amount, { poolFee, protocolFee }) => {
37
- return subtractRelevantFees(
38
- subtractRelevantFees(amount, protocolFee),
39
- poolFee,
40
- );
41
- };
42
-
43
- /**
44
- * The fee might not be in the same brand as the amount. If they are the same,
45
- * add the fee to the amount. Otherwise return the unadjusted amount.
46
- *
47
- * @param {Amount<'nat'>} amount
48
- * @param {Amount<'nat'>} fee
49
- * @returns {Amount<'nat'>}
50
- */
51
- const addRelevantFees = (amount, fee) => {
52
- if (amount.brand === fee.brand) {
53
- return AmountMath.add(amount, fee);
54
- }
55
- return amount;
56
- };
57
-
58
- /**
59
- * PoolFee and ProtocolFee each identify their brand. If either (or both) match
60
- * the brand of the Amount, add it/them to the amount.
61
- *
62
- * @param {Amount<'nat'>} amount
63
- * @param {FeePair} fee
64
- * @returns {Amount<'nat'>}
65
- */
66
- const addFees = (amount, { poolFee, protocolFee }) => {
67
- return addRelevantFees(addRelevantFees(amount, protocolFee), poolFee);
68
- };
69
-
70
- /**
71
- * Increment or decrement a pool balance by an amount. The amount's brand might
72
- * match the Central or Secondary balance of the pool. Return the adjusted
73
- * balance. The caller knows which amount they provided, so they're expecting a
74
- * single Amount whose brand matches the amount parameter.
75
- *
76
- * The first parameter specifies whether we're incrementing or decrementing from the pool
77
- *
78
- * @param {(amountLeft: Amount<any>, amountRight: Amount<any>, brand?: Brand) => Amount<any>} addOrSub
79
- * @param {PoolAllocation} poolAllocation
80
- * @param {Amount<'nat'>} amount
81
- * @returns {Amount<'nat'>}
82
- */
83
- const addOrSubtractFromPool = (addOrSub, poolAllocation, amount) => {
84
- if (poolAllocation.Central.brand === amount.brand) {
85
- return addOrSub(poolAllocation.Central, amount);
86
- } else {
87
- return addOrSub(poolAllocation.Secondary, amount);
88
- }
89
- };
90
-
91
- const isGreaterThanZero = amount => {
92
- return amount && amountGT(amount, AmountMath.makeEmptyFromAmount(amount));
93
- };
94
-
95
- const assertGreaterThanZero = (amount, name) => {
96
- (amount && isGreaterThanZero(amount)) ||
97
- Fail`${name} must be greater than 0: ${amount}`;
98
- };
99
-
100
- const isWantedAvailable = (poolAllocation, amountWanted) => {
101
- // The question is about a poolAllocation. If it has exactly amountWanted,
102
- // that's not sufficient, since it would leave the pool empty.
103
- return amountWanted.brand === poolAllocation.Central.brand
104
- ? !AmountMath.isGTE(amountWanted, poolAllocation.Central)
105
- : !AmountMath.isGTE(amountWanted, poolAllocation.Secondary);
106
- };
107
-
108
- /**
109
- * We've identified a violation of constraints that means we won't be able to
110
- * satisfy the user's request. (Not enough funds in the pool, too much was
111
- * requested, the proceeds would be empty, etc.) Return a result that says no
112
- * trade will take place and the pool balances won't change.
113
- *
114
- * @param {Amount<'nat'>} amountGiven
115
- * @param {Amount<'nat'>} amountWanted
116
- * @param {PoolAllocation} poolAllocation
117
- * @param {Ratio} poolFee
118
- */
119
- const makeNoTransaction = (
120
- amountGiven,
121
- amountWanted,
122
- poolAllocation,
123
- poolFee,
124
- ) => {
125
- const emptyGive = AmountMath.makeEmptyFromAmount(amountGiven);
126
- const emptyWant = AmountMath.makeEmptyFromAmount(amountWanted);
127
-
128
- let newX;
129
- let newY;
130
- if (poolAllocation.Central.brand === amountGiven.brand) {
131
- newX = poolAllocation.Central;
132
- newY = poolAllocation.Secondary;
133
- } else {
134
- newX = poolAllocation.Secondary;
135
- newY = poolAllocation.Central;
136
- }
137
-
138
- const result = harden({
139
- protocolFee: AmountMath.makeEmpty(poolAllocation.Central.brand),
140
- poolFee: AmountMath.makeEmpty(poolFee.numerator.brand),
141
- swapperGives: emptyGive,
142
- swapperGets: emptyWant,
143
- xIncrement: emptyGive,
144
- yDecrement: emptyWant,
145
- newX,
146
- newY,
147
- });
148
- return result;
149
- };
150
-
151
- /**
152
- * This is the heart of the calculation. See README.md for the long explanation.
153
- * calculate how much should be added to and removed from the pool, the fees,
154
- * and what the user will pay and receive.
155
- *
156
- * As soon as we detect that we won't be able to satisfy the request, we return
157
- * noTransaction, indicating that no trade should take place. This can be due to
158
- * a request for more assets than the pool holds, a specified price the current
159
- * assets won't support, or the trade would require more than the trader allowed,
160
- * or provide less, or fees would eat up all the trader's proceeds.
161
- *
162
- * We start by calculating the amounts that would be traded if no fees were
163
- * charged. The actual fees are based on these amounts. Once we know the actual
164
- * fees, we calculate the deltaX and deltaY that will best maintain the
165
- * constant product invariant.
166
- *
167
- * The amounts by which the pool will be adjusted, that the trader will pay and
168
- * receive, and the fees are then computed based on deltaX and deltaY.
169
- *
170
- * @type {InternalSwap}
171
- */
172
- export const swap = (
173
- amountGiven,
174
- poolAllocation,
175
- amountWanted,
176
- protocolFeeRatio,
177
- poolFeeRatio,
178
- swapFn,
179
- ) => {
180
- const noTransaction = makeNoTransaction(
181
- amountGiven,
182
- amountWanted,
183
- poolAllocation,
184
- poolFeeRatio,
185
- );
186
- assertGreaterThanZero(poolAllocation.Central, 'poolAllocation.Central');
187
- assertGreaterThanZero(poolAllocation.Secondary, 'poolAllocation.Secondary');
188
-
189
- if (!isGreaterThanZero(amountGiven) && !isGreaterThanZero(amountWanted)) {
190
- return noTransaction;
191
- }
192
-
193
- if (!isWantedAvailable(poolAllocation, amountWanted)) {
194
- return noTransaction;
195
- }
196
-
197
- // The protocol fee must always be collected in `Fee`, but the pool
198
- // fee is collected in the amount opposite of what is specified.
199
- // This call gives us improved amountIn or amountOut
200
- const fees = calculateFees(
201
- amountGiven,
202
- poolAllocation,
203
- amountWanted,
204
- protocolFeeRatio,
205
- poolFeeRatio,
206
- swapFn,
207
- );
208
-
209
- if (!isWantedAvailable(poolAllocation, addFees(amountWanted, fees))) {
210
- return noTransaction;
211
- }
212
-
213
- // Calculate no-fee amounts. swapFn will only pay attention to the `specified`
214
- // value. The pool fee is always charged on the unspecified side, so it is an
215
- // output of the calculation. When the specified value is in `Fee`, the protocol fee will
216
- // be deducted from amountGiven before adding to the pool or added to
217
- // amountWanted to calculate amountOut. Otherwise we add the protocol fee
218
- // to amountWanted.
219
- const { amountIn, amountOut } = swapFn({
220
- amountGiven: subtractFees(amountGiven, fees),
221
- poolAllocation,
222
- amountWanted: addFees(amountWanted, fees),
223
- });
224
-
225
- if (AmountMath.isEmpty(amountOut)) {
226
- return noTransaction;
227
- }
228
-
229
- // The swapper pays extra or receives less to cover the fees.
230
- const swapperGives = addFees(amountIn, fees);
231
- const swapperGets = subtractFees(amountOut, fees);
232
-
233
- // return noTransaction if fees would eat up all the trader's proceeds,
234
- // the trader specified an amountGiven, and the trade would require more, or
235
- // the trade would require them to give more than they specified.
236
- if (
237
- AmountMath.isEmpty(swapperGets) ||
238
- (!AmountMath.isEmpty(amountGiven) && amountGT(swapperGives, amountGiven)) ||
239
- amountGT(amountWanted, swapperGets)
240
- ) {
241
- return noTransaction;
242
- }
243
-
244
- const xIncrement = addRelevantFees(amountIn, fees.poolFee);
245
- const yDecrement = subtractRelevantFees(amountOut, fees.poolFee);
246
-
247
- // poolFee is the amount the pool will grow over the no-fee calculation.
248
- // protocolFee is to be separated and sent to an external purse.
249
- // The swapper amounts are what will be paid and received.
250
- // xIncrement and yDecrement are what will be added and removed from the pools.
251
- // Either xIncrement will be increased by the pool fee or yDecrement will be
252
- // reduced by it in order to compensate the pool.
253
- // newX and newY are the new pool balances, for comparison with start values.
254
- const result = harden({
255
- protocolFee: fees.protocolFee,
256
- poolFee: fees.poolFee,
257
- swapperGives,
258
- swapperGets,
259
- xIncrement,
260
- yDecrement,
261
- newX: addOrSubtractFromPool(AmountMath.add, poolAllocation, xIncrement),
262
- newY: addOrSubtractFromPool(
263
- AmountMath.subtract,
264
- poolAllocation,
265
- yDecrement,
266
- ),
267
- });
268
-
269
- return result;
270
- };
@@ -1,30 +0,0 @@
1
- /**
2
- * @callback Maximum
3
- * @param {Amount} left
4
- * @param {Amount} right
5
- * @returns {Amount}
6
- */
7
-
8
- /**
9
- * A bigint representing a number that will be divided by 10,0000. Financial
10
- * ratios are often represented in basis points.
11
- *
12
- * @typedef {bigint} BASIS_POINTS
13
- */
14
-
15
- /**
16
- * Make a Ratio representing a fee expressed in Basis Points. (hundredths of a
17
- * percent)
18
- *
19
- * @callback MakeFeeRatio
20
- * @param {BASIS_POINTS} feeBP
21
- * @param {Brand} brandOfFee
22
- * @returns {Ratio}
23
- */
24
-
25
- /**
26
- * @callback AmountGT
27
- * @param {Amount} left
28
- * @param {Amount} right
29
- * @returns {boolean}
30
- */