@agoric/fast-usdc 0.1.1-dev-7e9048c.0 → 0.1.1-dev-44f449b.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 +15 -15
- package/src/distribute-fees.core.js +93 -0
- package/src/exos/liquidity-pool.js +39 -1
- package/src/fast-usdc.contract.js +7 -0
- package/src/pool-share-math.js +3 -0
- package/src/start-fast-usdc.core.js +10 -30
- package/src/type-guards.js +5 -1
- package/src/utils/core-eval.js +20 -3
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-44f449b.0+44f449b",
|
|
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-44f449b.0+44f449b",
|
|
26
|
+
"@agoric/vats": "0.15.2-dev-44f449b.0+44f449b",
|
|
27
|
+
"@agoric/zone": "0.2.3-dev-44f449b.0+44f449b",
|
|
28
28
|
"@fast-check/ava": "^2.0.1",
|
|
29
29
|
"ava": "^5.3.0",
|
|
30
30
|
"c8": "^10.1.2",
|
|
@@ -32,16 +32,16 @@
|
|
|
32
32
|
"ts-blank-space": "^0.4.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@agoric/client-utils": "0.1.1-dev-
|
|
36
|
-
"@agoric/cosmic-proto": "0.4.1-dev-
|
|
37
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
38
|
-
"@agoric/internal": "0.3.3-dev-
|
|
39
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
40
|
-
"@agoric/orchestration": "0.1.1-dev-
|
|
41
|
-
"@agoric/store": "0.9.3-dev-
|
|
42
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
43
|
-
"@agoric/vow": "0.1.1-dev-
|
|
44
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
35
|
+
"@agoric/client-utils": "0.1.1-dev-44f449b.0+44f449b",
|
|
36
|
+
"@agoric/cosmic-proto": "0.4.1-dev-44f449b.0+44f449b",
|
|
37
|
+
"@agoric/ertp": "0.16.3-dev-44f449b.0+44f449b",
|
|
38
|
+
"@agoric/internal": "0.3.3-dev-44f449b.0+44f449b",
|
|
39
|
+
"@agoric/notifier": "0.6.3-dev-44f449b.0+44f449b",
|
|
40
|
+
"@agoric/orchestration": "0.1.1-dev-44f449b.0+44f449b",
|
|
41
|
+
"@agoric/store": "0.9.3-dev-44f449b.0+44f449b",
|
|
42
|
+
"@agoric/vat-data": "0.5.3-dev-44f449b.0+44f449b",
|
|
43
|
+
"@agoric/vow": "0.1.1-dev-44f449b.0+44f449b",
|
|
44
|
+
"@agoric/zoe": "0.26.3-dev-44f449b.0+44f449b",
|
|
45
45
|
"@cosmjs/proto-signing": "^0.32.4",
|
|
46
46
|
"@cosmjs/stargate": "^0.32.4",
|
|
47
47
|
"@endo/base64": "^1.0.9",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"publishConfig": {
|
|
82
82
|
"access": "public"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "44f449b7fa1c9b8051d98e567c350fce37e33f83"
|
|
85
85
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/** @file core eval module to collect fees. */
|
|
2
|
+
import { AmountMath } from '@agoric/ertp';
|
|
3
|
+
import { floorMultiplyBy } from '@agoric/zoe/src/contractSupport/index.js';
|
|
4
|
+
import { E } from '@endo/far';
|
|
5
|
+
import { makeTracer } from '@agoric/internal';
|
|
6
|
+
import { fromExternalConfig } from './utils/config-marshal.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @import {DepositFacet} from '@agoric/ertp';
|
|
10
|
+
* @import {FastUSDCCorePowers} from '@agoric/fast-usdc/src/start-fast-usdc.core.js';
|
|
11
|
+
* @import {CopyRecord} from '@endo/pass-style'
|
|
12
|
+
* @import {BootstrapManifestPermit} from '@agoric/vats/src/core/lib-boot.js'
|
|
13
|
+
* @import {LegibleCapData} from './utils/config-marshal.js'
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {{ destinationAddress: string } &
|
|
18
|
+
* ({ feePortion: Ratio} | {fixedFees: Amount<'nat'>}) &
|
|
19
|
+
* CopyRecord
|
|
20
|
+
* } FeeDistributionTerms
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const kwUSDC = 'USDC'; // keyword in AmountKeywordRecord
|
|
24
|
+
const issUSDC = 'USDC'; // issuer name
|
|
25
|
+
|
|
26
|
+
const trace = makeTracer('FUCF', true);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {BootstrapPowers & FastUSDCCorePowers } permittedPowers
|
|
30
|
+
* @param {{ options: LegibleCapData<{ feeTerms: FeeDistributionTerms}> }} config
|
|
31
|
+
*/
|
|
32
|
+
export const distributeFees = async (permittedPowers, config) => {
|
|
33
|
+
trace('distributeFees...', config.options);
|
|
34
|
+
|
|
35
|
+
const { agoricNames, namesByAddress, zoe } = permittedPowers.consume;
|
|
36
|
+
/** @type {Brand<'nat'>} */
|
|
37
|
+
const usdcBrand = await E(agoricNames).lookup('brand', issUSDC);
|
|
38
|
+
/** @type {{ feeTerms: FeeDistributionTerms}} */
|
|
39
|
+
const { feeTerms: terms } = fromExternalConfig(config.options, {
|
|
40
|
+
USDC: usdcBrand,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const { creatorFacet } = await permittedPowers.consume.fastUsdcKit;
|
|
44
|
+
const want = {
|
|
45
|
+
[kwUSDC]: await ('fixedFees' in terms
|
|
46
|
+
? terms.fixedFees
|
|
47
|
+
: E(creatorFacet)
|
|
48
|
+
.getContractFeeBalance()
|
|
49
|
+
.then(balance => floorMultiplyBy(balance, terms.feePortion))),
|
|
50
|
+
};
|
|
51
|
+
const proposal = harden({ want });
|
|
52
|
+
|
|
53
|
+
/** @type {DepositFacet} */
|
|
54
|
+
const depositFacet = await E(namesByAddress).lookup(
|
|
55
|
+
terms.destinationAddress,
|
|
56
|
+
'depositFacet',
|
|
57
|
+
);
|
|
58
|
+
trace('to:', terms.destinationAddress, depositFacet);
|
|
59
|
+
|
|
60
|
+
const toWithdraw = await E(creatorFacet).makeWithdrawFeesInvitation();
|
|
61
|
+
trace('invitation:', toWithdraw, 'proposal:', proposal);
|
|
62
|
+
const seat = E(zoe).offer(toWithdraw, proposal);
|
|
63
|
+
const result = await E(seat).getOfferResult();
|
|
64
|
+
trace('offer result', result);
|
|
65
|
+
const payout = await E(seat).getPayout(kwUSDC);
|
|
66
|
+
/** @type {Amount<'nat'>} */
|
|
67
|
+
// @ts-expect-error USDC is a nat brand
|
|
68
|
+
const rxd = await E(depositFacet).receive(payout);
|
|
69
|
+
trace('received', rxd);
|
|
70
|
+
if (!AmountMath.isGTE(rxd, proposal.want[kwUSDC])) {
|
|
71
|
+
trace('🚨 expected', proposal.want[kwUSDC], 'got', rxd);
|
|
72
|
+
}
|
|
73
|
+
trace('done');
|
|
74
|
+
};
|
|
75
|
+
harden(distributeFees);
|
|
76
|
+
|
|
77
|
+
/** @satisfies {BootstrapManifestPermit} */
|
|
78
|
+
const permit = {
|
|
79
|
+
consume: {
|
|
80
|
+
fastUsdcKit: true,
|
|
81
|
+
agoricNames: true,
|
|
82
|
+
namesByAddress: true,
|
|
83
|
+
zoe: true,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {unknown} _utils
|
|
89
|
+
* @param {Parameters<typeof distributeFees>[1]} config
|
|
90
|
+
*/
|
|
91
|
+
export const getManifestForDistributeFees = (_utils, { options }) => {
|
|
92
|
+
return { manifest: { [distributeFees.name]: permit }, options };
|
|
93
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AmountMath } from '@agoric/ertp';
|
|
1
|
+
import { AmountMath, AmountShape } from '@agoric/ertp';
|
|
2
2
|
import {
|
|
3
3
|
makeRecorderTopic,
|
|
4
4
|
TopicsRecordShape,
|
|
@@ -107,11 +107,18 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
107
107
|
withdrawHandler: M.interface('withdrawHandler', {
|
|
108
108
|
handle: M.call(SeatShape, M.any()).returns(M.promise()),
|
|
109
109
|
}),
|
|
110
|
+
withdrawFeesHandler: M.interface('withdrawFeesHandler', {
|
|
111
|
+
handle: M.call(SeatShape, M.any()).returns(M.promise()),
|
|
112
|
+
}),
|
|
110
113
|
public: M.interface('public', {
|
|
111
114
|
makeDepositInvitation: M.call().returns(M.promise()),
|
|
112
115
|
makeWithdrawInvitation: M.call().returns(M.promise()),
|
|
113
116
|
getPublicTopics: M.call().returns(TopicsRecordShape),
|
|
114
117
|
}),
|
|
118
|
+
feeRecipient: M.interface('feeRecipient', {
|
|
119
|
+
getContractFeeBalance: M.call().returns(AmountShape),
|
|
120
|
+
makeWithdrawFeesInvitation: M.call().returns(M.promise()),
|
|
121
|
+
}),
|
|
115
122
|
},
|
|
116
123
|
/**
|
|
117
124
|
* @param {ZCFMint<'nat'>} shareMint
|
|
@@ -326,6 +333,21 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
326
333
|
external.publishPoolMetrics();
|
|
327
334
|
},
|
|
328
335
|
},
|
|
336
|
+
withdrawFeesHandler: {
|
|
337
|
+
/** @param {ZCFSeat} seat */
|
|
338
|
+
async handle(seat) {
|
|
339
|
+
const { feeSeat } = this.state;
|
|
340
|
+
|
|
341
|
+
const { want } = seat.getProposal();
|
|
342
|
+
const available = feeSeat.getAmountAllocated('USDC', want.USDC.brand);
|
|
343
|
+
isGTE(available, want.USDC) ||
|
|
344
|
+
Fail`cannot withdraw ${want.USDC}; only ${available} available`;
|
|
345
|
+
|
|
346
|
+
// COMMIT POINT
|
|
347
|
+
zcf.atomicRearrange(harden([[feeSeat, seat, want]]));
|
|
348
|
+
seat.exit();
|
|
349
|
+
},
|
|
350
|
+
},
|
|
329
351
|
public: {
|
|
330
352
|
makeDepositInvitation() {
|
|
331
353
|
return zcf.makeInvitation(
|
|
@@ -353,6 +375,22 @@ export const prepareLiquidityPoolKit = (zone, zcf, USDC, tools) => {
|
|
|
353
375
|
};
|
|
354
376
|
},
|
|
355
377
|
},
|
|
378
|
+
feeRecipient: {
|
|
379
|
+
getContractFeeBalance() {
|
|
380
|
+
const { feeSeat } = this.state;
|
|
381
|
+
/** @type {Amount<'nat'>} */
|
|
382
|
+
const balance = feeSeat.getCurrentAllocation().USDC;
|
|
383
|
+
return balance;
|
|
384
|
+
},
|
|
385
|
+
makeWithdrawFeesInvitation() {
|
|
386
|
+
return zcf.makeInvitation(
|
|
387
|
+
this.facets.withdrawFeesHandler,
|
|
388
|
+
'Withdraw Fees',
|
|
389
|
+
undefined,
|
|
390
|
+
this.state.proposalShapes.withdrawFees,
|
|
391
|
+
);
|
|
392
|
+
},
|
|
393
|
+
},
|
|
356
394
|
},
|
|
357
395
|
{
|
|
358
396
|
finish: ({ facets: { external } }) => {
|
|
@@ -161,6 +161,13 @@ export const contract = async (zcf, privateArgs, zone, tools) => {
|
|
|
161
161
|
removeOperator(operatorId) {
|
|
162
162
|
return feedKit.creator.removeOperator(operatorId);
|
|
163
163
|
},
|
|
164
|
+
async getContractFeeBalance() {
|
|
165
|
+
return poolKit.feeRecipient.getContractFeeBalance();
|
|
166
|
+
},
|
|
167
|
+
/** @type {() => Promise<Invitation<unknown>>} */
|
|
168
|
+
async makeWithdrawFeesInvitation() {
|
|
169
|
+
return poolKit.feeRecipient.makeWithdrawFeesInvitation();
|
|
170
|
+
},
|
|
164
171
|
async connectToNoble() {
|
|
165
172
|
return vowTools.when(nobleAccountV, nobleAccount => {
|
|
166
173
|
trace('nobleAccount', nobleAccount);
|
package/src/pool-share-math.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { deeplyFulfilledObject, makeTracer } from '@agoric/internal';
|
|
2
|
-
import { Fail } from '@endo/errors';
|
|
3
2
|
import { E } from '@endo/far';
|
|
4
|
-
import { makeMarshal } from '@endo/marshal';
|
|
5
3
|
import { FastUSDCConfigShape } from './type-guards.js';
|
|
6
4
|
import { fromExternalConfig } from './utils/config-marshal.js';
|
|
7
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
inviteOracles,
|
|
7
|
+
publishDisplayInfo,
|
|
8
|
+
publishFeedPolicy,
|
|
9
|
+
} from './utils/core-eval.js';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
|
-
* @import {
|
|
11
|
-
* @import {TypedPattern} from '@agoric/internal'
|
|
12
|
+
* @import {Brand, Issuer} from '@agoric/ertp';
|
|
12
13
|
* @import {Instance, StartParams} from '@agoric/zoe/src/zoeService/utils'
|
|
13
14
|
* @import {Board} from '@agoric/vats'
|
|
14
15
|
* @import {ManifestBundleRef} from '@agoric/deploy-script-support/src/externalTypes.js'
|
|
15
16
|
* @import {BootstrapManifest} from '@agoric/vats/src/core/lib-boot.js'
|
|
16
|
-
* @import {Passable} from '@endo/pass-style'
|
|
17
17
|
* @import {LegibleCapData} from './utils/config-marshal.js'
|
|
18
18
|
* @import {FastUsdcSF} from './fast-usdc.contract.js'
|
|
19
|
-
* @import {
|
|
19
|
+
* @import {FastUSDCConfig} from './types.js'
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
const ShareAssetInfo = /** @type {const} */ harden({
|
|
@@ -46,26 +46,6 @@ const makePublishingStorageKit = async (path, { chainStorage, board }) => {
|
|
|
46
46
|
return { storageNode, marshaller };
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
const BOARD_AUX = 'boardAux';
|
|
50
|
-
const marshalData = makeMarshal(_val => Fail`data only`);
|
|
51
|
-
/**
|
|
52
|
-
* @param {Brand} brand
|
|
53
|
-
* @param {Pick<BootstrapPowers['consume'], 'board' | 'chainStorage'>} powers
|
|
54
|
-
*/
|
|
55
|
-
const publishDisplayInfo = async (brand, { board, chainStorage }) => {
|
|
56
|
-
// chainStorage type includes undefined, which doesn't apply here.
|
|
57
|
-
// @ts-expect-error UNTIL https://github.com/Agoric/agoric-sdk/issues/8247
|
|
58
|
-
const boardAux = E(chainStorage).makeChildNode(BOARD_AUX);
|
|
59
|
-
const [id, displayInfo, allegedName] = await Promise.all([
|
|
60
|
-
E(board).getId(brand),
|
|
61
|
-
E(brand).getDisplayInfo(),
|
|
62
|
-
E(brand).getAllegedName(),
|
|
63
|
-
]);
|
|
64
|
-
const node = E(boardAux).makeChildNode(id);
|
|
65
|
-
const aux = marshalData.toCapData(harden({ allegedName, displayInfo }));
|
|
66
|
-
await E(node).setValue(JSON.stringify(aux));
|
|
67
|
-
};
|
|
68
|
-
|
|
69
49
|
const POOL_METRICS = 'poolMetrics';
|
|
70
50
|
|
|
71
51
|
/**
|
|
@@ -79,7 +59,7 @@ const POOL_METRICS = 'poolMetrics';
|
|
|
79
59
|
* }} FastUSDCCorePowers
|
|
80
60
|
*
|
|
81
61
|
* @typedef {StartedInstanceKitWithLabel & {
|
|
82
|
-
* creatorFacet:
|
|
62
|
+
* creatorFacet: StartedInstanceKit<FastUsdcSF>['creatorFacet'];
|
|
83
63
|
* privateArgs: StartParams<FastUsdcSF>['privateArgs'];
|
|
84
64
|
* }} FastUSDCKit
|
|
85
65
|
*/
|
|
@@ -245,10 +225,10 @@ export const getManifestForFastUSDC = (
|
|
|
245
225
|
board: true,
|
|
246
226
|
},
|
|
247
227
|
issuer: {
|
|
248
|
-
produce: { FastLP: true },
|
|
228
|
+
produce: { FastLP: true },
|
|
249
229
|
},
|
|
250
230
|
brand: {
|
|
251
|
-
produce: { FastLP: true },
|
|
231
|
+
produce: { FastLP: true },
|
|
252
232
|
},
|
|
253
233
|
instance: {
|
|
254
234
|
produce: { fastUsdc: true },
|
package/src/type-guards.js
CHANGED
|
@@ -34,7 +34,11 @@ export const makeProposalShapes = ({ PoolShares, USDC }) => {
|
|
|
34
34
|
give: { PoolShare: makeNatAmountShape(PoolShares, 1n) },
|
|
35
35
|
want: { USDC: makeNatAmountShape(USDC, 1n) },
|
|
36
36
|
});
|
|
37
|
-
|
|
37
|
+
/** @type {TypedPattern<USDCProposalShapes['withdrawFees']>} */
|
|
38
|
+
const withdrawFees = M.splitRecord({
|
|
39
|
+
want: { USDC: makeNatAmountShape(USDC, 1n) },
|
|
40
|
+
});
|
|
41
|
+
return harden({ deposit, withdraw, withdrawFees });
|
|
38
42
|
};
|
|
39
43
|
|
|
40
44
|
/** @type {TypedPattern<FastUsdcTerms>} */
|
package/src/utils/core-eval.js
CHANGED
|
@@ -6,9 +6,7 @@ import { makeMarshal } from '@endo/marshal';
|
|
|
6
6
|
const trace = makeTracer('FUCoreEval');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* @import {
|
|
10
|
-
* @import {Passable} from '@endo/pass-style'
|
|
11
|
-
* @import {BootstrapManifest} from '@agoric/vats/src/core/lib-boot.js'
|
|
9
|
+
* @import {Brand, DepositFacet} from '@agoric/ertp';
|
|
12
10
|
* @import {FastUSDCKit} from '../start-fast-usdc.core.js'
|
|
13
11
|
* @import {FeedPolicy} from '../types.js'
|
|
14
12
|
*/
|
|
@@ -54,3 +52,22 @@ export const inviteOracles = async (
|
|
|
54
52
|
}),
|
|
55
53
|
);
|
|
56
54
|
};
|
|
55
|
+
|
|
56
|
+
const BOARD_AUX = 'boardAux';
|
|
57
|
+
/**
|
|
58
|
+
* @param {Brand} brand
|
|
59
|
+
* @param {Pick<BootstrapPowers['consume'], 'board' | 'chainStorage'>} powers
|
|
60
|
+
*/
|
|
61
|
+
export const publishDisplayInfo = async (brand, { board, chainStorage }) => {
|
|
62
|
+
// chainStorage type includes undefined, which doesn't apply here.
|
|
63
|
+
// @ts-expect-error UNTIL https://github.com/Agoric/agoric-sdk/issues/8247
|
|
64
|
+
const boardAux = E(chainStorage).makeChildNode(BOARD_AUX);
|
|
65
|
+
const [id, displayInfo, allegedName] = await Promise.all([
|
|
66
|
+
E(board).getId(brand),
|
|
67
|
+
E(brand).getDisplayInfo(),
|
|
68
|
+
E(brand).getAllegedName(),
|
|
69
|
+
]);
|
|
70
|
+
const node = E(boardAux).makeChildNode(id);
|
|
71
|
+
const aux = marshalData.toCapData(harden({ allegedName, displayInfo }));
|
|
72
|
+
await E(node).setValue(JSON.stringify(aux));
|
|
73
|
+
};
|