@agoric/fast-usdc 0.1.1-dev-059601c.0 → 0.1.1-dev-ddff762.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/package.json +14 -14
- package/src/exos/advancer.js +28 -18
- package/src/exos/liquidity-pool.js +51 -44
- package/src/exos/settler.js +5 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/fast-usdc",
|
|
3
|
-
"version": "0.1.1-dev-
|
|
3
|
+
"version": "0.1.1-dev-ddff762.0+ddff762",
|
|
4
4
|
"description": "CLI and library for Fast USDC product",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"lint:eslint": "eslint ."
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@agoric/swingset-liveslots": "0.10.3-dev-
|
|
26
|
-
"@agoric/vats": "0.15.2-dev-
|
|
27
|
-
"@agoric/zone": "0.2.3-dev-
|
|
25
|
+
"@agoric/swingset-liveslots": "0.10.3-dev-ddff762.0+ddff762",
|
|
26
|
+
"@agoric/vats": "0.15.2-dev-ddff762.0+ddff762",
|
|
27
|
+
"@agoric/zone": "0.2.3-dev-ddff762.0+ddff762",
|
|
28
28
|
"@fast-check/ava": "^2.0.1",
|
|
29
29
|
"ava": "^5.3.0",
|
|
30
30
|
"c8": "^10.1.2",
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"ts-blank-space": "^0.4.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@agoric/client-utils": "0.1.1-dev-
|
|
36
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
37
|
-
"@agoric/internal": "0.3.3-dev-
|
|
38
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
39
|
-
"@agoric/orchestration": "0.1.1-dev-
|
|
40
|
-
"@agoric/store": "0.9.3-dev-
|
|
41
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
42
|
-
"@agoric/vow": "0.1.1-dev-
|
|
43
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
35
|
+
"@agoric/client-utils": "0.1.1-dev-ddff762.0+ddff762",
|
|
36
|
+
"@agoric/ertp": "0.16.3-dev-ddff762.0+ddff762",
|
|
37
|
+
"@agoric/internal": "0.3.3-dev-ddff762.0+ddff762",
|
|
38
|
+
"@agoric/notifier": "0.6.3-dev-ddff762.0+ddff762",
|
|
39
|
+
"@agoric/orchestration": "0.1.1-dev-ddff762.0+ddff762",
|
|
40
|
+
"@agoric/store": "0.9.3-dev-ddff762.0+ddff762",
|
|
41
|
+
"@agoric/vat-data": "0.5.3-dev-ddff762.0+ddff762",
|
|
42
|
+
"@agoric/vow": "0.1.1-dev-ddff762.0+ddff762",
|
|
43
|
+
"@agoric/zoe": "0.26.3-dev-ddff762.0+ddff762",
|
|
44
44
|
"@cosmjs/proto-signing": "^0.32.4",
|
|
45
45
|
"@cosmjs/stargate": "^0.32.4",
|
|
46
46
|
"@endo/base64": "^1.0.9",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"publishConfig": {
|
|
81
81
|
"access": "public"
|
|
82
82
|
},
|
|
83
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "ddff762be0166b7973abca7bb202901afa494e53"
|
|
84
84
|
}
|
package/src/exos/advancer.js
CHANGED
|
@@ -3,7 +3,6 @@ import { assertAllDefined, makeTracer } from '@agoric/internal';
|
|
|
3
3
|
import { AnyNatAmountShape, ChainAddressShape } from '@agoric/orchestration';
|
|
4
4
|
import { pickFacet } from '@agoric/vat-data';
|
|
5
5
|
import { VowShape } from '@agoric/vow';
|
|
6
|
-
import { q } from '@endo/errors';
|
|
7
6
|
import { E } from '@endo/far';
|
|
8
7
|
import { M } from '@endo/patterns';
|
|
9
8
|
import {
|
|
@@ -153,6 +152,7 @@ export const prepareAdvancerKit = (
|
|
|
153
152
|
recipientAddress,
|
|
154
153
|
EudParamShape,
|
|
155
154
|
);
|
|
155
|
+
log(`decoded EUD: ${EUD}`);
|
|
156
156
|
// throws if the bech32 prefix is not found
|
|
157
157
|
const destination = chainHub.makeChainAddress(EUD);
|
|
158
158
|
|
|
@@ -161,9 +161,8 @@ export const prepareAdvancerKit = (
|
|
|
161
161
|
const advanceAmount = feeTools.calculateAdvance(fullAmount);
|
|
162
162
|
|
|
163
163
|
const { zcfSeat: tmpSeat } = zcf.makeEmptySeatKit();
|
|
164
|
-
const amountKWR = harden({ USDC: advanceAmount });
|
|
165
164
|
// throws if the pool has insufficient funds
|
|
166
|
-
borrowerFacet.borrow(tmpSeat,
|
|
165
|
+
borrowerFacet.borrow(tmpSeat, advanceAmount);
|
|
167
166
|
|
|
168
167
|
// this cannot throw since `.isSeen()` is called in the same turn
|
|
169
168
|
statusManager.advance(evidence);
|
|
@@ -172,7 +171,7 @@ export const prepareAdvancerKit = (
|
|
|
172
171
|
tmpSeat,
|
|
173
172
|
// @ts-expect-error LocalAccountMethods vs OrchestrationAccount
|
|
174
173
|
poolAccount,
|
|
175
|
-
|
|
174
|
+
harden({ USDC: advanceAmount }),
|
|
176
175
|
);
|
|
177
176
|
void watch(depositV, this.facets.depositHandler, {
|
|
178
177
|
fullAmount,
|
|
@@ -182,8 +181,8 @@ export const prepareAdvancerKit = (
|
|
|
182
181
|
tmpSeat,
|
|
183
182
|
txHash: evidence.txHash,
|
|
184
183
|
});
|
|
185
|
-
} catch (
|
|
186
|
-
log('Advancer error:',
|
|
184
|
+
} catch (error) {
|
|
185
|
+
log('Advancer error:', error);
|
|
187
186
|
statusManager.observe(evidence);
|
|
188
187
|
}
|
|
189
188
|
},
|
|
@@ -212,18 +211,28 @@ export const prepareAdvancerKit = (
|
|
|
212
211
|
});
|
|
213
212
|
},
|
|
214
213
|
/**
|
|
214
|
+
* We do not expect this to be a common failure. it should only occur
|
|
215
|
+
* if USDC is not registered in vbank or the tmpSeat has less than
|
|
216
|
+
* `advanceAmount`.
|
|
217
|
+
*
|
|
218
|
+
* If we do hit this path, we return funds to the Liquidity Pool and
|
|
219
|
+
* notify of Advancing failure.
|
|
220
|
+
*
|
|
215
221
|
* @param {Error} error
|
|
216
222
|
* @param {AdvancerVowCtx & { tmpSeat: ZCFSeat }} ctx
|
|
217
223
|
*/
|
|
218
|
-
onRejected(error, { tmpSeat }) {
|
|
219
|
-
// TODO return seat allocation from ctx to LP?
|
|
220
|
-
log('🚨 advance deposit failed', q(error).toString());
|
|
221
|
-
// TODO #10510 (comprehensive error testing) determine
|
|
222
|
-
// course of action here
|
|
224
|
+
onRejected(error, { tmpSeat, advanceAmount, ...restCtx }) {
|
|
223
225
|
log(
|
|
224
|
-
'
|
|
225
|
-
|
|
226
|
+
'⚠️ deposit to localOrchAccount failed, attempting to return payment to LP',
|
|
227
|
+
error,
|
|
226
228
|
);
|
|
229
|
+
try {
|
|
230
|
+
const { borrowerFacet, notifyFacet } = this.state;
|
|
231
|
+
notifyFacet.notifyAdvancingResult(restCtx, false);
|
|
232
|
+
borrowerFacet.returnToPool(tmpSeat, advanceAmount);
|
|
233
|
+
} catch (e) {
|
|
234
|
+
log('🚨 deposit to localOrchAccount failure recovery failed', e);
|
|
235
|
+
}
|
|
227
236
|
},
|
|
228
237
|
},
|
|
229
238
|
transferHandler: {
|
|
@@ -234,10 +243,11 @@ export const prepareAdvancerKit = (
|
|
|
234
243
|
onFulfilled(result, ctx) {
|
|
235
244
|
const { notifyFacet } = this.state;
|
|
236
245
|
const { advanceAmount, destination, ...detail } = ctx;
|
|
237
|
-
log(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
246
|
+
log('Advance transfer fulfilled', {
|
|
247
|
+
advanceAmount,
|
|
248
|
+
destination,
|
|
249
|
+
result,
|
|
250
|
+
});
|
|
241
251
|
// During development, due to a bug, this call threw.
|
|
242
252
|
// The failure was silent (no diagnostics) due to:
|
|
243
253
|
// - #10576 Vows do not report unhandled rejections
|
|
@@ -252,7 +262,7 @@ export const prepareAdvancerKit = (
|
|
|
252
262
|
*/
|
|
253
263
|
onRejected(error, ctx) {
|
|
254
264
|
const { notifyFacet } = this.state;
|
|
255
|
-
log('Advance transfer rejected',
|
|
265
|
+
log('Advance transfer rejected', error);
|
|
256
266
|
notifyFacet.notifyAdvancingResult(ctx, false);
|
|
257
267
|
},
|
|
258
268
|
},
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
* @import {PoolStats} from '../types.js';
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
const { add, isEqual, makeEmpty } = AmountMath;
|
|
31
|
+
const { add, isEqual, isGTE, makeEmpty } = AmountMath;
|
|
32
32
|
|
|
33
33
|
/** @param {Brand} brand */
|
|
34
34
|
const makeDust = brand => AmountMath.make(brand, 1n);
|
|
@@ -84,10 +84,8 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
84
84
|
'Liquidity Pool',
|
|
85
85
|
{
|
|
86
86
|
borrower: M.interface('borrower', {
|
|
87
|
-
borrow: M.call(
|
|
88
|
-
|
|
89
|
-
harden({ USDC: makeNatAmountShape(USDC, 1n) }),
|
|
90
|
-
).returns(),
|
|
87
|
+
borrow: M.call(SeatShape, makeNatAmountShape(USDC, 1n)).returns(),
|
|
88
|
+
returnToPool: M.call(SeatShape, makeNatAmountShape(USDC, 1n)).returns(),
|
|
91
89
|
}),
|
|
92
90
|
repayer: M.interface('repayer', {
|
|
93
91
|
repay: M.call(
|
|
@@ -153,32 +151,48 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
153
151
|
borrower: {
|
|
154
152
|
/**
|
|
155
153
|
* @param {ZCFSeat} toSeat
|
|
156
|
-
* @param {
|
|
154
|
+
* @param {Amount<'nat'>} amount
|
|
157
155
|
*/
|
|
158
|
-
borrow(toSeat,
|
|
156
|
+
borrow(toSeat, amount) {
|
|
159
157
|
const { encumberedBalance, poolSeat, poolStats } = this.state;
|
|
160
158
|
|
|
161
159
|
// Validate amount is available in pool
|
|
162
160
|
const post = borrowCalc(
|
|
163
|
-
|
|
161
|
+
amount,
|
|
164
162
|
poolSeat.getAmountAllocated('USDC', USDC),
|
|
165
163
|
encumberedBalance,
|
|
166
164
|
poolStats,
|
|
167
165
|
);
|
|
168
166
|
|
|
169
167
|
// COMMIT POINT
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
} catch (cause) {
|
|
173
|
-
const reason = Error('🚨 cannot commit borrow', { cause });
|
|
174
|
-
console.error(reason.message, cause);
|
|
175
|
-
zcf.shutdownWithFailure(reason);
|
|
176
|
-
}
|
|
168
|
+
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
169
|
+
zcf.atomicRearrange(harden([[poolSeat, toSeat, { USDC: amount }]]));
|
|
177
170
|
|
|
178
171
|
Object.assign(this.state, post);
|
|
179
172
|
this.facets.external.publishPoolMetrics();
|
|
180
173
|
},
|
|
181
|
-
|
|
174
|
+
/**
|
|
175
|
+
* If something fails during advance, return funds to the pool.
|
|
176
|
+
*
|
|
177
|
+
* @param {ZCFSeat} borrowSeat
|
|
178
|
+
* @param {Amount<'nat'>} amount
|
|
179
|
+
*/
|
|
180
|
+
returnToPool(borrowSeat, amount) {
|
|
181
|
+
const { zcfSeat: repaySeat } = zcf.makeEmptySeatKit();
|
|
182
|
+
const returnAmounts = harden({
|
|
183
|
+
Principal: amount,
|
|
184
|
+
PoolFee: makeEmpty(USDC),
|
|
185
|
+
ContractFee: makeEmpty(USDC),
|
|
186
|
+
});
|
|
187
|
+
const borrowSeatAllocation = borrowSeat.getCurrentAllocation();
|
|
188
|
+
isGTE(borrowSeatAllocation.USDC, amount) ||
|
|
189
|
+
Fail`⚠️ borrowSeatAllocation ${q(borrowSeatAllocation)} less than amountKWR ${q(amount)}`;
|
|
190
|
+
// arrange payments in a format repay is expecting
|
|
191
|
+
zcf.atomicRearrange(
|
|
192
|
+
harden([[borrowSeat, repaySeat, { USDC: amount }, returnAmounts]]),
|
|
193
|
+
);
|
|
194
|
+
return this.facets.repayer.repay(repaySeat, returnAmounts);
|
|
195
|
+
},
|
|
182
196
|
},
|
|
183
197
|
repayer: {
|
|
184
198
|
/**
|
|
@@ -208,23 +222,18 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
208
222
|
const { ContractFee, ...rest } = amounts;
|
|
209
223
|
|
|
210
224
|
// COMMIT POINT
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
} catch (cause) {
|
|
224
|
-
const reason = Error('🚨 cannot commit repay', { cause });
|
|
225
|
-
console.error(reason.message, cause);
|
|
226
|
-
zcf.shutdownWithFailure(reason);
|
|
227
|
-
}
|
|
225
|
+
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
226
|
+
zcf.atomicRearrange(
|
|
227
|
+
harden([
|
|
228
|
+
[
|
|
229
|
+
fromSeat,
|
|
230
|
+
poolSeat,
|
|
231
|
+
rest,
|
|
232
|
+
{ USDC: add(amounts.PoolFee, amounts.Principal) },
|
|
233
|
+
],
|
|
234
|
+
[fromSeat, feeSeat, { ContractFee }, { USDC: ContractFee }],
|
|
235
|
+
]),
|
|
236
|
+
);
|
|
228
237
|
|
|
229
238
|
Object.assign(this.state, post);
|
|
230
239
|
this.facets.external.publishPoolMetrics();
|
|
@@ -259,9 +268,8 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
259
268
|
const post = depositCalc(shareWorth, proposal);
|
|
260
269
|
|
|
261
270
|
// COMMIT POINT
|
|
262
|
-
|
|
271
|
+
const mint = shareMint.mintGains(post.payouts);
|
|
263
272
|
try {
|
|
264
|
-
const mint = shareMint.mintGains(post.payouts);
|
|
265
273
|
this.state.shareWorth = post.shareWorth;
|
|
266
274
|
zcf.atomicRearrange(
|
|
267
275
|
harden([
|
|
@@ -271,12 +279,12 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
271
279
|
[mint, lp, post.payouts],
|
|
272
280
|
]),
|
|
273
281
|
);
|
|
282
|
+
} catch (cause) {
|
|
283
|
+
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
284
|
+
throw new Error('🚨 cannot commit deposit', { cause });
|
|
285
|
+
} finally {
|
|
274
286
|
lp.exit();
|
|
275
287
|
mint.exit();
|
|
276
|
-
} catch (cause) {
|
|
277
|
-
const reason = Error('🚨 cannot commit deposit', { cause });
|
|
278
|
-
console.error(reason.message, cause);
|
|
279
|
-
zcf.shutdownWithFailure(reason);
|
|
280
288
|
}
|
|
281
289
|
external.publishPoolMetrics();
|
|
282
290
|
},
|
|
@@ -296,7 +304,6 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
296
304
|
const post = withdrawCalc(shareWorth, proposal);
|
|
297
305
|
|
|
298
306
|
// COMMIT POINT
|
|
299
|
-
|
|
300
307
|
try {
|
|
301
308
|
this.state.shareWorth = post.shareWorth;
|
|
302
309
|
zcf.atomicRearrange(
|
|
@@ -308,12 +315,12 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
308
315
|
]),
|
|
309
316
|
);
|
|
310
317
|
shareMint.burnLosses(proposal.give, burn);
|
|
318
|
+
} catch (cause) {
|
|
319
|
+
// UNTIL #10684: ability to terminate an incarnation w/o terminating the contract
|
|
320
|
+
throw new Error('🚨 cannot commit withdraw', { cause });
|
|
321
|
+
} finally {
|
|
311
322
|
lp.exit();
|
|
312
323
|
burn.exit();
|
|
313
|
-
} catch (cause) {
|
|
314
|
-
const reason = Error('🚨 cannot commit withdraw', { cause });
|
|
315
|
-
console.error(reason.message, cause);
|
|
316
|
-
zcf.shutdownWithFailure(reason);
|
|
317
324
|
}
|
|
318
325
|
external.publishPoolMetrics();
|
|
319
326
|
},
|
package/src/exos/settler.js
CHANGED
|
@@ -237,13 +237,13 @@ export const prepareSettler = (
|
|
|
237
237
|
const split = calculateSplit(received);
|
|
238
238
|
log('disbursing', split);
|
|
239
239
|
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
//
|
|
240
|
+
// If this throws, which arguably can't occur since we don't ever
|
|
241
|
+
// withdraw more than has been deposited (as denoted by
|
|
242
|
+
// `FungibleTokenPacketData`), funds will remain in the
|
|
243
|
+
// `settlementAccount`. A remediation can occur in a future upgrade.
|
|
244
244
|
await vowTools.when(
|
|
245
245
|
withdrawToSeat(
|
|
246
|
-
// @ts-expect-error
|
|
246
|
+
// @ts-expect-error LocalAccountMethods vs OrchestrationAccount
|
|
247
247
|
settlementAccount,
|
|
248
248
|
settlingSeat,
|
|
249
249
|
harden({ In: received }),
|