@agoric/inter-protocol 0.16.1-dev-590740f.0 → 0.16.1-dev-69236fd.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 +1 -1
- package/bundles/bundle-auctioneer-js-meta.json +116 -116
- package/bundles/bundle-auctioneer.js +1 -1
- package/bundles/bundle-econCommitteeCharter-js-meta.json +71 -71
- package/bundles/bundle-feeDistributor-js-meta.json +57 -57
- package/bundles/bundle-fluxAggregatorKit-js-meta.json +118 -118
- package/bundles/bundle-psm-js-meta.json +109 -109
- package/bundles/bundle-reserve-js-meta.json +108 -108
- package/bundles/bundle-scaledPriceAuthority-js-meta.json +83 -83
- package/bundles/bundle-vaultFactory-js-meta.json +133 -133
- package/bundles/bundle-vaultFactory.js +1 -1
- package/package.json +18 -17
- package/scripts/add-STARS.js +43 -0
- package/scripts/add-collateral-core.js +2 -2
- package/src/interest-math.js +13 -13
- package/src/interest.js +24 -24
- package/src/proposals/addAssetToVault.js +19 -7
- package/src/proposals/price-feed-proposal.js +29 -14
- package/src/vaultFactory/params.js +4 -4
- package/src/vaultFactory/storeUtils.js +11 -7
- package/src/vaultFactory/types.js +4 -4
- package/src/vaultFactory/vault.js +18 -13
- package/src/vaultFactory/vaultDirector.js +2 -0
- package/src/vaultFactory/vaultManager.js +47 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/inter-protocol",
|
|
3
|
-
"version": "0.16.1-dev-
|
|
3
|
+
"version": "0.16.1-dev-69236fd.0+69236fd",
|
|
4
4
|
"description": "Core cryptoeconomy contracts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "yarn build:bundles",
|
|
12
12
|
"build:bundles": "node ./scripts/build-bundles.js",
|
|
13
|
+
"build:add-STARS-proposal": "agoric run scripts/add-STARS.js",
|
|
13
14
|
"test": "ava",
|
|
14
15
|
"test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
|
|
15
16
|
"test:xs": "exit 0",
|
|
@@ -29,29 +30,29 @@
|
|
|
29
30
|
},
|
|
30
31
|
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@agoric/assert": "0.6.1-dev-
|
|
33
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
34
|
-
"@agoric/governance": "0.10.3-dev-
|
|
35
|
-
"@agoric/internal": "0.3.3-dev-
|
|
36
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
37
|
-
"@agoric/store": "0.9.3-dev-
|
|
38
|
-
"@agoric/time": "0.3.3-dev-
|
|
39
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
40
|
-
"@agoric/vats": "0.15.1-dev-
|
|
41
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
33
|
+
"@agoric/assert": "0.6.1-dev-69236fd.0+69236fd",
|
|
34
|
+
"@agoric/ertp": "0.16.3-dev-69236fd.0+69236fd",
|
|
35
|
+
"@agoric/governance": "0.10.3-dev-69236fd.0+69236fd",
|
|
36
|
+
"@agoric/internal": "0.3.3-dev-69236fd.0+69236fd",
|
|
37
|
+
"@agoric/notifier": "0.6.3-dev-69236fd.0+69236fd",
|
|
38
|
+
"@agoric/store": "0.9.3-dev-69236fd.0+69236fd",
|
|
39
|
+
"@agoric/time": "0.3.3-dev-69236fd.0+69236fd",
|
|
40
|
+
"@agoric/vat-data": "0.5.3-dev-69236fd.0+69236fd",
|
|
41
|
+
"@agoric/vats": "0.15.1-dev-69236fd.0+69236fd",
|
|
42
|
+
"@agoric/zoe": "0.26.3-dev-69236fd.0+69236fd",
|
|
42
43
|
"@endo/captp": "^3.1.1",
|
|
43
44
|
"@endo/eventual-send": "^0.17.2",
|
|
44
45
|
"@endo/far": "^0.2.18",
|
|
45
46
|
"@endo/marshal": "^0.8.5",
|
|
46
47
|
"@endo/nat": "^4.1.27",
|
|
47
|
-
"agoric": "0.21.1-dev-
|
|
48
|
+
"agoric": "0.21.1-dev-69236fd.0+69236fd",
|
|
48
49
|
"jessie.js": "^0.3.2"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"@agoric/deploy-script-support": "0.10.3-dev-
|
|
52
|
-
"@agoric/smart-wallet": "0.5.3-dev-
|
|
53
|
-
"@agoric/swingset-liveslots": "0.10.3-dev-
|
|
54
|
-
"@agoric/swingset-vat": "0.32.3-dev-
|
|
52
|
+
"@agoric/deploy-script-support": "0.10.3-dev-69236fd.0+69236fd",
|
|
53
|
+
"@agoric/smart-wallet": "0.5.3-dev-69236fd.0+69236fd",
|
|
54
|
+
"@agoric/swingset-liveslots": "0.10.3-dev-69236fd.0+69236fd",
|
|
55
|
+
"@agoric/swingset-vat": "0.32.3-dev-69236fd.0+69236fd",
|
|
55
56
|
"@endo/bundle-source": "^2.5.1",
|
|
56
57
|
"@endo/init": "^0.5.56",
|
|
57
58
|
"@endo/promise-kit": "^0.2.56",
|
|
@@ -79,5 +80,5 @@
|
|
|
79
80
|
"publishConfig": {
|
|
80
81
|
"access": "public"
|
|
81
82
|
},
|
|
82
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "69236fdbdce1521dd78da104bd54f331d4d2b28f"
|
|
83
84
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { makeHelpers } from '@agoric/deploy-script-support';
|
|
2
|
+
import { defaultProposalBuilder as vaultProposalBuilder } from './add-collateral-core.js';
|
|
3
|
+
import { defaultProposalBuilder as oraclesProposalBuilder } from './price-feed-core.js';
|
|
4
|
+
|
|
5
|
+
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
|
|
6
|
+
export const starsVaultProposalBuilder = async powers => {
|
|
7
|
+
return vaultProposalBuilder(powers, {
|
|
8
|
+
interchainAssetOptions: {
|
|
9
|
+
// Values for the Stargaze token on Osmosis
|
|
10
|
+
denom:
|
|
11
|
+
'ibc/987C17B11ABC2B20019178ACE62929FE9840202CE79498E29FE8E5CB02B7C0A4',
|
|
12
|
+
decimalPlaces: 6,
|
|
13
|
+
keyword: 'STARS',
|
|
14
|
+
oracleBrand: 'STARS',
|
|
15
|
+
proposedName: 'STARS',
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
|
|
21
|
+
export const starsOraclesProposalBuilder = async powers => {
|
|
22
|
+
return oraclesProposalBuilder(powers, {
|
|
23
|
+
AGORIC_INSTANCE_NAME: `STARS-USD price feed`,
|
|
24
|
+
IN_BRAND_LOOKUP: ['agoricNames', 'oracleBrand', 'STARS'],
|
|
25
|
+
IN_BRAND_DECIMALS: 6,
|
|
26
|
+
OUT_BRAND_LOOKUP: ['agoricNames', 'oracleBrand', 'USD'],
|
|
27
|
+
OUT_BRAND_DECIMALS: 4,
|
|
28
|
+
oracleAddresses: [
|
|
29
|
+
// copied from decentral-main-vaults-config.json
|
|
30
|
+
'agoric1krunjcqfrf7la48zrvdfeeqtls5r00ep68mzkr',
|
|
31
|
+
'agoric19uscwxdac6cf6z7d5e26e0jm0lgwstc47cpll8',
|
|
32
|
+
'agoric144rrhh4m09mh7aaffhm6xy223ym76gve2x7y78',
|
|
33
|
+
'agoric19d6gnr9fyp6hev4tlrg87zjrzsd5gzr5qlfq2p',
|
|
34
|
+
'agoric1n4fcxsnkxe4gj6e24naec99hzmc4pjfdccy5nj',
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default async (homeP, endowments) => {
|
|
40
|
+
const { writeCoreProposal } = await makeHelpers(homeP, endowments);
|
|
41
|
+
await writeCoreProposal('add-STARS', starsVaultProposalBuilder);
|
|
42
|
+
await writeCoreProposal('add-STARS-oracles', starsOraclesProposalBuilder);
|
|
43
|
+
};
|
|
@@ -10,7 +10,7 @@ export const defaultProposalBuilder = async (
|
|
|
10
10
|
{ publishRef, install: install0, wrapInstall },
|
|
11
11
|
{
|
|
12
12
|
debtLimitValue = undefined,
|
|
13
|
-
|
|
13
|
+
stabilityFeeValue = undefined,
|
|
14
14
|
interchainAssetOptions = /** @type {object} */ ({}),
|
|
15
15
|
} = {},
|
|
16
16
|
{ env = process.env } = {},
|
|
@@ -38,7 +38,7 @@ export const defaultProposalBuilder = async (
|
|
|
38
38
|
getManifestForAddAssetToVault.name,
|
|
39
39
|
{
|
|
40
40
|
debtLimitValue: debtLimitValue && BigInt(debtLimitValue),
|
|
41
|
-
|
|
41
|
+
stabilityFeeValue: stabilityFeeValue && BigInt(stabilityFeeValue),
|
|
42
42
|
interchainAssetOptions: {
|
|
43
43
|
denom,
|
|
44
44
|
issuerBoardId,
|
package/src/interest-math.js
CHANGED
|
@@ -9,39 +9,39 @@ import {
|
|
|
9
9
|
} from '@agoric/zoe/src/contractSupport/ratio.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* @param {Ratio}
|
|
13
|
-
* @param {Ratio}
|
|
12
|
+
* @param {Ratio} currentCompoundedStabilityFee as coefficient
|
|
13
|
+
* @param {Ratio} previousCompoundedStabilityFee as coefficient
|
|
14
14
|
* @returns {Ratio} additional compounding since the previous
|
|
15
15
|
*/
|
|
16
16
|
const calculateRelativeCompounding = (
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
currentCompoundedStabilityFee,
|
|
18
|
+
previousCompoundedStabilityFee,
|
|
19
19
|
) => {
|
|
20
20
|
// divide compounded interest by the snapshot
|
|
21
21
|
return multiplyRatios(
|
|
22
|
-
|
|
23
|
-
invertRatio(
|
|
22
|
+
currentCompoundedStabilityFee,
|
|
23
|
+
invertRatio(previousCompoundedStabilityFee),
|
|
24
24
|
);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* @param {Amount<'nat'>} debtSnapshot
|
|
29
|
-
* @param {Ratio}
|
|
30
|
-
* @param {Ratio}
|
|
29
|
+
* @param {Ratio} stabilityFeeSnapshot as coefficient
|
|
30
|
+
* @param {Ratio} currentCompoundedStabilityFee as coefficient
|
|
31
31
|
* @returns {Amount<'nat'>}
|
|
32
32
|
*/
|
|
33
33
|
export const calculateCurrentDebt = (
|
|
34
34
|
debtSnapshot,
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
stabilityFeeSnapshot,
|
|
36
|
+
currentCompoundedStabilityFee,
|
|
37
37
|
) => {
|
|
38
|
-
if (ratiosSame(
|
|
38
|
+
if (ratiosSame(stabilityFeeSnapshot, currentCompoundedStabilityFee)) {
|
|
39
39
|
return debtSnapshot;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
const interestSinceSnapshot = calculateRelativeCompounding(
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
currentCompoundedStabilityFee,
|
|
44
|
+
stabilityFeeSnapshot,
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
return multiplyBy(debtSnapshot, interestSinceSnapshot);
|
package/src/interest.js
CHANGED
|
@@ -57,8 +57,8 @@ export const makeInterestCalculator = (
|
|
|
57
57
|
* @type {Calculate}
|
|
58
58
|
*/
|
|
59
59
|
const calculate = (debtStatus, currentTime) => {
|
|
60
|
-
const { newDebt,
|
|
61
|
-
let newRecent =
|
|
60
|
+
const { newDebt, latestStabilityFeeUpdate } = debtStatus;
|
|
61
|
+
let newRecent = latestStabilityFeeUpdate;
|
|
62
62
|
let growingInterest = debtStatus.interest;
|
|
63
63
|
let growingDebt = newDebt;
|
|
64
64
|
while (
|
|
@@ -78,7 +78,7 @@ export const makeInterestCalculator = (
|
|
|
78
78
|
growingDebt += newInterest;
|
|
79
79
|
}
|
|
80
80
|
return {
|
|
81
|
-
|
|
81
|
+
latestStabilityFeeUpdate: newRecent,
|
|
82
82
|
interest: growingInterest,
|
|
83
83
|
newDebt: growingDebt,
|
|
84
84
|
};
|
|
@@ -93,9 +93,9 @@ export const makeInterestCalculator = (
|
|
|
93
93
|
* @type {Calculate}
|
|
94
94
|
*/
|
|
95
95
|
const calculateReportingPeriod = (debtStatus, currentTime) => {
|
|
96
|
-
const {
|
|
96
|
+
const { latestStabilityFeeUpdate } = debtStatus;
|
|
97
97
|
const overshoot = TimeMath.modRelRel(
|
|
98
|
-
TimeMath.subtractAbsAbs(currentTime,
|
|
98
|
+
TimeMath.subtractAbsAbs(currentTime, latestStabilityFeeUpdate),
|
|
99
99
|
recordingPeriod,
|
|
100
100
|
);
|
|
101
101
|
return calculate(
|
|
@@ -111,20 +111,20 @@ export const makeInterestCalculator = (
|
|
|
111
111
|
};
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
114
|
+
* compoundedStabilityFee *= (new debt) / (prior total debt)
|
|
115
115
|
*
|
|
116
|
-
* @param {Ratio}
|
|
116
|
+
* @param {Ratio} priorCompoundedStabilityFee
|
|
117
117
|
* @param {NatValue} priorDebt
|
|
118
118
|
* @param {NatValue} newDebt
|
|
119
119
|
*/
|
|
120
|
-
export const
|
|
121
|
-
|
|
120
|
+
export const calculateCompoundedStabilityFee = (
|
|
121
|
+
priorCompoundedStabilityFee,
|
|
122
122
|
priorDebt,
|
|
123
123
|
newDebt,
|
|
124
124
|
) => {
|
|
125
|
-
const brand =
|
|
125
|
+
const brand = priorCompoundedStabilityFee.numerator.brand;
|
|
126
126
|
const compounded = multiplyRatios(
|
|
127
|
-
|
|
127
|
+
priorCompoundedStabilityFee,
|
|
128
128
|
makeRatio(newDebt, brand, priorDebt, brand),
|
|
129
129
|
);
|
|
130
130
|
return quantize(compounded, COMPOUNDED_INTEREST_DENOMINATOR);
|
|
@@ -144,7 +144,7 @@ const validatedBrand = (mint, debt) => {
|
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
/**
|
|
147
|
-
* Charge interest accrued between `
|
|
147
|
+
* Charge interest accrued between `latestStabilityFeeUpdate` and `accruedUntil`.
|
|
148
148
|
*
|
|
149
149
|
* @param {{
|
|
150
150
|
* mint: ZCFMint<'nat'>,
|
|
@@ -152,21 +152,21 @@ const validatedBrand = (mint, debt) => {
|
|
|
152
152
|
* poolIncrementSeat: ZCFSeat,
|
|
153
153
|
* seatAllocationKeyword: Keyword }} powers
|
|
154
154
|
* @param {{
|
|
155
|
-
*
|
|
155
|
+
* stabilityFee: Ratio,
|
|
156
156
|
* chargingPeriod: RelativeTime,
|
|
157
157
|
* recordingPeriod: RelativeTime}} params
|
|
158
158
|
* @param {{
|
|
159
|
-
*
|
|
160
|
-
*
|
|
159
|
+
* latestStabilityFeeUpdate: Timestamp,
|
|
160
|
+
* compoundedStabilityFee: Ratio,
|
|
161
161
|
* totalDebt: Amount<'nat'>}} prior
|
|
162
162
|
* @param {Timestamp} accruedUntil
|
|
163
|
-
* @returns {{
|
|
163
|
+
* @returns {{compoundedStabilityFee: Ratio, latestStabilityFeeUpdate: Timestamp, totalDebt: Amount<'nat'> }}
|
|
164
164
|
*/
|
|
165
165
|
export const chargeInterest = (powers, params, prior, accruedUntil) => {
|
|
166
166
|
const brand = validatedBrand(powers.mint, prior.totalDebt);
|
|
167
167
|
|
|
168
168
|
const interestCalculator = makeInterestCalculator(
|
|
169
|
-
params.
|
|
169
|
+
params.stabilityFee,
|
|
170
170
|
params.chargingPeriod,
|
|
171
171
|
params.recordingPeriod,
|
|
172
172
|
);
|
|
@@ -174,7 +174,7 @@ export const chargeInterest = (powers, params, prior, accruedUntil) => {
|
|
|
174
174
|
// calculate delta of accrued debt
|
|
175
175
|
const debtStatus = interestCalculator.calculateReportingPeriod(
|
|
176
176
|
{
|
|
177
|
-
|
|
177
|
+
latestStabilityFeeUpdate: prior.latestStabilityFeeUpdate,
|
|
178
178
|
newDebt: prior.totalDebt.value,
|
|
179
179
|
interest: 0n, // XXX this is always zero, doesn't need to be an option
|
|
180
180
|
},
|
|
@@ -185,8 +185,8 @@ export const chargeInterest = (powers, params, prior, accruedUntil) => {
|
|
|
185
185
|
// done if none
|
|
186
186
|
if (interestAccrued === 0n) {
|
|
187
187
|
return {
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
compoundedStabilityFee: prior.compoundedStabilityFee,
|
|
189
|
+
latestStabilityFeeUpdate: debtStatus.latestStabilityFeeUpdate,
|
|
190
190
|
totalDebt: prior.totalDebt,
|
|
191
191
|
};
|
|
192
192
|
}
|
|
@@ -196,8 +196,8 @@ export const chargeInterest = (powers, params, prior, accruedUntil) => {
|
|
|
196
196
|
// testing with small numbers there's 5 digits of precision, and with large
|
|
197
197
|
// numbers the ratios tend towards ample precision.
|
|
198
198
|
// TODO adopt banker's rounding https://github.com/Agoric/agoric-sdk/issues/4573
|
|
199
|
-
const
|
|
200
|
-
prior.
|
|
199
|
+
const compoundedStabilityFee = calculateCompoundedStabilityFee(
|
|
200
|
+
prior.compoundedStabilityFee,
|
|
201
201
|
prior.totalDebt.value,
|
|
202
202
|
debtStatus.newDebt,
|
|
203
203
|
);
|
|
@@ -218,8 +218,8 @@ export const chargeInterest = (powers, params, prior, accruedUntil) => {
|
|
|
218
218
|
);
|
|
219
219
|
|
|
220
220
|
return {
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
compoundedStabilityFee,
|
|
222
|
+
latestStabilityFeeUpdate: debtStatus.latestStabilityFeeUpdate,
|
|
223
223
|
totalDebt,
|
|
224
224
|
};
|
|
225
225
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// @jessie-check
|
|
2
2
|
|
|
3
3
|
import { AmountMath, AssetKind } from '@agoric/ertp';
|
|
4
|
-
import { makeRatio } from '@agoric/zoe/src/contractSupport/index.js';
|
|
5
4
|
import { deeplyFulfilledObject } from '@agoric/internal';
|
|
6
5
|
import { Stable } from '@agoric/vats/src/tokens.js';
|
|
7
|
-
import {
|
|
6
|
+
import { makeRatio } from '@agoric/zoe/src/contractSupport/index.js';
|
|
8
7
|
import { parseRatio } from '@agoric/zoe/src/contractSupport/ratio.js';
|
|
8
|
+
import { E } from '@endo/far';
|
|
9
|
+
import { instanceNameFor } from './price-feed-proposal.js';
|
|
9
10
|
import { reserveThenGetNames } from './utils.js';
|
|
10
11
|
|
|
11
12
|
export * from './startPSM.js';
|
|
@@ -211,7 +212,7 @@ export const registerScaledPriceAuthority = async (
|
|
|
211
212
|
* @param {object} config.options
|
|
212
213
|
* @param {InterchainAssetOptions} config.options.interchainAssetOptions
|
|
213
214
|
* @param {bigint | number | string} config.options.debtLimitValue
|
|
214
|
-
* @param {bigint} config.options.
|
|
215
|
+
* @param {bigint} config.options.stabilityFeeValue
|
|
215
216
|
*/
|
|
216
217
|
export const addAssetToVault = async (
|
|
217
218
|
{
|
|
@@ -219,6 +220,7 @@ export const addAssetToVault = async (
|
|
|
219
220
|
brand: {
|
|
220
221
|
consume: { [Stable.symbol]: stableP },
|
|
221
222
|
},
|
|
223
|
+
instance: { consume: consumeInstance },
|
|
222
224
|
},
|
|
223
225
|
{
|
|
224
226
|
options: {
|
|
@@ -226,7 +228,7 @@ export const addAssetToVault = async (
|
|
|
226
228
|
debtLimitValue = 1_000n * 1_000_000n,
|
|
227
229
|
// Default to a safe value. Production will likely set this through governance.
|
|
228
230
|
// Allow setting through bootstrap to simplify testing.
|
|
229
|
-
|
|
231
|
+
stabilityFeeValue = 1n,
|
|
230
232
|
interchainAssetOptions,
|
|
231
233
|
},
|
|
232
234
|
},
|
|
@@ -239,11 +241,16 @@ export const addAssetToVault = async (
|
|
|
239
241
|
[keyword],
|
|
240
242
|
);
|
|
241
243
|
|
|
244
|
+
const oracleInstanceName = instanceNameFor(oracleBrand, 'USD');
|
|
245
|
+
// don't add the collateral offering to vaultFactory until its price feed is available
|
|
246
|
+
// eslint-disable-next-line no-restricted-syntax -- allow this computed property
|
|
247
|
+
await consumeInstance[oracleInstanceName];
|
|
248
|
+
|
|
242
249
|
const stable = await stableP;
|
|
243
250
|
const vaultFactoryCreator = E.get(vaultFactoryKit).creatorFacet;
|
|
244
251
|
await E(vaultFactoryCreator).addVaultType(interchainIssuer, oracleBrand, {
|
|
245
252
|
debtLimit: AmountMath.make(stable, BigInt(debtLimitValue)),
|
|
246
|
-
|
|
253
|
+
stabilityFee: makeRatio(stabilityFeeValue, stable),
|
|
247
254
|
// The rest of these we use safe defaults.
|
|
248
255
|
// In production they will be governed by the Econ Committee.
|
|
249
256
|
// Product deployments are also expected to have a low debtLimitValue at the outset,
|
|
@@ -261,7 +268,7 @@ export const getManifestForAddAssetToVault = (
|
|
|
261
268
|
{ restoreRef },
|
|
262
269
|
{
|
|
263
270
|
debtLimitValue,
|
|
264
|
-
|
|
271
|
+
stabilityFeeValue,
|
|
265
272
|
interchainAssetOptions,
|
|
266
273
|
scaledPriceAuthorityRef,
|
|
267
274
|
},
|
|
@@ -321,6 +328,11 @@ export const getManifestForAddAssetToVault = (
|
|
|
321
328
|
brand: {
|
|
322
329
|
consume: { [Stable.symbol]: true },
|
|
323
330
|
},
|
|
331
|
+
instance: {
|
|
332
|
+
// allow any instance because the AGORIC_INSTANCE_NAME of
|
|
333
|
+
// priceFeedOptions cannot be known statically.
|
|
334
|
+
consume: true,
|
|
335
|
+
},
|
|
324
336
|
},
|
|
325
337
|
},
|
|
326
338
|
installations: {
|
|
@@ -329,7 +341,7 @@ export const getManifestForAddAssetToVault = (
|
|
|
329
341
|
options: {
|
|
330
342
|
debtLimitValue,
|
|
331
343
|
interchainAssetOptions,
|
|
332
|
-
|
|
344
|
+
stabilityFeeValue,
|
|
333
345
|
},
|
|
334
346
|
};
|
|
335
347
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// @ts-nocheck -- lots of type errors. low prio b/c proposals are like scripts
|
|
2
|
-
import {
|
|
2
|
+
import { makeTracer } from '@agoric/internal';
|
|
3
3
|
import {
|
|
4
|
-
makeStorageNodeChild,
|
|
5
4
|
assertPathSegment,
|
|
5
|
+
makeStorageNodeChild,
|
|
6
6
|
} from '@agoric/internal/src/lib-chainStorage.js';
|
|
7
|
-
import {
|
|
7
|
+
import { E } from '@endo/far';
|
|
8
8
|
|
|
9
9
|
import { unitAmount } from '@agoric/zoe/src/contractSupport/priceQuote.js';
|
|
10
10
|
import { reserveThenDeposit, reserveThenGetNames } from './utils.js';
|
|
@@ -18,6 +18,9 @@ const sanitizePathSegment = name => {
|
|
|
18
18
|
return candidate;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
export const instanceNameFor = (inBrandName, outBrandName) =>
|
|
22
|
+
`${inBrandName}-${outBrandName} price feed`;
|
|
23
|
+
|
|
21
24
|
/**
|
|
22
25
|
* @typedef {{
|
|
23
26
|
* brandIn?: ERef<Brand<'nat'> | undefined>,
|
|
@@ -95,6 +98,7 @@ export const createPriceFeed = async (
|
|
|
95
98
|
priceAuthorityAdmin,
|
|
96
99
|
startGovernedUpgradable,
|
|
97
100
|
},
|
|
101
|
+
instance: { produce: produceInstance },
|
|
98
102
|
},
|
|
99
103
|
{
|
|
100
104
|
options: {
|
|
@@ -160,11 +164,27 @@ export const createPriceFeed = async (
|
|
|
160
164
|
installation: priceAggregator,
|
|
161
165
|
});
|
|
162
166
|
|
|
163
|
-
|
|
167
|
+
// Publish price feed in home.priceAuthority.
|
|
168
|
+
const forceReplace = true;
|
|
169
|
+
// Make sure this PA is registered before sharing the instance in agoricNames,
|
|
170
|
+
// which allows contracts that depend on the registry value to wait for it and
|
|
171
|
+
// prevent a race.
|
|
172
|
+
await E(priceAuthorityAdmin).registerPriceAuthority(
|
|
173
|
+
E(faKit.publicFacet).getPriceAuthority(),
|
|
174
|
+
brandIn,
|
|
175
|
+
brandOut,
|
|
176
|
+
forceReplace,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
await E(E(agoricNamesAdmin).lookupAdmin('instance'))
|
|
164
180
|
.update(AGORIC_INSTANCE_NAME, faKit.instance)
|
|
165
181
|
.catch(err =>
|
|
166
182
|
console.error(`🚨 failed to update ${AGORIC_INSTANCE_NAME}`, err),
|
|
167
183
|
);
|
|
184
|
+
// being after the above awaits means that when this resolves, the consumer
|
|
185
|
+
// gets notified that the authority is in the registry and its instance is in
|
|
186
|
+
// agoricNames.
|
|
187
|
+
produceInstance[AGORIC_INSTANCE_NAME].resolve(faKit.instance);
|
|
168
188
|
|
|
169
189
|
E(E.get(econCharterKit).creatorFacet).addInstance(
|
|
170
190
|
faKit.instance,
|
|
@@ -173,15 +193,6 @@ export const createPriceFeed = async (
|
|
|
173
193
|
);
|
|
174
194
|
trace('registered', AGORIC_INSTANCE_NAME, faKit.instance);
|
|
175
195
|
|
|
176
|
-
// Publish price feed in home.priceAuthority.
|
|
177
|
-
const forceReplace = true;
|
|
178
|
-
void E(priceAuthorityAdmin).registerPriceAuthority(
|
|
179
|
-
E(faKit.publicFacet).getPriceAuthority(),
|
|
180
|
-
brandIn,
|
|
181
|
-
brandOut,
|
|
182
|
-
forceReplace,
|
|
183
|
-
);
|
|
184
|
-
|
|
185
196
|
/**
|
|
186
197
|
* Initialize a new oracle and send an invitation to administer it.
|
|
187
198
|
*
|
|
@@ -231,6 +242,9 @@ export const getManifestForPriceFeed = async (
|
|
|
231
242
|
priceAuthorityAdmin: t,
|
|
232
243
|
startGovernedUpgradable: t,
|
|
233
244
|
},
|
|
245
|
+
instance: {
|
|
246
|
+
produce: t,
|
|
247
|
+
},
|
|
234
248
|
},
|
|
235
249
|
[ensureOracleBrands.name]: {
|
|
236
250
|
namedVat: {
|
|
@@ -242,6 +256,7 @@ export const getManifestForPriceFeed = async (
|
|
|
242
256
|
},
|
|
243
257
|
},
|
|
244
258
|
installations: {
|
|
259
|
+
// ??? will every eval of price-feed-proposal install priceAggregator ?
|
|
245
260
|
priceAggregator: restoreRef(priceFeedOptions.priceAggregatorRef),
|
|
246
261
|
},
|
|
247
262
|
options: {
|
|
@@ -302,7 +317,7 @@ export const startPriceFeeds = async (
|
|
|
302
317
|
{
|
|
303
318
|
options: {
|
|
304
319
|
priceFeedOptions: {
|
|
305
|
-
AGORIC_INSTANCE_NAME:
|
|
320
|
+
AGORIC_INSTANCE_NAME: instanceNameFor(inBrandName, outBrandName),
|
|
306
321
|
contractTerms: {
|
|
307
322
|
minSubmissionCount: 2,
|
|
308
323
|
minSubmissionValue: 1,
|
|
@@ -21,7 +21,7 @@ export const DEBT_LIMIT_KEY = 'DebtLimit';
|
|
|
21
21
|
export const LIQUIDATION_MARGIN_KEY = 'LiquidationMargin';
|
|
22
22
|
export const LIQUIDATION_PADDING_KEY = 'LiquidationPadding';
|
|
23
23
|
export const LIQUIDATION_PENALTY_KEY = 'LiquidationPenalty';
|
|
24
|
-
export const
|
|
24
|
+
export const STABILITY_FEE_KEY = 'StabilityFee';
|
|
25
25
|
export const MINT_FEE_KEY = 'MintFee';
|
|
26
26
|
export const MIN_INITIAL_DEBT_KEY = 'MinInitialDebt';
|
|
27
27
|
export const SHORTFALL_INVITATION_KEY = 'ShortfallInvitation';
|
|
@@ -89,7 +89,7 @@ export const makeVaultParamManager = (
|
|
|
89
89
|
publisherKit,
|
|
90
90
|
{
|
|
91
91
|
debtLimit,
|
|
92
|
-
|
|
92
|
+
stabilityFee,
|
|
93
93
|
liquidationMargin,
|
|
94
94
|
liquidationPadding = zeroRatio(liquidationMargin),
|
|
95
95
|
liquidationPenalty,
|
|
@@ -98,7 +98,7 @@ export const makeVaultParamManager = (
|
|
|
98
98
|
) =>
|
|
99
99
|
makeParamManagerSync(publisherKit, {
|
|
100
100
|
[DEBT_LIMIT_KEY]: [ParamTypes.AMOUNT, debtLimit],
|
|
101
|
-
[
|
|
101
|
+
[STABILITY_FEE_KEY]: [ParamTypes.RATIO, stabilityFee],
|
|
102
102
|
[LIQUIDATION_PADDING_KEY]: [ParamTypes.RATIO, liquidationPadding],
|
|
103
103
|
[LIQUIDATION_MARGIN_KEY]: [ParamTypes.RATIO, liquidationMargin],
|
|
104
104
|
[LIQUIDATION_PENALTY_KEY]: [ParamTypes.RATIO, liquidationPenalty],
|
|
@@ -110,7 +110,7 @@ export const vaultParamPattern = M.splitRecord(
|
|
|
110
110
|
{
|
|
111
111
|
liquidationMargin: ratioPattern,
|
|
112
112
|
liquidationPenalty: ratioPattern,
|
|
113
|
-
|
|
113
|
+
stabilityFee: ratioPattern,
|
|
114
114
|
mintFee: ratioPattern,
|
|
115
115
|
debtLimit: amountPattern,
|
|
116
116
|
},
|
|
@@ -131,15 +131,15 @@ harden(fromVaultKey);
|
|
|
131
131
|
* For use by `normalizedCollRatioKey` and tests.
|
|
132
132
|
*
|
|
133
133
|
* @param {PriceQuote} quote
|
|
134
|
-
* @param {Ratio}
|
|
134
|
+
* @param {Ratio} compoundedStabilityFee
|
|
135
135
|
* @param {Ratio} margin
|
|
136
136
|
* @returns {number}
|
|
137
137
|
*/
|
|
138
|
-
export const normalizedCollRatio = (quote,
|
|
138
|
+
export const normalizedCollRatio = (quote, compoundedStabilityFee, margin) => {
|
|
139
139
|
const amountIn = getAmountIn(quote).value;
|
|
140
140
|
const amountOut = getAmountOut(quote).value;
|
|
141
|
-
const interestNumerator =
|
|
142
|
-
const interestBase =
|
|
141
|
+
const interestNumerator = compoundedStabilityFee.numerator.value;
|
|
142
|
+
const interestBase = compoundedStabilityFee.denominator.value;
|
|
143
143
|
const numerator = multiply(
|
|
144
144
|
margin.numerator.value,
|
|
145
145
|
multiply(amountIn, interestNumerator),
|
|
@@ -159,13 +159,17 @@ harden(normalizedCollRatio);
|
|
|
159
159
|
* out the numerator and the denominator, and divide only once.
|
|
160
160
|
*
|
|
161
161
|
* @param {PriceQuote} quote
|
|
162
|
-
* @param {Ratio}
|
|
162
|
+
* @param {Ratio} compoundedStabilityFee
|
|
163
163
|
* @param {Ratio} margin
|
|
164
164
|
* @returns {string} lexically sortable string in which highest
|
|
165
165
|
* debt-to-collateral is earliest
|
|
166
166
|
*/
|
|
167
|
-
export const normalizedCollRatioKey = (
|
|
168
|
-
|
|
167
|
+
export const normalizedCollRatioKey = (
|
|
168
|
+
quote,
|
|
169
|
+
compoundedStabilityFee,
|
|
170
|
+
margin,
|
|
171
|
+
) => {
|
|
172
|
+
const collRatio = normalizedCollRatio(quote, compoundedStabilityFee, margin);
|
|
169
173
|
return `${encodeNumber(collRatio)}:`;
|
|
170
174
|
};
|
|
171
175
|
harden(normalizedCollRatioKey);
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* @property {Ratio} liquidationMargin - margin below which collateral will be
|
|
27
27
|
* liquidated to satisfy the debt.
|
|
28
28
|
* @property {Ratio} liquidationPenalty - penalty charged upon liquidation as proportion of debt
|
|
29
|
-
* @property {Ratio}
|
|
29
|
+
* @property {Ratio} stabilityFee - annual interest rate charged on debt positions
|
|
30
30
|
* @property {Ratio} mintFee - The fee (in BasisPoints) charged when creating
|
|
31
31
|
* or increasing a debt position.
|
|
32
32
|
* @property {Amount<'nat'>} debtLimit
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
* @property {() => Ratio} getLiquidationMargin
|
|
79
79
|
* @property {() => Ratio} getMintFee
|
|
80
80
|
* @property {() => Promise<PriceQuote>} getCollateralQuote
|
|
81
|
-
* @property {() => Ratio}
|
|
81
|
+
* @property {() => Ratio} getStabilityFee - The annual interest rate on a debt position
|
|
82
82
|
* @property {() => RelativeTime} getChargingPeriod - The period (in seconds) at
|
|
83
83
|
* which interest is charged to the debt position.
|
|
84
84
|
* @property {() => RelativeTime} getRecordingPeriod - The period (in seconds)
|
|
@@ -109,8 +109,8 @@
|
|
|
109
109
|
|
|
110
110
|
/**
|
|
111
111
|
* @typedef {object} DebtStatus
|
|
112
|
-
* @property {Timestamp}
|
|
113
|
-
* @property {NatValue} interest interest accrued since
|
|
112
|
+
* @property {Timestamp} latestStabilityFeeUpdate
|
|
113
|
+
* @property {NatValue} interest interest accrued since latestStabilityFeeUpdate
|
|
114
114
|
* @property {NatValue} newDebt total including principal and interest
|
|
115
115
|
*/
|
|
116
116
|
|