Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reinstate economy boot using minInitialPoolLiquidity=0 #5441

Merged
merged 8 commits into from
May 26, 2022
9 changes: 6 additions & 3 deletions packages/cosmic-swingset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,12 @@ scenario2-setup-nobuild:
mv t1/n0/config/genesis2.json t1/n0/config/genesis.json
$(MAKE) set-local-gci-ingress

scenario2-run-chain-economy:
t1/decentral-economy-config.json: $(ECONOMY_PROPOSALS)
jq -s '.[0] * { coreProposals: .[1] }' \
../vats/decentral-core-config.json \
'$(ECONOMY_PROPOSALS)' > t1/decentral-economy-config.json

scenario2-run-chain-economy: t1/decentral-economy-config.json
CHAIN_BOOTSTRAP_VAT_CONFIG="$$PWD/t1/decentral-economy-config.json" \
OTEL_EXPORTER_PROMETHEUS_PORT=$(OTEL_EXPORTER_PROMETHEUS_PORT) \
$(AGC) --home=t1/n0 start --log_level=warn $(AGC_START_ARGS)
Expand All @@ -150,8 +152,9 @@ scenario2-run-chain:
$(AGC) --home=t1/n0 start --log_level=warn $(AGC_START_ARGS)

# Run a chain with an explicit halt.
scenario2-run-chain-to-halt:
$(AGC) --home=t1/n0 start --log_level=warn --halt-height=$$(($(INITIAL_HEIGHT) + 3)); \
scenario2-run-chain-to-halt: t1/decentral-economy-config.json
CHAIN_BOOTSTRAP_VAT_CONFIG="$$PWD/t1/decentral-economy-config.json" \
$(AGC) --home=t1/n0 start --log_level=warn --halt-height=$$(($(INITIAL_HEIGHT) + 3)); \
test "$$?" -eq 98

# Blow away all client state to try again without resetting the chain.
Expand Down
3 changes: 2 additions & 1 deletion packages/cosmic-swingset/economy-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
{
"econCommitteeOptions": {
"committeeSize": 1
}
},
"minInitialPoolLiquidity": "0"
}
]
},
Expand Down
7 changes: 5 additions & 2 deletions packages/run-protocol/scripts/add-collateral-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { getManifestForAddAssetToVault } from '../src/proposals/addAssetToVault.
import { getManifestForPsm } from '../src/proposals/startPSM.js';
import { makeInstallCache } from '../src/proposals/utils.js';

