@agoric/inter-protocol 0.13.3 → 0.13.4-dev-800c2bb.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -20
- package/bundles/bundle-auctioneer-js-meta.json +722 -0
- package/bundles/bundle-auctioneer.js +1 -0
- package/bundles/bundle-econCommitteeCharter-js-meta.json +514 -0
- package/bundles/bundle-econCommitteeCharter.js +1 -0
- package/bundles/bundle-feeDistributor-js-meta.json +458 -0
- package/bundles/bundle-feeDistributor.js +1 -1
- package/bundles/bundle-fluxAggregatorKit-js-meta.json +674 -0
- package/bundles/bundle-fluxAggregatorKit.js +1 -0
- package/bundles/bundle-psm-js-meta.json +666 -0
- package/bundles/bundle-psm.js +1 -1
- package/bundles/bundle-reserve-js-meta.json +662 -0
- package/bundles/bundle-reserve.js +1 -1
- package/bundles/bundle-scaledPriceAuthority-js-meta.json +542 -0
- package/bundles/bundle-scaledPriceAuthority.js +1 -1
- package/bundles/bundle-vaultFactory-js-meta.json +786 -0
- package/bundles/bundle-vaultFactory.js +1 -1
- package/exported.js +0 -2
- package/package.json +34 -31
- package/scripts/add-collateral-core.js +14 -4
- package/scripts/build-bundles.js +9 -2
- package/scripts/deploy-contracts.js +1 -4
- package/scripts/init-core.js +20 -38
- package/scripts/invite-committee-core.js +1 -1
- package/scripts/manual-price-feed.js +2 -2
- package/scripts/price-feed-core.js +7 -6
- package/scripts/start-local-chain.sh +84 -0
- package/src/auction/auctionBook.js +755 -0
- package/src/auction/auctioneer.js +720 -0
- package/src/auction/offerBook.js +221 -0
- package/src/auction/params.js +174 -0
- package/src/auction/scheduleMath.js +167 -0
- package/src/auction/scheduler.js +370 -0
- package/src/auction/sortedOffers.js +136 -0
- package/src/auction/util.js +55 -0
- package/src/clientSupport.js +324 -0
- package/src/collectFees.js +8 -14
- package/src/contractSupport.js +24 -68
- package/src/econCommitteeCharter.js +161 -77
- package/src/feeDistributor.js +60 -20
- package/src/index.js +2 -0
- package/src/interest-math.js +1 -4
- package/src/interest.js +20 -13
- package/src/price/README.md +57 -0
- package/src/price/fluxAggregatorContract.js +190 -0
- package/src/price/fluxAggregatorKit.js +375 -0
- package/src/price/priceOracleKit.js +127 -0
- package/src/price/roundsManager.js +726 -0
- package/src/proposals/addAssetToVault.js +89 -94
- package/src/proposals/committee-proposal.js +141 -40
- package/src/proposals/core-proposal.js +100 -167
- package/src/proposals/econ-behaviors.js +320 -564
- package/src/proposals/price-feed-proposal.js +175 -78
- package/src/proposals/startEconCommittee.js +25 -12
- package/src/proposals/startPSM.js +231 -211
- package/src/proposals/utils.js +31 -17
- package/src/psm/README.md +71 -0
- package/src/psm/psm.js +272 -160
- package/src/psm/types.js +2 -0
- package/src/reserve/assetReserve.js +56 -413
- package/src/reserve/assetReserveKit.js +303 -0
- package/src/reserve/doc.md +1 -3
- package/src/reserve/params.js +2 -5
- package/src/typeGuards.js +13 -0
- package/src/vaultFactory/Liquidation.md +100 -0
- package/src/vaultFactory/burn.js +2 -1
- package/src/vaultFactory/liquidation.js +270 -108
- package/src/vaultFactory/math.js +95 -0
- package/src/vaultFactory/orderedVaultStore.js +0 -1
- package/src/vaultFactory/params.js +133 -112
- package/src/vaultFactory/prioritizedVaults.js +36 -79
- package/src/vaultFactory/storeUtils.js +67 -9
- package/src/vaultFactory/type-imports.js +2 -0
- package/src/vaultFactory/types.js +22 -26
- package/src/vaultFactory/vault.js +772 -709
- package/src/vaultFactory/vaultDirector.js +480 -483
- package/src/vaultFactory/vaultFactory.js +99 -60
- package/src/vaultFactory/vaultHolder.js +121 -95
- package/src/vaultFactory/vaultKit.js +39 -31
- package/src/vaultFactory/vaultManager.js +1249 -868
- package/bundles/bundle-amm-meta.js +0 -618
- package/bundles/bundle-amm.js +0 -1
- package/bundles/bundle-feeDistributor-meta.js +0 -346
- package/bundles/bundle-interchainPool-meta.js +0 -534
- package/bundles/bundle-interchainPool.js +0 -1
- package/bundles/bundle-liquidateIncrementally-meta.js +0 -442
- package/bundles/bundle-liquidateIncrementally.js +0 -1
- package/bundles/bundle-liquidateMinimum-meta.js +0 -442
- package/bundles/bundle-liquidateMinimum.js +0 -1
- package/bundles/bundle-psm-meta.js +0 -538
- package/bundles/bundle-psmCharter-meta.js +0 -418
- package/bundles/bundle-psmCharter.js +0 -1
- package/bundles/bundle-reserve-meta.js +0 -542
- package/bundles/bundle-scaledPriceAuthority-meta.js +0 -442
- package/bundles/bundle-stakeFactory-meta.js +0 -574
- package/bundles/bundle-stakeFactory.js +0 -1
- package/bundles/bundle-vaultFactory-meta.js +0 -598
- package/scripts/add-initial-liquidity.js +0 -180
- package/src/collect.js +0 -13
- package/src/interchainPool.js +0 -135
- package/src/makeTracer.js +0 -36
- package/src/my-lien.js +0 -85
- package/src/proposals/demoIssuers.js +0 -685
- package/src/proposals/sim-behaviors.js +0 -40
- package/src/psm/psmCharter.js +0 -139
- package/src/stakeFactory/README.md +0 -62
- package/src/stakeFactory/attestation.js +0 -267
- package/src/stakeFactory/attestationTool.js +0 -66
- package/src/stakeFactory/constants.js +0 -16
- package/src/stakeFactory/params.js +0 -31
- package/src/stakeFactory/stakeFactory.js +0 -236
- package/src/stakeFactory/stakeFactoryKit.js +0 -455
- package/src/stakeFactory/stakeFactoryManager.js +0 -296
- package/src/stakeFactory/types.js +0 -42
- package/src/vaultFactory/liquidateIncrementally.js +0 -350
- package/src/vaultFactory/liquidateMinimum.js +0 -100
- package/src/vpool-xyk-amm/AttackersGuide.md +0 -89
- package/src/vpool-xyk-amm/addLiquidity.js +0 -222
- package/src/vpool-xyk-amm/addPool.js +0 -197
- package/src/vpool-xyk-amm/constantProduct/AMM-Trade.jpeg +0 -0
- package/src/vpool-xyk-amm/constantProduct/README.md +0 -204
- package/src/vpool-xyk-amm/constantProduct/calcFees.js +0 -99
- package/src/vpool-xyk-amm/constantProduct/calcSwapPrices.js +0 -85
- package/src/vpool-xyk-amm/constantProduct/core.js +0 -153
- package/src/vpool-xyk-amm/constantProduct/defaults.js +0 -5
- package/src/vpool-xyk-amm/constantProduct/getXY.js +0 -52
- package/src/vpool-xyk-amm/constantProduct/internal-types.js +0 -116
- package/src/vpool-xyk-amm/constantProduct/invariants.js +0 -43
- package/src/vpool-xyk-amm/constantProduct/swap.js +0 -272
- package/src/vpool-xyk-amm/constantProduct/types.js +0 -32
- package/src/vpool-xyk-amm/doublePool.js +0 -194
- package/src/vpool-xyk-amm/estimate.js +0 -155
- package/src/vpool-xyk-amm/multipoolMarketMaker.js +0 -520
- package/src/vpool-xyk-amm/params.js +0 -61
- package/src/vpool-xyk-amm/pool.js +0 -396
- package/src/vpool-xyk-amm/priceAuthority.js +0 -94
- package/src/vpool-xyk-amm/removeLiquidity.js +0 -31
- package/src/vpool-xyk-amm/singlePool.js +0 -73
- package/src/vpool-xyk-amm/swap.js +0 -69
- package/src/vpool-xyk-amm/types.js +0 -154
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {object} ImprovedNoFeeSwapResult
|
|
5
|
-
* @property {Amount<'nat'>} amountIn
|
|
6
|
-
* @property {Amount<'nat'>} amountOut
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {object} FeePair
|
|
11
|
-
*
|
|
12
|
-
* @property {Amount<'nat'>} poolFee
|
|
13
|
-
* @property {Amount<'nat'>} protocolFee
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @typedef {object} PoolAllocation
|
|
18
|
-
*
|
|
19
|
-
* @property {Amount<'nat'>} Central
|
|
20
|
-
* @property {Amount<'nat'>} Secondary
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @typedef {object} NoFeeSwapFnInput
|
|
25
|
-
* @property {Amount} amountGiven
|
|
26
|
-
* @property {Amount} amountWanted
|
|
27
|
-
* @property {Brand=} brand
|
|
28
|
-
* @property {PoolAllocation} poolAllocation
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* This is the type for swapInNoFees and swapOutNoFees. pricesForStatedInput()
|
|
33
|
-
* uses swapInNoFees, while pricesForStatedOutput() uses swapOutNoFees.
|
|
34
|
-
*
|
|
35
|
-
* @callback NoFeeSwapFn
|
|
36
|
-
* @param {NoFeeSwapFnInput} input
|
|
37
|
-
* @returns {ImprovedNoFeeSwapResult}
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @typedef {FeePair & ImprovedNoFeeSwapResult} FeeEstimate
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @callback CalculateFees
|
|
46
|
-
* @param {Amount} amountGiven
|
|
47
|
-
* @param {PoolAllocation} poolAllocation
|
|
48
|
-
* @param {Amount} amountWanted
|
|
49
|
-
* @param {Ratio} protocolFeeRatio
|
|
50
|
-
* @param {Ratio} poolFeeRatio
|
|
51
|
-
* @param {NoFeeSwapFn} swapFn
|
|
52
|
-
* @returns {FeeEstimate}
|
|
53
|
-
*/
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @callback InternalSwap
|
|
57
|
-
* @param {Amount} amountGiven
|
|
58
|
-
* @param {PoolAllocation} poolAllocation
|
|
59
|
-
* @param {Amount} amountWanted
|
|
60
|
-
* @param {Ratio} protocolFeeRatio
|
|
61
|
-
* @param {Ratio} poolFeeRatio
|
|
62
|
-
* @param {NoFeeSwapFn} swapFn
|
|
63
|
-
* @returns {SinglePoolSwapResult}
|
|
64
|
-
*/
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @callback CalcSwapInPrices
|
|
68
|
-
* @param {Amount} amountGiven
|
|
69
|
-
* @param {PoolAllocation} poolAllocation
|
|
70
|
-
* @param {Amount=} amountWanted
|
|
71
|
-
* @param {Ratio} protocolFeeRatio
|
|
72
|
-
* @param {Ratio} poolFeeRatio
|
|
73
|
-
* @returns {SinglePoolSwapResult}
|
|
74
|
-
*/
|
|
75
|
-
/**
|
|
76
|
-
* @callback CalcSwapOutPrices
|
|
77
|
-
* @param {Amount=} amountGiven
|
|
78
|
-
* @param {PoolAllocation} poolAllocation
|
|
79
|
-
* @param {Amount} amountWanted
|
|
80
|
-
* @param {Ratio} protocolFeeRatio
|
|
81
|
-
* @param {Ratio} poolFeeRatio
|
|
82
|
-
* @returns {SinglePoolSwapResult}
|
|
83
|
-
*/
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @typedef {object} GetXYParam
|
|
87
|
-
* @property {Amount=} amountGiven
|
|
88
|
-
* @property {PoolAllocation} poolAllocation
|
|
89
|
-
* @property {Amount=} amountWanted
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @typedef {object} GetXYResultDeltaX
|
|
94
|
-
* @property {Amount} x
|
|
95
|
-
* @property {Amount} y
|
|
96
|
-
* @property {Amount} deltaX
|
|
97
|
-
* @property {Amount|undefined} deltaY
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @typedef {object} GetXYResultDeltaY
|
|
102
|
-
* @property {Amount} x
|
|
103
|
-
* @property {Amount} y
|
|
104
|
-
* @property {Amount} deltaY
|
|
105
|
-
* @property {Amount|undefined} deltaX
|
|
106
|
-
*/
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* @typedef {GetXYResultDeltaX & GetXYResultDeltaY} GetXYResult
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @callback GetXY
|
|
114
|
-
* @param {GetXYParam} obj
|
|
115
|
-
* @returns {GetXYResult}
|
|
116
|
-
*/
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import { assert, details as X } from '@agoric/assert';
|
|
4
|
-
import { AmountMath } from '@agoric/ertp';
|
|
5
|
-
|
|
6
|
-
import { natSafeMath } from '@agoric/zoe/src/contractSupport/index.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* xy <= (x + deltaX)(y - deltaY)
|
|
10
|
-
*
|
|
11
|
-
* @param {Amount} x - the amount of Brand X in pool, xPoolAllocation
|
|
12
|
-
* @param {Amount} y - the amount of Brand Y in pool, yPoolAllocation
|
|
13
|
-
* @param {Amount} deltaX - the amount of Brand X to be added
|
|
14
|
-
* @param {Amount} deltaY - the amount of Brand Y to be taken out
|
|
15
|
-
*/
|
|
16
|
-
export const checkKInvariantSellingX = (x, y, deltaX, deltaY) => {
|
|
17
|
-
const oldK = natSafeMath.multiply(x.value, y.value);
|
|
18
|
-
const newX = AmountMath.add(x, deltaX);
|
|
19
|
-
const newY = AmountMath.subtract(y, deltaY);
|
|
20
|
-
const newK = natSafeMath.multiply(newX.value, newY.value);
|
|
21
|
-
return oldK <= newK;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* xy <= (x + deltaX)(y - deltaY)
|
|
26
|
-
*
|
|
27
|
-
* @param {Amount} x - the amount of Brand X in pool, xPoolAllocation
|
|
28
|
-
* @param {Amount} y - the amount of Brand Y in pool, yPoolAllocation
|
|
29
|
-
* @param {Amount} deltaX - the amount of Brand X to be added
|
|
30
|
-
* @param {Amount} deltaY - the amount of Brand Y to be taken out
|
|
31
|
-
*/
|
|
32
|
-
export const assertKInvariantSellingX = (x, y, deltaX, deltaY) => {
|
|
33
|
-
assert(
|
|
34
|
-
checkKInvariantSellingX(x, y, deltaX, deltaY),
|
|
35
|
-
X`the constant product invariant was violated, with x=${x}, y=${y}, deltaX=${deltaX}, deltaY=${deltaY}, oldK=${natSafeMath.multiply(
|
|
36
|
-
x.value,
|
|
37
|
-
y.value,
|
|
38
|
-
)}, newK=${natSafeMath.multiply(
|
|
39
|
-
AmountMath.add(x, deltaX).value,
|
|
40
|
-
AmountMath.subtract(y, deltaY).value,
|
|
41
|
-
)}`,
|
|
42
|
-
);
|
|
43
|
-
};
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import { AmountMath } from '@agoric/ertp';
|
|
4
|
-
import { calculateFees, amountGT } from './calcFees.js';
|
|
5
|
-
|
|
6
|
-
const { details: X } = assert;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The fee might not be in the same brand as the amount. If they are the same,
|
|
10
|
-
* subtract the fee from the amount. Otherwise return the unadjusted amount.
|
|
11
|
-
*
|
|
12
|
-
* We return empty if the fee is larger because an empty amount indicates that
|
|
13
|
-
* the trader didn't place a limit on the inputAmount.
|
|
14
|
-
*
|
|
15
|
-
* @param {Amount} amount
|
|
16
|
-
* @param {Amount} fee
|
|
17
|
-
* @returns {Amount}
|
|
18
|
-
*/
|
|
19
|
-
const subtractRelevantFees = (amount, fee) => {
|
|
20
|
-
if (amount.brand === fee.brand) {
|
|
21
|
-
if (AmountMath.isGTE(fee, amount)) {
|
|
22
|
-
return AmountMath.makeEmptyFromAmount(amount);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return AmountMath.subtract(amount, fee);
|
|
26
|
-
}
|
|
27
|
-
return amount;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* PoolFee and ProtocolFee each identify their brand. If either (or both) match
|
|
32
|
-
* the brand of the Amount, subtract it/them from the amount.
|
|
33
|
-
*
|
|
34
|
-
* @param {Amount} amount
|
|
35
|
-
* @param {FeePair} fee
|
|
36
|
-
* @returns {Amount}
|
|
37
|
-
*/
|
|
38
|
-
const subtractFees = (amount, { poolFee, protocolFee }) => {
|
|
39
|
-
return subtractRelevantFees(
|
|
40
|
-
subtractRelevantFees(amount, protocolFee),
|
|
41
|
-
poolFee,
|
|
42
|
-
);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* The fee might not be in the same brand as the amount. If they are the same,
|
|
47
|
-
* add the fee to the amount. Otherwise return the unadjusted amount.
|
|
48
|
-
*
|
|
49
|
-
* @param {Amount} amount
|
|
50
|
-
* @param {Amount} fee
|
|
51
|
-
* @returns {Amount}
|
|
52
|
-
*/
|
|
53
|
-
const addRelevantFees = (amount, fee) => {
|
|
54
|
-
if (amount.brand === fee.brand) {
|
|
55
|
-
return AmountMath.add(amount, fee);
|
|
56
|
-
}
|
|
57
|
-
return amount;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* PoolFee and ProtocolFee each identify their brand. If either (or both) match
|
|
62
|
-
* the brand of the Amount, add it/them to the amount.
|
|
63
|
-
*
|
|
64
|
-
* @param {Amount} amount
|
|
65
|
-
* @param {FeePair} fee
|
|
66
|
-
* @returns {Amount}
|
|
67
|
-
*/
|
|
68
|
-
const addFees = (amount, { poolFee, protocolFee }) => {
|
|
69
|
-
return addRelevantFees(addRelevantFees(amount, protocolFee), poolFee);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Increment or decrement a pool balance by an amount. The amount's brand might
|
|
74
|
-
* match the Central or Secondary balance of the pool. Return the adjusted
|
|
75
|
-
* balance. The caller knows which amount they provided, so they're expecting a
|
|
76
|
-
* single Amount whose brand matches the amount parameter.
|
|
77
|
-
*
|
|
78
|
-
* The first parameter specifies whether we're incrementing or decrementing from the pool
|
|
79
|
-
*
|
|
80
|
-
* @param {(amountLeft: Amount, amountRight: Amount, brand?: Brand) => Amount} addOrSub
|
|
81
|
-
* @param {PoolAllocation} poolAllocation
|
|
82
|
-
* @param {Amount} amount
|
|
83
|
-
* @returns {Amount}
|
|
84
|
-
*/
|
|
85
|
-
const addOrSubtractFromPool = (addOrSub, poolAllocation, amount) => {
|
|
86
|
-
if (poolAllocation.Central.brand === amount.brand) {
|
|
87
|
-
return addOrSub(poolAllocation.Central, amount);
|
|
88
|
-
} else {
|
|
89
|
-
return addOrSub(poolAllocation.Secondary, amount);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const isGreaterThanZero = amount => {
|
|
94
|
-
return amount && amountGT(amount, AmountMath.makeEmptyFromAmount(amount));
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const assertGreaterThanZero = (amount, name) => {
|
|
98
|
-
(amount && isGreaterThanZero(amount)) ||
|
|
99
|
-
assert.fail(X`${name} must be greater than 0: ${amount}`);
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const isWantedAvailable = (poolAllocation, amountWanted) => {
|
|
103
|
-
// The question is about a poolAllocation. If it has exactly amountWanted,
|
|
104
|
-
// that's not sufficient, since it would leave the pool empty.
|
|
105
|
-
return amountWanted.brand === poolAllocation.Central.brand
|
|
106
|
-
? !AmountMath.isGTE(amountWanted, poolAllocation.Central)
|
|
107
|
-
: !AmountMath.isGTE(amountWanted, poolAllocation.Secondary);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* We've identified a violation of constraints that means we won't be able to
|
|
112
|
-
* satisfy the user's request. (Not enough funds in the pool, too much was
|
|
113
|
-
* requested, the proceeds would be empty, etc.) Return a result that says no
|
|
114
|
-
* trade will take place and the pool balances won't change.
|
|
115
|
-
*
|
|
116
|
-
* @param {Amount} amountGiven
|
|
117
|
-
* @param {Amount} amountWanted
|
|
118
|
-
* @param {PoolAllocation} poolAllocation
|
|
119
|
-
* @param {Ratio} poolFee
|
|
120
|
-
*/
|
|
121
|
-
const makeNoTransaction = (
|
|
122
|
-
amountGiven,
|
|
123
|
-
amountWanted,
|
|
124
|
-
poolAllocation,
|
|
125
|
-
poolFee,
|
|
126
|
-
) => {
|
|
127
|
-
const emptyGive = AmountMath.makeEmptyFromAmount(amountGiven);
|
|
128
|
-
const emptyWant = AmountMath.makeEmptyFromAmount(amountWanted);
|
|
129
|
-
|
|
130
|
-
let newX;
|
|
131
|
-
let newY;
|
|
132
|
-
if (poolAllocation.Central.brand === amountGiven.brand) {
|
|
133
|
-
newX = poolAllocation.Central;
|
|
134
|
-
newY = poolAllocation.Secondary;
|
|
135
|
-
} else {
|
|
136
|
-
newX = poolAllocation.Secondary;
|
|
137
|
-
newY = poolAllocation.Central;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const result = harden({
|
|
141
|
-
protocolFee: AmountMath.makeEmpty(poolAllocation.Central.brand),
|
|
142
|
-
poolFee: AmountMath.makeEmpty(poolFee.numerator.brand),
|
|
143
|
-
swapperGives: emptyGive,
|
|
144
|
-
swapperGets: emptyWant,
|
|
145
|
-
xIncrement: emptyGive,
|
|
146
|
-
yDecrement: emptyWant,
|
|
147
|
-
newX,
|
|
148
|
-
newY,
|
|
149
|
-
});
|
|
150
|
-
return result;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* This is the heart of the calculation. See README.md for the long explanation.
|
|
155
|
-
* calculate how much should be added to and removed from the pool, the fees,
|
|
156
|
-
* and what the user will pay and receive.
|
|
157
|
-
*
|
|
158
|
-
* As soon as we detect that we won't be able to satisfy the request, we return
|
|
159
|
-
* noTransaction, indicating that no trade should take place. This can be due to
|
|
160
|
-
* a request for more assets than the pool holds, a specified price the current
|
|
161
|
-
* assets won't support, or the trade would require more than the trader allowed,
|
|
162
|
-
* or provide less, or fees would eat up all the trader's proceeds.
|
|
163
|
-
*
|
|
164
|
-
* We start by calculating the amounts that would be traded if no fees were
|
|
165
|
-
* charged. The actual fees are based on these amounts. Once we know the actual
|
|
166
|
-
* fees, we calculate the deltaX and deltaY that will best maintain the
|
|
167
|
-
* constant product invariant.
|
|
168
|
-
*
|
|
169
|
-
* The amounts by which the pool will be adjusted, that the trader will pay and
|
|
170
|
-
* receive, and the fees are then computed based on deltaX and deltaY.
|
|
171
|
-
*
|
|
172
|
-
* @type {InternalSwap}
|
|
173
|
-
*/
|
|
174
|
-
export const swap = (
|
|
175
|
-
amountGiven,
|
|
176
|
-
poolAllocation,
|
|
177
|
-
amountWanted,
|
|
178
|
-
protocolFeeRatio,
|
|
179
|
-
poolFeeRatio,
|
|
180
|
-
swapFn,
|
|
181
|
-
) => {
|
|
182
|
-
const noTransaction = makeNoTransaction(
|
|
183
|
-
amountGiven,
|
|
184
|
-
amountWanted,
|
|
185
|
-
poolAllocation,
|
|
186
|
-
poolFeeRatio,
|
|
187
|
-
);
|
|
188
|
-
assertGreaterThanZero(poolAllocation.Central, 'poolAllocation.Central');
|
|
189
|
-
assertGreaterThanZero(poolAllocation.Secondary, 'poolAllocation.Secondary');
|
|
190
|
-
|
|
191
|
-
if (!isGreaterThanZero(amountGiven) && !isGreaterThanZero(amountWanted)) {
|
|
192
|
-
return noTransaction;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (!isWantedAvailable(poolAllocation, amountWanted)) {
|
|
196
|
-
return noTransaction;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// The protocol fee must always be collected in `Fee`, but the pool
|
|
200
|
-
// fee is collected in the amount opposite of what is specified.
|
|
201
|
-
// This call gives us improved amountIn or amountOut
|
|
202
|
-
const fees = calculateFees(
|
|
203
|
-
amountGiven,
|
|
204
|
-
poolAllocation,
|
|
205
|
-
amountWanted,
|
|
206
|
-
protocolFeeRatio,
|
|
207
|
-
poolFeeRatio,
|
|
208
|
-
swapFn,
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
if (!isWantedAvailable(poolAllocation, addFees(amountWanted, fees))) {
|
|
212
|
-
return noTransaction;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Calculate no-fee amounts. swapFn will only pay attention to the `specified`
|
|
216
|
-
// value. The pool fee is always charged on the unspecified side, so it is an
|
|
217
|
-
// output of the calculation. When the specified value is in `Fee`, the protocol fee will
|
|
218
|
-
// be deducted from amountGiven before adding to the pool or added to
|
|
219
|
-
// amountWanted to calculate amountOut. Otherwise we add the protocol fee
|
|
220
|
-
// to amountWanted.
|
|
221
|
-
const { amountIn, amountOut } = swapFn({
|
|
222
|
-
amountGiven: subtractFees(amountGiven, fees),
|
|
223
|
-
poolAllocation,
|
|
224
|
-
amountWanted: addFees(amountWanted, fees),
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
if (AmountMath.isEmpty(amountOut)) {
|
|
228
|
-
return noTransaction;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// The swapper pays extra or receives less to cover the fees.
|
|
232
|
-
const swapperGives = addFees(amountIn, fees);
|
|
233
|
-
const swapperGets = subtractFees(amountOut, fees);
|
|
234
|
-
|
|
235
|
-
// return noTransaction if fees would eat up all the trader's proceeds,
|
|
236
|
-
// the trader specified an amountGiven, and the trade would require more, or
|
|
237
|
-
// the trade would require them to give more than they specified.
|
|
238
|
-
if (
|
|
239
|
-
AmountMath.isEmpty(swapperGets) ||
|
|
240
|
-
(!AmountMath.isEmpty(amountGiven) && amountGT(swapperGives, amountGiven)) ||
|
|
241
|
-
amountGT(amountWanted, swapperGets)
|
|
242
|
-
) {
|
|
243
|
-
return noTransaction;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const xIncrement = addRelevantFees(amountIn, fees.poolFee);
|
|
247
|
-
const yDecrement = subtractRelevantFees(amountOut, fees.poolFee);
|
|
248
|
-
|
|
249
|
-
// poolFee is the amount the pool will grow over the no-fee calculation.
|
|
250
|
-
// protocolFee is to be separated and sent to an external purse.
|
|
251
|
-
// The swapper amounts are what will be paid and received.
|
|
252
|
-
// xIncrement and yDecrement are what will be added and removed from the pools.
|
|
253
|
-
// Either xIncrement will be increased by the pool fee or yDecrement will be
|
|
254
|
-
// reduced by it in order to compensate the pool.
|
|
255
|
-
// newX and newY are the new pool balances, for comparison with start values.
|
|
256
|
-
const result = harden({
|
|
257
|
-
protocolFee: fees.protocolFee,
|
|
258
|
-
poolFee: fees.poolFee,
|
|
259
|
-
swapperGives,
|
|
260
|
-
swapperGets,
|
|
261
|
-
xIncrement,
|
|
262
|
-
yDecrement,
|
|
263
|
-
newX: addOrSubtractFromPool(AmountMath.add, poolAllocation, xIncrement),
|
|
264
|
-
newY: addOrSubtractFromPool(
|
|
265
|
-
AmountMath.subtract,
|
|
266
|
-
poolAllocation,
|
|
267
|
-
yDecrement,
|
|
268
|
-
),
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
return result;
|
|
272
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @callback Maximum
|
|
5
|
-
* @param {Amount} left
|
|
6
|
-
* @param {Amount} right
|
|
7
|
-
* @returns {Amount}
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A bigint representing a number that will be divided by 10,0000. Financial
|
|
12
|
-
* ratios are often represented in basis points.
|
|
13
|
-
*
|
|
14
|
-
* @typedef {bigint} BASIS_POINTS
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Make a Ratio representing a fee expressed in Basis Points. (hundredths of a
|
|
19
|
-
* percent)
|
|
20
|
-
*
|
|
21
|
-
* @callback MakeFeeRatio
|
|
22
|
-
* @param {BASIS_POINTS} feeBP
|
|
23
|
-
* @param {Brand} brandOfFee
|
|
24
|
-
* @returns {Ratio}
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @callback AmountGT
|
|
29
|
-
* @param {Amount} left
|
|
30
|
-
* @param {Amount} right
|
|
31
|
-
* @returns {boolean}
|
|
32
|
-
*/
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import { AmountMath } from '@agoric/ertp';
|
|
4
|
-
import { Far } from '@endo/marshal';
|
|
5
|
-
import { makeFeeRatio } from './constantProduct/calcFees.js';
|
|
6
|
-
import {
|
|
7
|
-
pricesForStatedInput,
|
|
8
|
-
pricesForStatedOutput,
|
|
9
|
-
} from './constantProduct/calcSwapPrices.js';
|
|
10
|
-
|
|
11
|
-
const { details: X } = assert;
|
|
12
|
-
|
|
13
|
-
// Price calculations and swap using a pair of pools. Both pools map between RUN
|
|
14
|
-
// and some collateral. We arrange the trades so collateralInPool will have
|
|
15
|
-
// collateral added and collateralOutPool subtracted. When traders specify an
|
|
16
|
-
// input price, that brand will be the inPool; when they specify the output
|
|
17
|
-
// price that brand is the outPool.
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* doublePool is the virtualPool implementation for calculating prices when
|
|
21
|
-
* transiting through two pools. virtual pools wrap something that can do a swap
|
|
22
|
-
* and calculate prices. Current wrapped pools are single pools and pairs of
|
|
23
|
-
* pools, but we've also contemplated using a similar virtual wrapper for other
|
|
24
|
-
* curves.
|
|
25
|
-
*
|
|
26
|
-
* @param {ZCF} zcf
|
|
27
|
-
* @param {XYKPool} collateralInPool
|
|
28
|
-
* @param {XYKPool} collateralOutPool
|
|
29
|
-
* @param {() => bigint} getProtocolFeeBP - retrieve governed protocol fee value
|
|
30
|
-
* @param {() => bigint} getPoolFeeBP - retrieve governed pool fee value
|
|
31
|
-
* @param {ZCFSeat} feeSeat
|
|
32
|
-
* @returns {VirtualPool<'double'>}
|
|
33
|
-
*/
|
|
34
|
-
export const makeDoublePool = (
|
|
35
|
-
zcf,
|
|
36
|
-
collateralInPool,
|
|
37
|
-
collateralOutPool,
|
|
38
|
-
getProtocolFeeBP,
|
|
39
|
-
getPoolFeeBP,
|
|
40
|
-
feeSeat,
|
|
41
|
-
) => {
|
|
42
|
-
const inCentral = collateralInPool.getCentralAmount();
|
|
43
|
-
const inSecondary = collateralInPool.getSecondaryAmount();
|
|
44
|
-
|
|
45
|
-
const outCentral = collateralOutPool.getCentralAmount();
|
|
46
|
-
const outSecondary = collateralOutPool.getSecondaryAmount();
|
|
47
|
-
|
|
48
|
-
const inAllocation = { Central: inCentral, Secondary: inSecondary };
|
|
49
|
-
const outAllocation = { Central: outCentral, Secondary: outSecondary };
|
|
50
|
-
|
|
51
|
-
const centralBrand = inCentral.brand;
|
|
52
|
-
const emptyCentralAmount = AmountMath.makeEmpty(centralBrand);
|
|
53
|
-
centralBrand === outCentral.brand ||
|
|
54
|
-
assert.fail(
|
|
55
|
-
X`The central brands on the two pools must match: ${centralBrand}, ${outCentral.brand}`,
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
const allocateGainsAndLosses = (seat, prices) => {
|
|
59
|
-
const inPoolSeat = collateralInPool.getPoolSeat();
|
|
60
|
-
const outPoolSeat = collateralOutPool.getPoolSeat();
|
|
61
|
-
|
|
62
|
-
seat.decrementBy(harden({ In: prices.swapperGives }));
|
|
63
|
-
inPoolSeat.decrementBy(harden({ Central: prices.inPoolDecrement }));
|
|
64
|
-
outPoolSeat.decrementBy(harden({ Secondary: prices.outPoolDecrement }));
|
|
65
|
-
seat.incrementBy(harden({ Out: prices.swapperGets }));
|
|
66
|
-
inPoolSeat.incrementBy(harden({ Secondary: prices.inPoolIncrement }));
|
|
67
|
-
outPoolSeat.incrementBy(harden({ Central: prices.outPoolIncrement }));
|
|
68
|
-
feeSeat.incrementBy(harden({ Fee: prices.protocolFee }));
|
|
69
|
-
|
|
70
|
-
zcf.reallocate(outPoolSeat, inPoolSeat, feeSeat, seat);
|
|
71
|
-
seat.exit();
|
|
72
|
-
collateralInPool.updateState();
|
|
73
|
-
collateralOutPool.updateState();
|
|
74
|
-
return `Swap successfully completed.`;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const getPriceForInput = (amountIn, amountOut) => {
|
|
78
|
-
const protocolFeeRatio = makeFeeRatio(getProtocolFeeBP(), centralBrand);
|
|
79
|
-
const poolFeeRatioCentral = makeFeeRatio(getPoolFeeBP(), centralBrand);
|
|
80
|
-
const poolFeeRatioAmountOut = makeFeeRatio(getPoolFeeBP(), amountOut.brand);
|
|
81
|
-
|
|
82
|
-
// We must do two consecutive swapInPrice() calls,
|
|
83
|
-
// followed by a call to swapOutPrice().
|
|
84
|
-
// 1) from amountIn to the central token, which tells us how much central
|
|
85
|
-
// would be provided for amountIn,
|
|
86
|
-
// 2) from that amount of central to brandOut, which tells us how much of
|
|
87
|
-
// brandOut will be provided as well as the minimum price in central
|
|
88
|
-
// tokens, then finally
|
|
89
|
-
// 3) call swapOutPrice() to see if the same proceeds can be purchased for
|
|
90
|
-
// less.
|
|
91
|
-
// Notice that in the second call, the original amountOut is used, and in
|
|
92
|
-
// the third call, the original amountIn is used.
|
|
93
|
-
const interimInpoolPrices = pricesForStatedInput(
|
|
94
|
-
amountIn,
|
|
95
|
-
inAllocation,
|
|
96
|
-
emptyCentralAmount,
|
|
97
|
-
protocolFeeRatio,
|
|
98
|
-
poolFeeRatioCentral,
|
|
99
|
-
);
|
|
100
|
-
const outPoolPrices = pricesForStatedInput(
|
|
101
|
-
interimInpoolPrices.swapperGets,
|
|
102
|
-
outAllocation,
|
|
103
|
-
amountOut,
|
|
104
|
-
protocolFeeRatio,
|
|
105
|
-
poolFeeRatioAmountOut,
|
|
106
|
-
);
|
|
107
|
-
const finalInPoolPrices = pricesForStatedOutput(
|
|
108
|
-
amountIn,
|
|
109
|
-
inAllocation,
|
|
110
|
-
outPoolPrices.swapperGives,
|
|
111
|
-
protocolFeeRatio,
|
|
112
|
-
poolFeeRatioCentral,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
// When finalInPoolPrices has a price improvement that makes the difference
|
|
116
|
-
// between finalInPoolPrices.yDecrement and outPoolPrices.xIncrement more
|
|
117
|
-
// than the calculated protocol fees add the excess to the protocol fee.
|
|
118
|
-
const protocolFee = AmountMath.max(
|
|
119
|
-
AmountMath.add(finalInPoolPrices.protocolFee, outPoolPrices.protocolFee),
|
|
120
|
-
AmountMath.subtract(
|
|
121
|
-
finalInPoolPrices.yDecrement,
|
|
122
|
-
outPoolPrices.xIncrement,
|
|
123
|
-
),
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
return harden({
|
|
127
|
-
swapperGives: finalInPoolPrices.swapperGives,
|
|
128
|
-
swapperGets: outPoolPrices.swapperGets,
|
|
129
|
-
inPoolIncrement: finalInPoolPrices.xIncrement,
|
|
130
|
-
inPoolDecrement: finalInPoolPrices.yDecrement,
|
|
131
|
-
outPoolIncrement: outPoolPrices.xIncrement,
|
|
132
|
-
outPoolDecrement: outPoolPrices.yDecrement,
|
|
133
|
-
protocolFee,
|
|
134
|
-
});
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const getPriceForOutput = (amountIn, amountOut) => {
|
|
138
|
-
const protocolFeeRatio = makeFeeRatio(getProtocolFeeBP(), centralBrand);
|
|
139
|
-
const poolFeeRatioCentral = makeFeeRatio(getPoolFeeBP(), centralBrand);
|
|
140
|
-
const poolFeeRatioAmountIn = makeFeeRatio(getPoolFeeBP(), amountIn.brand);
|
|
141
|
-
|
|
142
|
-
// We must do two consecutive swapOutPrice() calls, followed by a call to
|
|
143
|
-
// swapInPrice().
|
|
144
|
-
// 1) from amountOut to the central token, which tells us how much central
|
|
145
|
-
// is required to obtain amountOut,
|
|
146
|
-
// 2) from that amount of central to brandIn, which tells us how much of
|
|
147
|
-
// brandIn is required as well as the max proceeds in central tokens, then
|
|
148
|
-
// finally
|
|
149
|
-
// 3) call swapInPrice() to see if those central proceeds could purchase
|
|
150
|
-
// larger amount
|
|
151
|
-
// Notice that the amountIn parameter to the first call to swapOutPrice
|
|
152
|
-
// specifies an empty amount. This is interpreted as "no limit", which is
|
|
153
|
-
// necessary since we can't guess a reasonable maximum of the central token.
|
|
154
|
-
const interimOutpoolPrices = pricesForStatedOutput(
|
|
155
|
-
emptyCentralAmount,
|
|
156
|
-
outAllocation,
|
|
157
|
-
amountOut,
|
|
158
|
-
protocolFeeRatio,
|
|
159
|
-
poolFeeRatioCentral,
|
|
160
|
-
);
|
|
161
|
-
const inpoolPrices = pricesForStatedOutput(
|
|
162
|
-
amountIn,
|
|
163
|
-
inAllocation,
|
|
164
|
-
interimOutpoolPrices.swapperGives,
|
|
165
|
-
protocolFeeRatio,
|
|
166
|
-
poolFeeRatioAmountIn,
|
|
167
|
-
);
|
|
168
|
-
const finalOutpoolPrices = pricesForStatedInput(
|
|
169
|
-
inpoolPrices.swapperGets,
|
|
170
|
-
outAllocation,
|
|
171
|
-
amountOut,
|
|
172
|
-
protocolFeeRatio,
|
|
173
|
-
poolFeeRatioCentral,
|
|
174
|
-
);
|
|
175
|
-
return harden({
|
|
176
|
-
swapperGives: inpoolPrices.swapperGives,
|
|
177
|
-
swapperGets: finalOutpoolPrices.swapperGets,
|
|
178
|
-
inPoolIncrement: inpoolPrices.xIncrement,
|
|
179
|
-
inPoolDecrement: inpoolPrices.yDecrement,
|
|
180
|
-
outPoolIncrement: finalOutpoolPrices.xIncrement,
|
|
181
|
-
outPoolDecrement: finalOutpoolPrices.yDecrement,
|
|
182
|
-
protocolFee: AmountMath.add(
|
|
183
|
-
finalOutpoolPrices.protocolFee,
|
|
184
|
-
inpoolPrices.protocolFee,
|
|
185
|
-
),
|
|
186
|
-
});
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
return Far('double pool', {
|
|
190
|
-
getPriceForInput,
|
|
191
|
-
getPriceForOutput,
|
|
192
|
-
allocateGainsAndLosses,
|
|
193
|
-
});
|
|
194
|
-
};
|