Skip to content

Commit

Permalink
8981 upgrade vaults (#9283)
Browse files Browse the repository at this point in the history
closes: #8049
closes: #8740
closes: #8868
closes: #8918
closes: #8981
closes: #8079
refs: #8400
closes: #8735
closes: #7873
closes: #8726
closes: #7954
closes: #8757
closes: #8728 
closes: #8789

## Description

Upgrade **VaultFactory** in A3P, relying on the new PriceFeeds, and
auctions. The actual upgrade waits for the priceFeeds to start supplying
before doing the upgrade, so there won't be any gap in priceUpdates.

When the upgrade is finished, we also update the auctioneerKit and
Auction instance in the bootstrap environment.

This PR demonstrates that VaultFactory can be upgraded even though
governance is not persistent (#8123).

### Security Considerations

N/A

### Scaling Considerations

This is largely in service of #8400, which reports that priceFeed vats
are accumulating garbage. This PR switches to new priceFeeds, which
won't have that problem, though cleaning up the existing vats is a task
for the future.

### Documentation Considerations

No changes to user-visible behavior.

### Testing Considerations

A3P tests that verify that vaultFactory has been upgraded, that a new
Auctioneer is running and is receiving prices. Verify that when prices
drop, assets are sold via the auction, the bidder gets the proceeds, and
the vaults are liquidated or reconstituted appropriately.

### Upgrade Considerations

Upgrade all the vats!
  • Loading branch information
mergify[bot] authored May 6, 2024
2 parents 8e94b2a + e9affc8 commit 24f7f32
Show file tree
Hide file tree
Showing 20 changed files with 600 additions and 195 deletions.
139 changes: 139 additions & 0 deletions a3p-integration/proposals/a:upgrade-next/agd-tools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import {
agd,
agops,
agopsLocation,
executeCommand,
VALIDATORADDR,
executeOffer,
GOV1ADDR,
GOV2ADDR,
GOV3ADDR,
newOfferId,
CHAINID,
} from '@agoric/synthetic-chain';

const ORACLE_ADDRESSES = [GOV1ADDR, GOV2ADDR, GOV3ADDR];

export const BID_OFFER_ID = 'bid-vaultUpgrade-test3';

const queryVstorage = path =>
agd.query('vstorage', 'data', '--output', 'json', path);

// XXX use endo/marshal?
const getQuoteBody = async path => {
const queryOut = await queryVstorage(path);

const body = JSON.parse(JSON.parse(queryOut.value).values[0]);
return JSON.parse(body.body.substring(1));
};

export const getOracleInstance = async price => {
const instanceRec = await queryVstorage(`published.agoricNames.instance`);

const value = JSON.parse(instanceRec.value);
const body = JSON.parse(value.values.at(-1));

const feeds = JSON.parse(body.body.substring(1));
const feedName = `${price}-USD price feed`;

const key = Object.keys(feeds).find(k => feeds[k][0] === feedName);
if (key) {
return body.slots[key];
}
return null;
};

export const checkForOracle = async (t, name) => {
const instance = await getOracleInstance(name);
t.truthy(instance);
};

export const addOraclesForBrand = async (brandIn, oraclesByBrand) => {
await null;
const promiseArray = [];

const oraclesWithID = [];
// newOfferId() waits 1 second
const offerIdBase = await newOfferId();
for (let i = 0; i < ORACLE_ADDRESSES.length; i += 1) {
const oracleAddress = ORACLE_ADDRESSES[i];
const offerId = `${offerIdBase}.${i}`;
oraclesWithID.push({ address: oracleAddress, offerId });

promiseArray.push(
executeOffer(
oracleAddress,
agops.oracle('accept', '--offerId', offerId, `--pair ${brandIn}.USD`),
),
);
}
oraclesByBrand.set(brandIn, oraclesWithID);

return Promise.all(promiseArray);
};

export const pushPrices = (price, brandIn, oraclesByBrand) => {
const promiseArray = [];

for (const oracle of oraclesByBrand.get(brandIn)) {
promiseArray.push(
executeOffer(
oracle.address,
agops.oracle(
'pushPriceRound',
'--price',
price,
'--oracleAdminAcceptOfferId',
oracle.offerId,
),
),
);
}

return Promise.all(promiseArray);
};

export const getPriceQuote = async price => {
const path = `published.priceFeed.${price}-USD_price_feed`;
const body = await getQuoteBody(path);
return body.amountOut.value;
};

export const agopsInter = (...params) => {
const newParams = ['inter', ...params];
return executeCommand(agopsLocation, newParams);
};

export const createBid = (price, addr, offerId) => {
return agopsInter(
'bid',
'by-price',
`--price ${price}`,
`--give 1.0IST`,
'--from',
addr,
'--keyring-backend test',
`--offer-id ${offerId}`,
);
};

export const getLiveOffers = async addr => {
const path = `published.wallet.${addr}.current`;
const body = await getQuoteBody(path);
return body.liveOffers;
};

export const getAuctionCollateral = async index => {
const path = `published.auction.book${index}`;
const body = await getQuoteBody(path);
return body.collateralAvailable.value;
};

export const bankSend = (addr, wanted) => {
const chain = ['--chain-id', CHAINID];
const from = ['--from', VALIDATORADDR];
const testKeyring = ['--keyring-backend', 'test'];
const noise = [...from, ...chain, ...testKeyring, '--yes'];

return agd.tx('bank', 'send', VALIDATORADDR, addr, wanted, ...noise);
};
150 changes: 0 additions & 150 deletions a3p-integration/proposals/a:upgrade-next/priceFeed.test.js

This file was deleted.

3 changes: 2 additions & 1 deletion a3p-integration/proposals/a:upgrade-next/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
# Place here any test that should be executed using the executed proposal.
# The effects of this step are not persisted in further proposal layers.

GLOBIGNORE=initial.test.js

# test the state right after upgrade
yarn ava initial.test.js

# test more, in ways that changes system state
GLOBIGNORE=initial.test.js
yarn ava ./*.test.js
Loading

0 comments on commit 24f7f32

Please sign in to comment.