// Build proposal for sim-chain etc.
export const defaultProposalBuilder = async (
{ publishRef, install: install0, wrapInstall },
{ interchainAssetOptions = /** @type {object} */ ({}) } = {},
Expand All @@ -15,13 +14,16 @@ export const defaultProposalBuilder = async (
/** @type {import('../src/proposals/addAssetToVault.js').InterchainAssetOptions} */
const {
issuerBoardId = env.INTERCHAIN_ISSUER_BOARD_ID,
denom = env.INTERCHAIN_DENOM,
oracleBrand = 'ATOM',
decimalPlaces = 6,
keyword = 'IbcATOM',
proposedName = oracleBrand,
} = interchainAssetOptions;

assert(issuerBoardId, 'INTERCHAIN_ISSUER_BOARD_ID is required');
if (!denom) {
assert(issuerBoardId, 'INTERCHAIN_ISSUER_BOARD_ID is required');
}

const install = wrapInstall ? wrapInstall(install0) : install0;

Expand All @@ -31,6 +33,7 @@ export const defaultProposalBuilder = async (
getManifestForAddAssetToVault.name,
{
interchainAssetOptions: {
denom,
issuerBoardId,
decimalPlaces,
keyword,
Expand Down
13 changes: 9 additions & 4 deletions packages/run-protocol/scripts/init-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,22 @@ export const mainProposalBuilder = async ({
export const defaultProposalBuilder = async (
{ publishRef, install },
options = {},
{ env = process.env } = {},
) => {
/** @param {string|undefined} s */
const optBigInt = s => s && BigInt(s);
const {
ROLE = process.env.ROLE || 'chain',
vaultFactoryControllerAddress = process.env.VAULT_FACTORY_CONTROLLER_ADDR,
ROLE = env.ROLE || 'chain',
vaultFactoryControllerAddress = env.VAULT_FACTORY_CONTROLLER_ADDR,
minInitialPoolLiquidity = env.MIN_INITIAL_POOL_LIQUIDITY,
anchorOptions: {
anchorDenom = process.env.ANCHOR_DENOM,
anchorDenom = env.ANCHOR_DENOM,
anchorDecimalPlaces = '6',
anchorKeyword = 'AUSD',
anchorProposedName = anchorKeyword,
} = {},
econCommitteeOptions: {
committeeSize: econCommitteeSize = process.env.ECON_COMMITTEE_SIZE || '3',
committeeSize: econCommitteeSize = env.ECON_COMMITTEE_SIZE || '3',
} = {},
} = options;

Expand All @@ -180,6 +184,7 @@ export const defaultProposalBuilder = async (
{
ROLE,
vaultFactoryControllerAddress,
minInitialPoolLiquidity: optBigInt(minInitialPoolLiquidity),
anchorOptions,
econCommitteeOptions,
installKeys: {
Expand Down
168 changes: 150 additions & 18 deletions packages/run-protocol/src/proposals/addAssetToVault.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @ts-check
import { AmountMath } from '@agoric/ertp';
import { AmountMath, AssetKind } from '@agoric/ertp';
import { makeRatio } from '@agoric/zoe/src/contractSupport/index.js';
import { E } from '@endo/far';

Expand All @@ -9,10 +9,11 @@ export * from './startPSM.js';

/**
* @typedef {object} InterchainAssetOptions
* @property {string} issuerBoardId
* @property {string} [issuerBoardId]
* @property {string} [denom]
* @property {number} [decimalPlaces]
* @property {string} [proposedName]
* @property {string} keyword
* @property {string} proposedName
* @property {number} decimalPlaces
* @property {string} oracleBrand
*/

Expand All @@ -22,22 +23,130 @@ export * from './startPSM.js';
* @param {object} config.options
* @param {InterchainAssetOptions} config.options.interchainAssetOptions
*/
export const addInterchainAsset = async (
export const publishInterchainAssetFromBoardId = async (
{ consume: { board, agoricNamesAdmin } },
{ options: { interchainAssetOptions } },
) => {
const { issuerBoardId, keyword, decimalPlaces, proposedName } =
interchainAssetOptions;
const { issuerBoardId, keyword } = interchainAssetOptions;
// Incompatible with denom.
assert.equal(interchainAssetOptions.denom, undefined);
assert.typeof(issuerBoardId, 'string');
assert.typeof(keyword, 'string');
assert.typeof(decimalPlaces, 'number');
assert.typeof(proposedName, 'string');

const issuer = await E(board).getValue(issuerBoardId);
const brand = await E(issuer).getBrand();

E(E(agoricNamesAdmin).lookupAdmin('issuer')).update(keyword, issuer);
E(E(agoricNamesAdmin).lookupAdmin('brand')).update(keyword, brand);
return Promise.all([
E(E(agoricNamesAdmin).lookupAdmin('issuer')).update(keyword, issuer),
E(E(agoricNamesAdmin).lookupAdmin('brand')).update(keyword, brand),
]);
};

const addPool = async (
zoe,
amm,
issuer,
keyword,
brand,
runBrand,
runIssuer,
) => {
const ammPub = E(zoe).getPublicFacet(amm);
const [addPoolInvitation] = await Promise.all([
E(ammPub).addPoolInvitation(),
E(ammPub).addIssuer(issuer, keyword),
]);
const proposal = harden({
give: {
Secondary: AmountMath.makeEmpty(brand),
Central: AmountMath.makeEmpty(runBrand),
},
});
const centralPurse = E(runIssuer).makeEmptyPurse();
const secondaryPurse = E(issuer).makeEmptyPurse();
const [emptyCentral, emptySecondary] = await Promise.all([
E(centralPurse).withdraw(proposal.give.Central),
E(secondaryPurse).withdraw(proposal.give.Secondary),
]);
const payments = harden({
Central: emptyCentral,
Secondary: emptySecondary,
});
const addLiquiditySeat = await E(zoe).offer(
addPoolInvitation,
proposal,
payments,
);
await E(addLiquiditySeat).getOfferResult();
};

/**
* @param { EconomyBootstrapPowers } powers
* @param {object} config
* @param {object} config.options
* @param {InterchainAssetOptions} config.options.interchainAssetOptions
*/
export const publishInterchainAssetFromBank = async (
{
consume: { zoe, bankManager, agoricNamesAdmin, bankMints },
produce: { bankMints: produceBankMints },
installation: {
consume: { mintHolder },
},
instance: {
consume: { amm },
},
issuer: {
consume: { RUN: runIssuer },
},
brand: {
consume: { RUN: runBrandP },
},
},
{ options: { interchainAssetOptions } },
) => {
const { denom, decimalPlaces, proposedName, keyword } =
interchainAssetOptions;

// Incompatible with issuerBoardId.
assert.equal(interchainAssetOptions.issuerBoardId, undefined);
assert.typeof(denom, 'string');
assert.typeof(keyword, 'string');
assert.typeof(decimalPlaces, 'number');
assert.typeof(proposedName, 'string');

/** @type {import('@agoric/vats/src/mintHolder.js').AssetTerms} */
const terms = {
keyword,
assetKind: AssetKind.NAT,
displayInfo: {
decimalPlaces,
assetKind: AssetKind.NAT,
},
};
const { creatorFacet: mint, publicFacet: issuer } = E.get(
E(zoe).startInstance(mintHolder, {}, terms),
);

const [brand, runBrand] = await Promise.all([
E(issuer).getBrand(),
runBrandP,
]);
const kit = { mint, issuer, brand };

await addPool(zoe, amm, issuer, keyword, brand, runBrand, runIssuer);

// Create the mint list if it doesn't exist and wasn't already rejected.
produceBankMints.resolve([]);
await Promise.all([
Promise.resolve(bankMints).then(
mints => mints.push(mint),
() => {}, // If the bankMints list was rejected, ignore the error.
),
E(E(agoricNamesAdmin).lookupAdmin('issuer')).update(keyword, issuer),
E(E(agoricNamesAdmin).lookupAdmin('brand')).update(keyword, brand),
E(bankManager).addAsset(denom, keyword, proposedName, kit),
]);
};

/**
Expand Down Expand Up @@ -159,16 +268,38 @@ export const getManifestForAddAssetToVault = (
{ restoreRef },
{ interchainAssetOptions, scaledPriceAuthorityRef },
) => {
const publishIssuerFromBoardId =
typeof interchainAssetOptions.issuerBoardId === 'string';
const publishIssuerFromBank =
!publishIssuerFromBoardId &&
typeof interchainAssetOptions.denom === 'string';
return {
manifest: {
[addInterchainAsset.name]: {
consume: {
board: true,
zoe: true,
bankManager: true,
agoricNamesAdmin: true,
...(publishIssuerFromBoardId && {
[publishInterchainAssetFromBoardId.name]: {
consume: {
board: true,
agoricNamesAdmin: true,
},
},
},
}),
...(publishIssuerFromBank && {
[publishInterchainAssetFromBank.name]: {
consume: {
zoe: true,
bankManager: true,
agoricNamesAdmin: true,
bankMints: true,
},
produce: { bankMints: true },
installation: {
consume: { mintHolder: true },
},
instance: { consume: { amm: 'amm' } },
issuer: { consume: { RUN: 'zoe' } },
brand: { consume: { RUN: 'zoe' } },
},
}),
[registerScaledPriceAuthority.name]: {
consume: {
agoricNamesAdmin: true,
Expand All @@ -183,6 +314,7 @@ export const getManifestForAddAssetToVault = (
[addAssetToVault.name]: {
consume: {
vaultFactoryCreator: true,
ammCreatorFacet: true,
reserveCreatorFacet: true,
agoricNamesAdmin: true,
},
Expand Down
5 changes: 4 additions & 1 deletion packages/run-protocol/src/proposals/core-proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export const getManifestForEconCommittee = (

export const getManifestForMain = (
{ restoreRef },
{ installKeys, vaultFactoryControllerAddress },
{ installKeys, vaultFactoryControllerAddress, minInitialPoolLiquidity },
) => {
return {
manifest: SHARED_MAIN_MANIFEST,
Expand All @@ -270,6 +270,7 @@ export const getManifestForMain = (
},
options: {
vaultFactoryControllerAddress,
minInitialPoolLiquidity,
},
};
};
Expand All @@ -290,6 +291,7 @@ export const getManifestForRunProtocol = (
econCommitteeOptions,
installKeys,
vaultFactoryControllerAddress,
minInitialPoolLiquidity,
},
) => {
const econCommitteeManifest = getManifestForEconCommittee(
Expand All @@ -301,6 +303,7 @@ export const getManifestForRunProtocol = (
{
installKeys,
vaultFactoryControllerAddress,
minInitialPoolLiquidity,
},
);
return {
Expand Down
8 changes: 4 additions & 4 deletions packages/run-protocol/src/proposals/econ-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const CENTRAL_DENOM_NAME = 'urun';
* ammCreatorFacet: XYKAMMCreatorFacet,
* ammGovernorCreatorFacet: GovernedContractFacetAccess<unknown>,
* economicCommitteeCreatorFacet: CommitteeElectorateCreatorFacet,
* interchainMints: Mint[],
* bankMints: Mint[],
* psmCreatorFacet: unknown,
* psmGovernorCreatorFacet: GovernedContractFacetAccess<unknown>,
* reservePublicFacet: AssetReservePublicFacet,
Expand Down Expand Up @@ -159,7 +159,7 @@ harden(startInterchainPool);

/**
* @param { EconomyBootstrapPowers } powers
* @param {object} opts
* @param {{ options?: { minInitialPoolLiquidity?: bigint }}} opts
*/
export const setupAmm = async (
{
Expand All @@ -183,15 +183,15 @@ export const setupAmm = async (
consume: { contractGovernor: governorInstallation, amm: ammInstallation },
},
},
opts,
{ options = {} } = {},
) => {
const poserInvitationP = E(committeeCreator).getPoserInvitation();
const [poserInvitation, poserInvitationAmount, runBrand] = await Promise.all([
poserInvitationP,
E(E(zoe).getInvitationIssuer()).getAmountOf(poserInvitationP),
runBrandP,
]);
const { minInitialPoolLiquidity = 1_000_000_000n } = opts;
const { minInitialPoolLiquidity = 1_000_000_000n } = options;

const timer = await chainTimerService; // avoid promise for legibility

Expand Down
5 changes: 3 additions & 2 deletions packages/run-protocol/src/vpool-xyk-amm/addPool.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ export const makeAddIssuer = (zcf, isInSecondaries, brandToLiquidityMint) => {
AssetKind.NAT,
harden({ decimalPlaces: 6 }),
),
mint => {
zcf.saveIssuer(secondaryIssuer, keyword);
/** @param {ZCFMint} mint */
async mint => {
await zcf.saveIssuer(secondaryIssuer, keyword);
Comment on lines +45 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linking #5407 for motivation

brandToLiquidityMint.init(secondaryBrand, mint);
const { issuer: liquidityIssuer } = mint.getIssuerRecord();
return liquidityIssuer;
Expand Down
Loading