@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.
- 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
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { Fail } from '@agoric/assert';
|
|
4
|
+
import { AmountMath } from '@agoric/ertp';
|
|
5
|
+
import { assertAllDefined } from '@agoric/internal';
|
|
6
|
+
import { parseRatio } from '@agoric/zoe/src/contractSupport/ratio.js';
|
|
7
|
+
|
|
8
|
+
// XXX support other decimal places
|
|
9
|
+
const COSMOS_UNIT = 1_000_000n;
|
|
10
|
+
const scaleDecimals = num => BigInt(num * Number(COSMOS_UNIT));
|
|
11
|
+
|
|
12
|
+
// NB: not really a Proposal because the brands are not remotes
|
|
13
|
+
// Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
|
|
14
|
+
// mustMatch(harden(proposal), ProposalShape);
|
|
15
|
+
/**
|
|
16
|
+
* Give/want
|
|
17
|
+
*
|
|
18
|
+
* @param {Record<string, Brand>} brands
|
|
19
|
+
* @param {{ giveMinted?: number, wantMinted?: number } | { collateralBrandKey: string, giveCollateral?: number, wantCollateral?: number }} opts
|
|
20
|
+
* @returns {Proposal}
|
|
21
|
+
*/
|
|
22
|
+
const makeVaultProposal = (brands, opts) => {
|
|
23
|
+
const proposal = { give: {}, want: {} };
|
|
24
|
+
|
|
25
|
+
if ('giveCollateral' in opts && opts.giveCollateral) {
|
|
26
|
+
const { collateralBrandKey } = opts;
|
|
27
|
+
proposal.give.Collateral = {
|
|
28
|
+
brand: brands[collateralBrandKey],
|
|
29
|
+
value: scaleDecimals(opts.giveCollateral),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if ('giveMinted' in opts && opts.giveMinted) {
|
|
33
|
+
proposal.give.Minted = {
|
|
34
|
+
brand: brands.IST,
|
|
35
|
+
value: scaleDecimals(opts.giveMinted),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if ('wantCollateral' in opts && opts.wantCollateral) {
|
|
40
|
+
const { collateralBrandKey } = opts;
|
|
41
|
+
proposal.want.Collateral = {
|
|
42
|
+
brand: brands[collateralBrandKey],
|
|
43
|
+
value: scaleDecimals(opts.wantCollateral),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if ('wantMinted' in opts && opts.wantMinted) {
|
|
47
|
+
proposal.want.Minted = {
|
|
48
|
+
brand: brands.IST,
|
|
49
|
+
value: scaleDecimals(opts.wantMinted),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return harden(proposal);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {Record<string, Brand>} brands
|
|
58
|
+
* @param {{ offerId: string, wantMinted: number, giveCollateral: number, collateralBrandKey: string }} opts
|
|
59
|
+
* @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
|
|
60
|
+
*/
|
|
61
|
+
const makeOpenOffer = (brands, opts) => {
|
|
62
|
+
const proposal = makeVaultProposal(brands, opts);
|
|
63
|
+
|
|
64
|
+
// NB: not really a Proposal because the brands are not remotes
|
|
65
|
+
// Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
|
|
66
|
+
// mustMatch(harden(proposal), ProposalShape);
|
|
67
|
+
|
|
68
|
+
const collateralBrand = brands[opts.collateralBrandKey];
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
id: opts.offerId,
|
|
72
|
+
invitationSpec: {
|
|
73
|
+
source: 'agoricContract',
|
|
74
|
+
instancePath: ['VaultFactory'],
|
|
75
|
+
callPipe: [
|
|
76
|
+
['getCollateralManager', [collateralBrand]],
|
|
77
|
+
['makeVaultInvitation'],
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
proposal,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {Record<string, Brand>} brands
|
|
86
|
+
* @param {{ offerId: string, collateralBrandKey?: string, giveCollateral?: number, wantCollateral?: number, giveMinted?: number, wantMinted?: number }} opts
|
|
87
|
+
* @param {string} previousOffer
|
|
88
|
+
* @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
|
|
89
|
+
*/
|
|
90
|
+
const makeAdjustOffer = (brands, opts, previousOffer) => {
|
|
91
|
+
// NB: not really a Proposal because the brands are not remotes
|
|
92
|
+
// Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
|
|
93
|
+
// mustMatch(harden(proposal), ProposalShape);
|
|
94
|
+
const proposal = makeVaultProposal(brands, opts);
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
id: opts.offerId,
|
|
98
|
+
invitationSpec: {
|
|
99
|
+
source: 'continuing',
|
|
100
|
+
previousOffer,
|
|
101
|
+
invitationMakerName: 'AdjustBalances',
|
|
102
|
+
},
|
|
103
|
+
proposal,
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @param {Record<string, Brand>} brands
|
|
109
|
+
* @param {{ offerId: string, collateralBrandKey?: string, giveMinted: number }} opts
|
|
110
|
+
* @param {string} previousOffer
|
|
111
|
+
* @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
|
|
112
|
+
*/
|
|
113
|
+
const makeCloseOffer = (brands, opts, previousOffer) => {
|
|
114
|
+
const proposal = makeVaultProposal(brands, opts);
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
id: opts.offerId,
|
|
118
|
+
invitationSpec: {
|
|
119
|
+
source: 'continuing',
|
|
120
|
+
previousOffer,
|
|
121
|
+
invitationMakerName: 'CloseVault',
|
|
122
|
+
},
|
|
123
|
+
proposal,
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @param {string} vaultId
|
|
129
|
+
* @param {Promise<import('@agoric/smart-wallet/src/smartWallet').CurrentWalletRecord>} currentP
|
|
130
|
+
* @returns {Promise<string>} offer id in which the vault was made
|
|
131
|
+
*/
|
|
132
|
+
export const lookupOfferIdForVault = async (vaultId, currentP) => {
|
|
133
|
+
const { offerToPublicSubscriberPaths } = await currentP;
|
|
134
|
+
|
|
135
|
+
for (const [offerId, publicSubscribers] of offerToPublicSubscriberPaths) {
|
|
136
|
+
if (publicSubscribers.vault?.endsWith(vaultId)) {
|
|
137
|
+
return offerId;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
throw Fail`vault ${vaultId} not found`;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @param {Record<string, Brand>} brands
|
|
145
|
+
* @param {({ wantMinted: number | undefined, giveMinted: number | undefined })} opts
|
|
146
|
+
* @param {number} [fee=0]
|
|
147
|
+
* @param {string} [anchor]
|
|
148
|
+
* @returns {Proposal} XXX not a real proposal, uses BoardRemote
|
|
149
|
+
*/
|
|
150
|
+
const makePsmProposal = (brands, opts, fee = 0, anchor = 'AUSD') => {
|
|
151
|
+
const giving = opts.giveMinted ? 'minted' : 'anchor';
|
|
152
|
+
const brand =
|
|
153
|
+
giving === 'anchor'
|
|
154
|
+
? { in: brands[anchor], out: brands.IST }
|
|
155
|
+
: { in: brands.IST, out: brands[anchor] };
|
|
156
|
+
const value =
|
|
157
|
+
Number(giving === 'anchor' ? opts.wantMinted : opts.giveMinted) *
|
|
158
|
+
Number(COSMOS_UNIT);
|
|
159
|
+
const adjusted = {
|
|
160
|
+
in: BigInt(Math.ceil(giving === 'anchor' ? value / (1 - fee) : value)),
|
|
161
|
+
out: BigInt(Math.ceil(giving === 'minted' ? value * (1 - fee) : value)),
|
|
162
|
+
};
|
|
163
|
+
return {
|
|
164
|
+
give: {
|
|
165
|
+
In: { brand: brand.in, value: adjusted.in },
|
|
166
|
+
},
|
|
167
|
+
want: {
|
|
168
|
+
Out: { brand: brand.out, value: adjusted.out },
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @param {Instance} instance
|
|
175
|
+
* @param {Record<string, Brand>} brands
|
|
176
|
+
* @param {{ offerId: number, feePct?: number } &
|
|
177
|
+
* ({ wantMinted: number | undefined, giveMinted: number | undefined, pair: [string, string] })} opts
|
|
178
|
+
* @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
|
|
179
|
+
*/
|
|
180
|
+
const makePsmSwapOffer = (instance, brands, opts) => {
|
|
181
|
+
const method = opts.wantMinted
|
|
182
|
+
? 'makeWantMintedInvitation'
|
|
183
|
+
: 'makeGiveMintedInvitation'; // ref psm.js
|
|
184
|
+
const proposal = makePsmProposal(
|
|
185
|
+
brands,
|
|
186
|
+
opts,
|
|
187
|
+
opts.feePct ? opts.feePct / 100 : undefined,
|
|
188
|
+
opts.pair[1],
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// NB: not really a Proposal because the brands are not remotes
|
|
192
|
+
// Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
|
|
193
|
+
// mustMatch(harden(proposal), ProposalShape);
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
id: opts.offerId,
|
|
197
|
+
invitationSpec: {
|
|
198
|
+
source: 'contract',
|
|
199
|
+
instance,
|
|
200
|
+
publicInvitationMaker: method,
|
|
201
|
+
},
|
|
202
|
+
proposal,
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @param {Record<string, Brand>} _brands
|
|
208
|
+
* @param {{
|
|
209
|
+
* offerId: string,
|
|
210
|
+
* give: string,
|
|
211
|
+
* maxBuy: string,
|
|
212
|
+
* wantMinimum?: string,
|
|
213
|
+
* parseAmount: (x: string) => Amount<'nat'>,
|
|
214
|
+
* } & ({
|
|
215
|
+
* price: number,
|
|
216
|
+
* } | {
|
|
217
|
+
* discount: number, // -1 to 1. e.g. 0.10 for 10% discount, -0.05 for 5% markup
|
|
218
|
+
* })} opts
|
|
219
|
+
* @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
|
|
220
|
+
*/
|
|
221
|
+
const makeBidOffer = (_brands, opts) => {
|
|
222
|
+
assert.typeof(opts.parseAmount, 'function');
|
|
223
|
+
assertAllDefined({
|
|
224
|
+
offerId: opts.offerId,
|
|
225
|
+
give: opts.give,
|
|
226
|
+
maxBuy: opts.maxBuy,
|
|
227
|
+
});
|
|
228
|
+
const { parseAmount } = opts;
|
|
229
|
+
const proposal = {
|
|
230
|
+
give: { Bid: parseAmount(opts.give) },
|
|
231
|
+
...(opts.wantMinimum
|
|
232
|
+
? { want: { Collateral: parseAmount(opts.wantMinimum) } }
|
|
233
|
+
: {}),
|
|
234
|
+
};
|
|
235
|
+
const istBrand = proposal.give.Bid.brand;
|
|
236
|
+
const maxBuy = parseAmount(opts.maxBuy);
|
|
237
|
+
|
|
238
|
+
const bounds = (x, lo, hi) => {
|
|
239
|
+
assert(x >= lo && x <= hi);
|
|
240
|
+
return x;
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
assert(
|
|
244
|
+
'price' in opts || 'discount' in opts,
|
|
245
|
+
'must specify price or discount',
|
|
246
|
+
);
|
|
247
|
+
/** @type {import('./auction/auctionBook.js').OfferSpec} */
|
|
248
|
+
const offerArgs =
|
|
249
|
+
'price' in opts
|
|
250
|
+
? {
|
|
251
|
+
maxBuy: parseAmount(opts.maxBuy),
|
|
252
|
+
offerPrice: parseRatio(opts.price, istBrand, maxBuy.brand),
|
|
253
|
+
}
|
|
254
|
+
: {
|
|
255
|
+
maxBuy,
|
|
256
|
+
offerBidScaling: parseRatio(
|
|
257
|
+
(1 - bounds(opts.discount, -1, 1)).toFixed(2),
|
|
258
|
+
istBrand,
|
|
259
|
+
istBrand,
|
|
260
|
+
),
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
|
|
264
|
+
const offerSpec = {
|
|
265
|
+
id: opts.offerId,
|
|
266
|
+
invitationSpec: {
|
|
267
|
+
source: 'agoricContract',
|
|
268
|
+
instancePath: ['auctioneer'],
|
|
269
|
+
callPipe: [['makeBidInvitation', [maxBuy.brand]]],
|
|
270
|
+
},
|
|
271
|
+
proposal,
|
|
272
|
+
offerArgs,
|
|
273
|
+
};
|
|
274
|
+
return offerSpec;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* @param {Record<string, Brand>} brands
|
|
279
|
+
* @param {{
|
|
280
|
+
* offerId: string,
|
|
281
|
+
* give: number,
|
|
282
|
+
* collateralBrandKey: string,
|
|
283
|
+
* }} opts
|
|
284
|
+
* @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
|
|
285
|
+
*/
|
|
286
|
+
const makeAddCollateralOffer = (brands, opts) => {
|
|
287
|
+
/** @type {AmountKeywordRecord} */
|
|
288
|
+
const give = {
|
|
289
|
+
Collateral: AmountMath.make(
|
|
290
|
+
brands[opts.collateralBrandKey],
|
|
291
|
+
scaleDecimals(opts.give),
|
|
292
|
+
),
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/** @type {import('@agoric/smart-wallet/src/offers.js').OfferSpec} */
|
|
296
|
+
const offerSpec = {
|
|
297
|
+
id: opts.offerId,
|
|
298
|
+
invitationSpec: {
|
|
299
|
+
source: 'agoricContract',
|
|
300
|
+
instancePath: ['reserve'],
|
|
301
|
+
callPipe: [['makeAddCollateralInvitation', []]],
|
|
302
|
+
},
|
|
303
|
+
proposal: { give },
|
|
304
|
+
};
|
|
305
|
+
return offerSpec;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
export const Offers = {
|
|
309
|
+
auction: {
|
|
310
|
+
Bid: makeBidOffer,
|
|
311
|
+
},
|
|
312
|
+
psm: {
|
|
313
|
+
// lowercase because it's not an invitation name. Instead it's an abstraction over two invitation makers.
|
|
314
|
+
swap: makePsmSwapOffer,
|
|
315
|
+
},
|
|
316
|
+
vaults: {
|
|
317
|
+
OpenVault: makeOpenOffer,
|
|
318
|
+
AdjustBalances: makeAdjustOffer,
|
|
319
|
+
CloseVault: makeCloseOffer,
|
|
320
|
+
},
|
|
321
|
+
reserve: {
|
|
322
|
+
AddCollateral: makeAddCollateralOffer,
|
|
323
|
+
},
|
|
324
|
+
};
|
package/src/collectFees.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
|
+
|
|
3
|
+
import { atomicTransfer } from '@agoric/zoe/src/contractSupport/index.js';
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
6
|
* Provide shared support for providing access to fees from a service contract.
|
|
4
7
|
*
|
|
@@ -6,25 +9,16 @@
|
|
|
6
9
|
* @param {ZCFSeat} feeSeat
|
|
7
10
|
* @param {Brand} feeBrand
|
|
8
11
|
* @param {string} keyword
|
|
12
|
+
* @returns {Promise<Invitation<string>>}
|
|
9
13
|
*/
|
|
10
|
-
export const
|
|
11
|
-
zcf,
|
|
12
|
-
feeSeat,
|
|
13
|
-
feeBrand,
|
|
14
|
-
keyword,
|
|
15
|
-
) => {
|
|
14
|
+
export const makeCollectFeesInvitation = (zcf, feeSeat, feeBrand, keyword) => {
|
|
16
15
|
const collectFees = seat => {
|
|
17
16
|
const amount = feeSeat.getAmountAllocated(keyword, feeBrand);
|
|
18
|
-
feeSeat
|
|
19
|
-
seat.incrementBy(harden({ Fee: amount }));
|
|
20
|
-
zcf.reallocate(seat, feeSeat);
|
|
17
|
+
atomicTransfer(zcf, feeSeat, seat, { [keyword]: amount }, { Fee: amount });
|
|
21
18
|
|
|
22
19
|
seat.exit();
|
|
23
20
|
return `paid out ${amount.value}`;
|
|
24
21
|
};
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
zcf.makeInvitation(collectFees, 'collect fees');
|
|
28
|
-
|
|
29
|
-
return { makeCollectFeesInvitation };
|
|
23
|
+
return zcf.makeInvitation(collectFees, 'collect fees');
|
|
30
24
|
};
|
package/src/contractSupport.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
// @
|
|
1
|
+
// @jessie-check
|
|
2
|
+
|
|
2
3
|
import { AmountMath } from '@agoric/ertp';
|
|
3
4
|
import { makeStoredPublisherKit, makeStoredPublishKit } from '@agoric/notifier';
|
|
4
5
|
import { M } from '@agoric/store';
|
|
5
6
|
import { E } from '@endo/eventual-send';
|
|
6
7
|
|
|
7
|
-
const {
|
|
8
|
+
const { Fail, quote: q } = assert;
|
|
8
9
|
|
|
9
10
|
export const amountPattern = harden({ brand: M.remotable(), value: M.any() });
|
|
10
11
|
export const ratioPattern = harden({
|
|
@@ -19,10 +20,11 @@ export const ratioPattern = harden({
|
|
|
19
20
|
* on a proposal. We use two Amounts because an Amount cannot represent
|
|
20
21
|
* a negative number (so we use a "loss" that will be subtracted).
|
|
21
22
|
*
|
|
22
|
-
* @
|
|
23
|
-
* @param {Amount}
|
|
24
|
-
* @param {Amount}
|
|
25
|
-
* @
|
|
23
|
+
* @template {AssetKind} K
|
|
24
|
+
* @param {Amount<K>} base
|
|
25
|
+
* @param {Amount<K>} gain
|
|
26
|
+
* @param {Amount<K>} loss
|
|
27
|
+
* @returns {Amount<K>}
|
|
26
28
|
*/
|
|
27
29
|
export const addSubtract = (base, gain, loss) =>
|
|
28
30
|
AmountMath.subtract(AmountMath.add(base, gain), loss);
|
|
@@ -37,31 +39,16 @@ export const assertOnlyKeys = (proposal, keys) => {
|
|
|
37
39
|
/** @param {AmountKeywordRecord} clause */
|
|
38
40
|
const onlyKeys = clause =>
|
|
39
41
|
Object.getOwnPropertyNames(clause).every(c => keys.includes(c));
|
|
40
|
-
onlyKeys(proposal.give) ||
|
|
41
|
-
|
|
42
|
-
onlyKeys(proposal.want) ||
|
|
43
|
-
assert.fail(X`extraneous terms in want: ${proposal.want}`);
|
|
42
|
+
onlyKeys(proposal.give) || Fail`extraneous terms in give: ${proposal.give}`;
|
|
43
|
+
onlyKeys(proposal.want) || Fail`extraneous terms in want: ${proposal.want}`;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* give/want respectively of a proposal. The `key` is the allocation keyword.
|
|
50
|
-
*
|
|
51
|
-
* @param {ZCFSeat} fromSeat
|
|
52
|
-
* @param {ZCFSeat} toSeat
|
|
53
|
-
* @param {Amount} fromLoses
|
|
54
|
-
* @param {Amount} fromGains
|
|
55
|
-
* @param {Keyword} key
|
|
47
|
+
* @param {Amount[]} amounts
|
|
48
|
+
* @returns {boolean}
|
|
56
49
|
*/
|
|
57
|
-
export const
|
|
58
|
-
|
|
59
|
-
if (!AmountMath.isEmpty(fromLoses)) {
|
|
60
|
-
toSeat.incrementBy(fromSeat.decrementBy(harden({ [key]: fromLoses })));
|
|
61
|
-
}
|
|
62
|
-
if (!AmountMath.isEmpty(fromGains)) {
|
|
63
|
-
fromSeat.incrementBy(toSeat.decrementBy(harden({ [key]: fromGains })));
|
|
64
|
-
}
|
|
50
|
+
export const allEmpty = amounts => {
|
|
51
|
+
return amounts.every(a => AmountMath.isEmpty(a));
|
|
65
52
|
};
|
|
66
53
|
|
|
67
54
|
/**
|
|
@@ -72,16 +59,14 @@ export const stageDelta = (fromSeat, toSeat, fromLoses, fromGains, key) => {
|
|
|
72
59
|
*/
|
|
73
60
|
export const checkDebtLimit = (debtLimit, totalDebt, toMint) => {
|
|
74
61
|
const debtPost = AmountMath.add(totalDebt, toMint);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
)}`,
|
|
80
|
-
);
|
|
62
|
+
AmountMath.isGTE(debtLimit, debtPost) ||
|
|
63
|
+
Fail`Minting ${q(toMint)} past ${q(
|
|
64
|
+
totalDebt,
|
|
65
|
+
)} would hit total debt limit ${q(debtLimit)}`;
|
|
81
66
|
};
|
|
82
67
|
|
|
83
68
|
/**
|
|
84
|
-
* @deprecated
|
|
69
|
+
* @deprecated incompatible with durability; instead handle vstorage ephemerally on a durable PublishKit
|
|
85
70
|
* @template T
|
|
86
71
|
* @param {ERef<StorageNode>} storageNode
|
|
87
72
|
* @param {ERef<Marshaller>} marshaller
|
|
@@ -116,6 +101,7 @@ harden(makeMetricsPublisherKit);
|
|
|
116
101
|
*/
|
|
117
102
|
|
|
118
103
|
/**
|
|
104
|
+
* @deprecated incompatible with durability; instead handle vstorage ephemerally on a durable PublishKit
|
|
119
105
|
* @template T
|
|
120
106
|
* @param {ERef<StorageNode>} storageNode
|
|
121
107
|
* @param {ERef<Marshaller>} marshaller
|
|
@@ -137,38 +123,8 @@ export const makeMetricsPublishKit = (storageNode, marshaller) => {
|
|
|
137
123
|
harden(makeMetricsPublishKit);
|
|
138
124
|
|
|
139
125
|
/**
|
|
140
|
-
* @
|
|
141
|
-
* @
|
|
142
|
-
* @param {() => E} init
|
|
126
|
+
* @param {Brand} brand must be a 'nat' brand, not checked
|
|
127
|
+
* @param {NatValue} [min]
|
|
143
128
|
*/
|
|
144
|
-
export const
|
|
145
|
-
|
|
146
|
-
const ephemeras = new Map();
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Provide an object to hold state that need not (or cannot) be durable.
|
|
150
|
-
*
|
|
151
|
-
* @type {(key: K) => E}
|
|
152
|
-
*/
|
|
153
|
-
return key => {
|
|
154
|
-
if (ephemeras.has(key)) {
|
|
155
|
-
// @ts-expect-error cast
|
|
156
|
-
return ephemeras.get(key);
|
|
157
|
-
}
|
|
158
|
-
const newEph = init();
|
|
159
|
-
ephemeras.set(key, newEph);
|
|
160
|
-
return newEph;
|
|
161
|
-
};
|
|
162
|
-
};
|
|
163
|
-
harden(makeEphemeraProvider);
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* @template {Record<string, unknown>} T
|
|
167
|
-
* @param {T} specimen
|
|
168
|
-
* @param {Array<keyof T>} keyList
|
|
169
|
-
*/
|
|
170
|
-
export const assertKeysDefined = (specimen, keyList) => {
|
|
171
|
-
for (const key of keyList) {
|
|
172
|
-
assert(specimen[key], X`Missing ${q(key)}`);
|
|
173
|
-
}
|
|
174
|
-
};
|
|
129
|
+
export const makeNatAmountShape = (brand, min) =>
|
|
130
|
+
harden({ brand, value: min ? M.gte(min) : M.nat() });
|