@agoric/fast-usdc 0.2.0-u18a.0 → 0.2.0-u19.1
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/package.json +26 -25
- package/src/add-operators.core.js +63 -0
- package/src/cli/cli.js +1 -1
- package/src/cli/config-commands.js +1 -1
- package/src/cli/config.js +1 -1
- package/src/cli/lp-commands.js +21 -39
- package/src/cli/operator-commands.js +1 -0
- package/src/cli/transfer.js +5 -5
- package/src/clientSupport.js +98 -0
- package/src/distribute-fees.core.js +93 -0
- package/src/exos/advancer.js +109 -41
- package/src/exos/liquidity-pool.js +81 -34
- package/src/exos/operator-kit.js +0 -2
- package/src/exos/settler.js +154 -95
- package/src/exos/status-manager.js +97 -59
- package/src/exos/transaction-feed.js +30 -9
- package/src/fast-usdc-policy.core.js +2 -12
- package/src/fast-usdc.contract.js +23 -31
- package/src/main.js +1 -0
- package/src/pool-share-math.js +55 -9
- package/src/{fast-usdc.start.js → start-fast-usdc.core.js} +13 -81
- package/src/type-guards.js +37 -8
- package/src/types.ts +34 -5
- package/src/utils/chain-policies.js +140 -0
- package/src/utils/core-eval.js +73 -0
- package/src/utils/deploy-config.js +36 -75
- package/src/utils/fees.js +3 -4
- /package/src/{util → cli/util}/agoric.js +0 -0
- /package/src/{util → cli/util}/bank.js +0 -0
- /package/src/{util → cli/util}/cctp.js +0 -0
- /package/src/{util → cli/util}/file.js +0 -0
- /package/src/{util → cli/util}/noble.js +0 -0
package/src/exos/advancer.js
CHANGED
|
@@ -16,13 +16,14 @@ import { makeFeeTools } from '../utils/fees.js';
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @import {HostInterface} from '@agoric/async-flow';
|
|
19
|
+
* @import {Amount, Brand} from '@agoric/ertp';
|
|
19
20
|
* @import {TypedPattern} from '@agoric/internal'
|
|
20
21
|
* @import {NatAmount} from '@agoric/ertp';
|
|
21
22
|
* @import {ChainAddress, ChainHub, Denom, OrchestrationAccount} from '@agoric/orchestration';
|
|
22
23
|
* @import {ZoeTools} from '@agoric/orchestration/src/utils/zoe-tools.js';
|
|
23
24
|
* @import {VowTools} from '@agoric/vow';
|
|
24
25
|
* @import {Zone} from '@agoric/zone';
|
|
25
|
-
* @import {
|
|
26
|
+
* @import {AddressHook, EvmHash, FeeConfig, LogFn, NobleAddress, EvidenceWithRisk} from '../types.js';
|
|
26
27
|
* @import {StatusManager} from './status-manager.js';
|
|
27
28
|
* @import {LiquidityPoolKit} from './liquidity-pool.js';
|
|
28
29
|
*/
|
|
@@ -31,12 +32,12 @@ import { makeFeeTools } from '../utils/fees.js';
|
|
|
31
32
|
* @typedef {{
|
|
32
33
|
* chainHub: ChainHub;
|
|
33
34
|
* feeConfig: FeeConfig;
|
|
34
|
-
* localTransfer: ZoeTools['localTransfer'];
|
|
35
35
|
* log?: LogFn;
|
|
36
36
|
* statusManager: StatusManager;
|
|
37
37
|
* usdc: { brand: Brand<'nat'>; denom: Denom; };
|
|
38
38
|
* vowTools: VowTools;
|
|
39
39
|
* zcf: ZCF;
|
|
40
|
+
* zoeTools: ZoeTools;
|
|
40
41
|
* }} AdvancerKitPowers
|
|
41
42
|
*/
|
|
42
43
|
|
|
@@ -63,12 +64,21 @@ const AdvancerKitI = harden({
|
|
|
63
64
|
onRejected: M.call(M.error(), AdvancerVowCtxShape).returns(),
|
|
64
65
|
}),
|
|
65
66
|
transferHandler: M.interface('TransferHandlerI', {
|
|
66
|
-
// TODO confirm undefined, and not bigint (sequence)
|
|
67
67
|
onFulfilled: M.call(M.undefined(), AdvancerVowCtxShape).returns(
|
|
68
68
|
M.undefined(),
|
|
69
69
|
),
|
|
70
70
|
onRejected: M.call(M.error(), AdvancerVowCtxShape).returns(M.undefined()),
|
|
71
71
|
}),
|
|
72
|
+
withdrawHandler: M.interface('WithdrawHandlerI', {
|
|
73
|
+
onFulfilled: M.call(M.undefined(), {
|
|
74
|
+
advanceAmount: AnyNatAmountShape,
|
|
75
|
+
tmpReturnSeat: M.remotable(),
|
|
76
|
+
}).returns(M.undefined()),
|
|
77
|
+
onRejected: M.call(M.error(), {
|
|
78
|
+
advanceAmount: AnyNatAmountShape,
|
|
79
|
+
tmpReturnSeat: M.remotable(),
|
|
80
|
+
}).returns(M.undefined()),
|
|
81
|
+
}),
|
|
72
82
|
});
|
|
73
83
|
|
|
74
84
|
/**
|
|
@@ -81,6 +91,14 @@ const AdvancerKitI = harden({
|
|
|
81
91
|
* }} AdvancerVowCtx
|
|
82
92
|
*/
|
|
83
93
|
|
|
94
|
+
export const stateShape = harden({
|
|
95
|
+
notifier: M.remotable(),
|
|
96
|
+
borrower: M.remotable(),
|
|
97
|
+
poolAccount: M.remotable(),
|
|
98
|
+
intermediateRecipient: M.opt(ChainAddressShape),
|
|
99
|
+
settlementAddress: M.opt(ChainAddressShape),
|
|
100
|
+
});
|
|
101
|
+
|
|
84
102
|
/**
|
|
85
103
|
* @param {Zone} zone
|
|
86
104
|
* @param {AdvancerKitPowers} caps
|
|
@@ -90,12 +108,12 @@ export const prepareAdvancerKit = (
|
|
|
90
108
|
{
|
|
91
109
|
chainHub,
|
|
92
110
|
feeConfig,
|
|
93
|
-
localTransfer,
|
|
94
111
|
log = makeTracer('Advancer', true),
|
|
95
112
|
statusManager,
|
|
96
113
|
usdc,
|
|
97
114
|
vowTools: { watch, when },
|
|
98
115
|
zcf,
|
|
116
|
+
zoeTools: { localTransfer, withdrawToSeat },
|
|
99
117
|
},
|
|
100
118
|
) => {
|
|
101
119
|
assertAllDefined({
|
|
@@ -114,8 +132,8 @@ export const prepareAdvancerKit = (
|
|
|
114
132
|
AdvancerKitI,
|
|
115
133
|
/**
|
|
116
134
|
* @param {{
|
|
117
|
-
*
|
|
118
|
-
*
|
|
135
|
+
* notifier: import('./settler.js').SettlerKit['notifier'];
|
|
136
|
+
* borrower: LiquidityPoolKit['borrower'];
|
|
119
137
|
* poolAccount: HostInterface<OrchestrationAccount<{chainId: 'agoric'}>>;
|
|
120
138
|
* settlementAddress: ChainAddress;
|
|
121
139
|
* intermediateRecipient?: ChainAddress;
|
|
@@ -152,9 +170,7 @@ export const prepareAdvancerKit = (
|
|
|
152
170
|
statusManager.skipAdvance(evidence, risk.risksIdentified);
|
|
153
171
|
return;
|
|
154
172
|
}
|
|
155
|
-
|
|
156
|
-
const { borrowerFacet, poolAccount, settlementAddress } =
|
|
157
|
-
this.state;
|
|
173
|
+
const { settlementAddress } = this.state;
|
|
158
174
|
const { recipientAddress } = evidence.aux;
|
|
159
175
|
const decoded = decodeAddressHook(recipientAddress);
|
|
160
176
|
mustMatch(decoded, AddressHookShape);
|
|
@@ -167,12 +183,20 @@ export const prepareAdvancerKit = (
|
|
|
167
183
|
const destination = chainHub.makeChainAddress(EUD);
|
|
168
184
|
|
|
169
185
|
const fullAmount = toAmount(evidence.tx.amount);
|
|
186
|
+
const { borrower, notifier, poolAccount } = this.state;
|
|
187
|
+
// do not advance if we've already received a mint/settlement
|
|
188
|
+
const mintedEarly = notifier.checkMintedEarly(
|
|
189
|
+
evidence,
|
|
190
|
+
destination,
|
|
191
|
+
);
|
|
192
|
+
if (mintedEarly) return;
|
|
193
|
+
|
|
170
194
|
// throws if requested does not exceed fees
|
|
171
195
|
const advanceAmount = feeTools.calculateAdvance(fullAmount);
|
|
172
196
|
|
|
173
197
|
const { zcfSeat: tmpSeat } = zcf.makeEmptySeatKit();
|
|
174
198
|
// throws if the pool has insufficient funds
|
|
175
|
-
|
|
199
|
+
borrower.borrow(tmpSeat, advanceAmount);
|
|
176
200
|
|
|
177
201
|
// this cannot throw since `.isSeen()` is called in the same turn
|
|
178
202
|
statusManager.advance(evidence);
|
|
@@ -193,7 +217,7 @@ export const prepareAdvancerKit = (
|
|
|
193
217
|
});
|
|
194
218
|
} catch (error) {
|
|
195
219
|
log('Advancer error:', error);
|
|
196
|
-
statusManager.
|
|
220
|
+
statusManager.skipAdvance(evidence, [error.message]);
|
|
197
221
|
}
|
|
198
222
|
},
|
|
199
223
|
/** @param {ChainAddress} intermediateRecipient */
|
|
@@ -207,14 +231,21 @@ export const prepareAdvancerKit = (
|
|
|
207
231
|
* @param {AdvancerVowCtx & { tmpSeat: ZCFSeat }} ctx
|
|
208
232
|
*/
|
|
209
233
|
onFulfilled(result, ctx) {
|
|
210
|
-
const { poolAccount, intermediateRecipient } =
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
234
|
+
const { poolAccount, intermediateRecipient, settlementAddress } =
|
|
235
|
+
this.state;
|
|
236
|
+
const { destination, advanceAmount, tmpSeat, ...detail } = ctx;
|
|
237
|
+
tmpSeat.exit();
|
|
238
|
+
const amount = harden({
|
|
239
|
+
denom: usdc.denom,
|
|
240
|
+
value: advanceAmount.value,
|
|
241
|
+
});
|
|
242
|
+
const transferOrSendV =
|
|
243
|
+
destination.chainId === settlementAddress.chainId
|
|
244
|
+
? E(poolAccount).send(destination, amount)
|
|
245
|
+
: E(poolAccount).transfer(destination, amount, {
|
|
246
|
+
forwardOpts: { intermediateRecipient },
|
|
247
|
+
});
|
|
248
|
+
return watch(transferOrSendV, this.facets.transferHandler, {
|
|
218
249
|
destination,
|
|
219
250
|
advanceAmount,
|
|
220
251
|
...detail,
|
|
@@ -237,9 +268,10 @@ export const prepareAdvancerKit = (
|
|
|
237
268
|
error,
|
|
238
269
|
);
|
|
239
270
|
try {
|
|
240
|
-
const {
|
|
241
|
-
|
|
242
|
-
|
|
271
|
+
const { borrower, notifier } = this.state;
|
|
272
|
+
notifier.notifyAdvancingResult(restCtx, false);
|
|
273
|
+
borrower.returnToPool(tmpSeat, advanceAmount);
|
|
274
|
+
tmpSeat.exit();
|
|
243
275
|
} catch (e) {
|
|
244
276
|
log('🚨 deposit to localOrchAccount failure recovery failed', e);
|
|
245
277
|
}
|
|
@@ -247,44 +279,80 @@ export const prepareAdvancerKit = (
|
|
|
247
279
|
},
|
|
248
280
|
transferHandler: {
|
|
249
281
|
/**
|
|
250
|
-
* @param {
|
|
282
|
+
* @param {undefined} result
|
|
251
283
|
* @param {AdvancerVowCtx} ctx
|
|
252
284
|
*/
|
|
253
285
|
onFulfilled(result, ctx) {
|
|
254
|
-
const {
|
|
286
|
+
const { notifier } = this.state;
|
|
255
287
|
const { advanceAmount, destination, ...detail } = ctx;
|
|
256
|
-
log('Advance
|
|
257
|
-
advanceAmount,
|
|
258
|
-
destination,
|
|
259
|
-
result,
|
|
260
|
-
});
|
|
288
|
+
log('Advance succeeded', { advanceAmount, destination });
|
|
261
289
|
// During development, due to a bug, this call threw.
|
|
262
290
|
// The failure was silent (no diagnostics) due to:
|
|
263
291
|
// - #10576 Vows do not report unhandled rejections
|
|
264
292
|
// For now, the advancer kit relies on consistency between
|
|
265
|
-
//
|
|
293
|
+
// notify, statusManager, and callers of handleTransactionEvent().
|
|
266
294
|
// TODO: revisit #10576 during #10510
|
|
267
|
-
|
|
295
|
+
notifier.notifyAdvancingResult({ destination, ...detail }, true);
|
|
268
296
|
},
|
|
269
297
|
/**
|
|
270
298
|
* @param {Error} error
|
|
271
299
|
* @param {AdvancerVowCtx} ctx
|
|
272
300
|
*/
|
|
273
301
|
onRejected(error, ctx) {
|
|
274
|
-
const {
|
|
275
|
-
log('Advance
|
|
276
|
-
|
|
302
|
+
const { notifier, poolAccount } = this.state;
|
|
303
|
+
log('Advance failed', error);
|
|
304
|
+
const { advanceAmount, ...restCtx } = ctx;
|
|
305
|
+
notifier.notifyAdvancingResult(restCtx, false);
|
|
306
|
+
const { zcfSeat: tmpReturnSeat } = zcf.makeEmptySeatKit();
|
|
307
|
+
const withdrawV = withdrawToSeat(
|
|
308
|
+
// @ts-expect-error LocalAccountMethods vs OrchestrationAccount
|
|
309
|
+
poolAccount,
|
|
310
|
+
tmpReturnSeat,
|
|
311
|
+
harden({ USDC: advanceAmount }),
|
|
312
|
+
);
|
|
313
|
+
void watch(withdrawV, this.facets.withdrawHandler, {
|
|
314
|
+
advanceAmount,
|
|
315
|
+
tmpReturnSeat,
|
|
316
|
+
});
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
withdrawHandler: {
|
|
320
|
+
/**
|
|
321
|
+
*
|
|
322
|
+
* @param {undefined} result
|
|
323
|
+
* @param {{ advanceAmount: Amount<'nat'>; tmpReturnSeat: ZCFSeat; }} ctx
|
|
324
|
+
*/
|
|
325
|
+
onFulfilled(result, { advanceAmount, tmpReturnSeat }) {
|
|
326
|
+
const { borrower } = this.state;
|
|
327
|
+
try {
|
|
328
|
+
borrower.returnToPool(tmpReturnSeat, advanceAmount);
|
|
329
|
+
} catch (e) {
|
|
330
|
+
// If we reach here, the unused advance funds will remain in `tmpReturnSeat`
|
|
331
|
+
// and must be retrieved from recovery sets.
|
|
332
|
+
log(
|
|
333
|
+
`🚨 return ${q(advanceAmount)} to pool failed. funds remain on "tmpReturnSeat"`,
|
|
334
|
+
e,
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
tmpReturnSeat.exit();
|
|
338
|
+
},
|
|
339
|
+
/**
|
|
340
|
+
* @param {Error} error
|
|
341
|
+
* @param {{ advanceAmount: Amount<'nat'>; tmpReturnSeat: ZCFSeat; }} ctx
|
|
342
|
+
*/
|
|
343
|
+
onRejected(error, { advanceAmount, tmpReturnSeat }) {
|
|
344
|
+
log(
|
|
345
|
+
`🚨 withdraw ${q(advanceAmount)} from "poolAccount" to return to pool failed`,
|
|
346
|
+
error,
|
|
347
|
+
);
|
|
348
|
+
// If we reach here, the unused advance funds will remain in the `poolAccount`.
|
|
349
|
+
// A contract update will be required to return them to the LiquidityPool.
|
|
350
|
+
tmpReturnSeat.exit();
|
|
277
351
|
},
|
|
278
352
|
},
|
|
279
353
|
},
|
|
280
354
|
{
|
|
281
|
-
stateShape
|
|
282
|
-
notifyFacet: M.remotable(),
|
|
283
|
-
borrowerFacet: M.remotable(),
|
|
284
|
-
poolAccount: M.remotable(),
|
|
285
|
-
intermediateRecipient: M.opt(ChainAddressShape),
|
|
286
|
-
settlementAddress: M.opt(ChainAddressShape),
|
|
287
|
-
}),
|
|
355
|
+
stateShape,
|
|
288
356
|
},
|
|
289
357
|
);
|
|
290
358
|
};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { AmountMath } from '@agoric/ertp';
|
|
1
|
+
import { AmountMath, AmountShape, RatioShape } from '@agoric/ertp';
|
|
2
2
|
import {
|
|
3
3
|
makeRecorderTopic,
|
|
4
|
+
RecorderKitShape,
|
|
4
5
|
TopicsRecordShape,
|
|
5
|
-
} from '@agoric/zoe/src/contractSupport/
|
|
6
|
+
} from '@agoric/zoe/src/contractSupport/index.js';
|
|
6
7
|
import { SeatShape } from '@agoric/zoe/src/typeGuards.js';
|
|
7
8
|
import { M } from '@endo/patterns';
|
|
8
9
|
import { Fail, q } from '@endo/errors';
|
|
9
10
|
import {
|
|
10
11
|
borrowCalc,
|
|
12
|
+
checkPoolBalance,
|
|
11
13
|
depositCalc,
|
|
12
14
|
makeParity,
|
|
13
15
|
repayCalc,
|
|
@@ -20,6 +22,7 @@ import {
|
|
|
20
22
|
} from '../type-guards.js';
|
|
21
23
|
|
|
22
24
|
/**
|
|
25
|
+
* @import {Amount, Brand, Payment} from '@agoric/ertp';
|
|
23
26
|
* @import {Zone} from '@agoric/zone';
|
|
24
27
|
* @import {Remote} from '@agoric/internal'
|
|
25
28
|
* @import {StorageNode} from '@agoric/internal/src/lib-chainStorage.js'
|
|
@@ -28,32 +31,7 @@ import {
|
|
|
28
31
|
* @import {PoolStats} from '../types.js';
|
|
29
32
|
*/
|
|
30
33
|
|
|
31
|
-
const { add,
|
|
32
|
-
|
|
33
|
-
/** @param {Brand} brand */
|
|
34
|
-
const makeDust = brand => AmountMath.make(brand, 1n);
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Verifies that the total pool balance (unencumbered + encumbered) matches the
|
|
38
|
-
* shareWorth numerator. The total pool balance consists of:
|
|
39
|
-
* 1. unencumbered balance - USDC available in the pool for borrowing
|
|
40
|
-
* 2. encumbered balance - USDC currently lent out
|
|
41
|
-
*
|
|
42
|
-
* A negligible `dust` amount is used to initialize shareWorth with a non-zero
|
|
43
|
-
* denominator. It must remain in the pool at all times.
|
|
44
|
-
*
|
|
45
|
-
* @param {ZCFSeat} poolSeat
|
|
46
|
-
* @param {ShareWorth} shareWorth
|
|
47
|
-
* @param {Brand} USDC
|
|
48
|
-
* @param {Amount<'nat'>} encumberedBalance
|
|
49
|
-
*/
|
|
50
|
-
const checkPoolBalance = (poolSeat, shareWorth, USDC, encumberedBalance) => {
|
|
51
|
-
const unencumberedBalance = poolSeat.getAmountAllocated('USDC', USDC);
|
|
52
|
-
const dust = makeDust(USDC);
|
|
53
|
-
const grossBalance = add(add(unencumberedBalance, dust), encumberedBalance);
|
|
54
|
-
isEqual(grossBalance, shareWorth.numerator) ||
|
|
55
|
-
Fail`🚨 pool balance ${q(unencumberedBalance)} and encumbered balance ${q(encumberedBalance)} inconsistent with shareWorth ${q(shareWorth)}`;
|
|
56
|
-
};
|
|
34
|
+
const { add, isGTE, makeEmpty } = AmountMath;
|
|
57
35
|
|
|
58
36
|
/**
|
|
59
37
|
* @typedef {{
|
|
@@ -71,6 +49,22 @@ const checkPoolBalance = (poolSeat, shareWorth, USDC, encumberedBalance) => {
|
|
|
71
49
|
* }} RepayPaymentKWR
|
|
72
50
|
*/
|
|
73
51
|
|
|
52
|
+
export const stateShape = harden({
|
|
53
|
+
encumberedBalance: AmountShape,
|
|
54
|
+
feeSeat: M.remotable(),
|
|
55
|
+
poolStats: M.record(),
|
|
56
|
+
poolMetricsRecorderKit: RecorderKitShape,
|
|
57
|
+
poolSeat: M.remotable(),
|
|
58
|
+
PoolShares: M.remotable(),
|
|
59
|
+
proposalShapes: {
|
|
60
|
+
deposit: M.pattern(),
|
|
61
|
+
withdraw: M.pattern(),
|
|
62
|
+
withdrawFees: M.pattern(),
|
|
63
|
+
},
|
|
64
|
+
shareMint: M.remotable(),
|
|
65
|
+
shareWorth: RatioShape,
|
|
66
|
+
});
|
|
67
|
+
|
|
74
68
|
/**
|
|
75
69
|
* @param {Zone} zone
|
|
76
70
|
* @param {ZCF} zcf
|
|
@@ -106,11 +100,18 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
106
100
|
withdrawHandler: M.interface('withdrawHandler', {
|
|
107
101
|
handle: M.call(SeatShape, M.any()).returns(M.promise()),
|
|
108
102
|
}),
|
|
103
|
+
withdrawFeesHandler: M.interface('withdrawFeesHandler', {
|
|
104
|
+
handle: M.call(SeatShape, M.any()).returns(M.promise()),
|
|
105
|
+
}),
|
|
109
106
|
public: M.interface('public', {
|
|
110
107
|
makeDepositInvitation: M.call().returns(M.promise()),
|
|
111
108
|
makeWithdrawInvitation: M.call().returns(M.promise()),
|
|
112
109
|
getPublicTopics: M.call().returns(TopicsRecordShape),
|
|
113
110
|
}),
|
|
111
|
+
feeRecipient: M.interface('feeRecipient', {
|
|
112
|
+
getContractFeeBalance: M.call().returns(AmountShape),
|
|
113
|
+
makeWithdrawFeesInvitation: M.call().returns(M.promise()),
|
|
114
|
+
}),
|
|
114
115
|
},
|
|
115
116
|
/**
|
|
116
117
|
* @param {ZCFMint<'nat'>} shareMint
|
|
@@ -119,7 +120,7 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
119
120
|
(shareMint, node) => {
|
|
120
121
|
const { brand: PoolShares } = shareMint.getIssuerRecord();
|
|
121
122
|
const proposalShapes = makeProposalShapes({ USDC, PoolShares });
|
|
122
|
-
const shareWorth = makeParity(
|
|
123
|
+
const shareWorth = makeParity(USDC, PoolShares);
|
|
123
124
|
const { zcfSeat: poolSeat } = zcf.makeEmptySeatKit();
|
|
124
125
|
const { zcfSeat: feeSeat } = zcf.makeEmptySeatKit();
|
|
125
126
|
const poolMetricsRecorderKit = tools.makeRecorderKit(
|
|
@@ -191,7 +192,9 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
191
192
|
zcf.atomicRearrange(
|
|
192
193
|
harden([[borrowSeat, repaySeat, { USDC: amount }, returnAmounts]]),
|
|
193
194
|
);
|
|
194
|
-
|
|
195
|
+
this.facets.repayer.repay(repaySeat, returnAmounts);
|
|
196
|
+
borrowSeat.exit();
|
|
197
|
+
repaySeat.exit();
|
|
195
198
|
},
|
|
196
199
|
},
|
|
197
200
|
repayer: {
|
|
@@ -207,7 +210,11 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
207
210
|
poolStats,
|
|
208
211
|
shareWorth,
|
|
209
212
|
} = this.state;
|
|
210
|
-
checkPoolBalance(
|
|
213
|
+
checkPoolBalance(
|
|
214
|
+
poolSeat.getCurrentAllocation(),
|
|
215
|
+
shareWorth,
|
|
216
|
+
encumberedBalance,
|
|
217
|
+
);
|
|
211
218
|
|
|
212
219
|
const fromSeatAllocation = fromSeat.getCurrentAllocation();
|
|
213
220
|
// Validate allocation equals amounts and Principal <= encumberedBalance
|
|
@@ -264,7 +271,11 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
264
271
|
/** @type {USDCProposalShapes['deposit']} */
|
|
265
272
|
// @ts-expect-error ensured by proposalShape
|
|
266
273
|
const proposal = lp.getProposal();
|
|
267
|
-
checkPoolBalance(
|
|
274
|
+
checkPoolBalance(
|
|
275
|
+
poolSeat.getCurrentAllocation(),
|
|
276
|
+
shareWorth,
|
|
277
|
+
encumberedBalance,
|
|
278
|
+
);
|
|
268
279
|
const post = depositCalc(shareWorth, proposal);
|
|
269
280
|
|
|
270
281
|
// COMMIT POINT
|
|
@@ -300,8 +311,12 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
300
311
|
// @ts-expect-error ensured by proposalShape
|
|
301
312
|
const proposal = lp.getProposal();
|
|
302
313
|
const { zcfSeat: burn } = zcf.makeEmptySeatKit();
|
|
303
|
-
|
|
304
|
-
|
|
314
|
+
const post = withdrawCalc(
|
|
315
|
+
shareWorth,
|
|
316
|
+
proposal,
|
|
317
|
+
poolSeat.getCurrentAllocation(),
|
|
318
|
+
encumberedBalance,
|
|
319
|
+
);
|
|
305
320
|
|
|
306
321
|
// COMMIT POINT
|
|
307
322
|
try {
|
|
@@ -325,6 +340,21 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
325
340
|
external.publishPoolMetrics();
|
|
326
341
|
},
|
|
327
342
|
},
|
|
343
|
+
withdrawFeesHandler: {
|
|
344
|
+
/** @param {ZCFSeat} seat */
|
|
345
|
+
async handle(seat) {
|
|
346
|
+
const { feeSeat } = this.state;
|
|
347
|
+
|
|
348
|
+
const { want } = seat.getProposal();
|
|
349
|
+
const available = feeSeat.getAmountAllocated('USDC', want.USDC.brand);
|
|
350
|
+
isGTE(available, want.USDC) ||
|
|
351
|
+
Fail`cannot withdraw ${want.USDC}; only ${available} available`;
|
|
352
|
+
|
|
353
|
+
// COMMIT POINT
|
|
354
|
+
zcf.atomicRearrange(harden([[feeSeat, seat, want]]));
|
|
355
|
+
seat.exit();
|
|
356
|
+
},
|
|
357
|
+
},
|
|
328
358
|
public: {
|
|
329
359
|
makeDepositInvitation() {
|
|
330
360
|
return zcf.makeInvitation(
|
|
@@ -352,11 +382,28 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
352
382
|
};
|
|
353
383
|
},
|
|
354
384
|
},
|
|
385
|
+
feeRecipient: {
|
|
386
|
+
getContractFeeBalance() {
|
|
387
|
+
const { feeSeat } = this.state;
|
|
388
|
+
/** @type {Amount<'nat'>} */
|
|
389
|
+
const balance = feeSeat.getCurrentAllocation().USDC;
|
|
390
|
+
return balance;
|
|
391
|
+
},
|
|
392
|
+
makeWithdrawFeesInvitation() {
|
|
393
|
+
return zcf.makeInvitation(
|
|
394
|
+
this.facets.withdrawFeesHandler,
|
|
395
|
+
'Withdraw Fees',
|
|
396
|
+
undefined,
|
|
397
|
+
this.state.proposalShapes.withdrawFees,
|
|
398
|
+
);
|
|
399
|
+
},
|
|
400
|
+
},
|
|
355
401
|
},
|
|
356
402
|
{
|
|
357
403
|
finish: ({ facets: { external } }) => {
|
|
358
404
|
void external.publishPoolMetrics();
|
|
359
405
|
},
|
|
406
|
+
stateShape,
|
|
360
407
|
},
|
|
361
408
|
);
|
|
362
409
|
};
|
package/src/exos/operator-kit.js
CHANGED
|
@@ -90,8 +90,6 @@ export const prepareOperatorKit = (zone, staticPowers) =>
|
|
|
90
90
|
*/
|
|
91
91
|
async SubmitEvidence(evidence, riskAssessment) {
|
|
92
92
|
const { operator } = this.facets;
|
|
93
|
-
// TODO(bootstrap integration): cause this call to throw and confirm that it
|
|
94
|
-
// shows up in the the smart-wallet UpdateRecord `error` property
|
|
95
93
|
operator.submitEvidence(evidence, riskAssessment);
|
|
96
94
|
return staticPowers.makeInertInvitation(
|
|
97
95
|
'evidence was pushed in the invitation maker call',
|