From feda8383545b5125ffcc4320d4dfbf4599e04169 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Sun, 5 Mar 2023 13:37:30 -0800 Subject: [PATCH] chore: clean up governance, add invitation patterns in auctioneer --- .../inter-protocol/src/auction/auctioneer.js | 152 ++++++++++-------- .../test/auction/test-auctionContract.js | 10 +- 2 files changed, 92 insertions(+), 70 deletions(-) diff --git a/packages/inter-protocol/src/auction/auctioneer.js b/packages/inter-protocol/src/auction/auctioneer.js index 61daed35c90..06c5d63b4ec 100644 --- a/packages/inter-protocol/src/auction/auctioneer.js +++ b/packages/inter-protocol/src/auction/auctioneer.js @@ -9,7 +9,7 @@ import { makeScalarBigMapStore, provideDurableMapStore, } from '@agoric/vat-data'; -import { AmountMath } from '@agoric/ertp'; +import { AmountMath, AmountShape } from '@agoric/ertp'; import { atomicRearrange, makeRatioFromAmounts, @@ -166,11 +166,11 @@ export const start = async (zcf, privateArgs, baggage) => { liqSeat.exit(); deposits.set(brand, []); } else if (depositsForBrand.length > 1) { - const collatRaise = collateralSeat.getCurrentAllocation().Collateral; - const currencyRaise = currencySeat.getCurrentAllocation().Currency; + const collProceeds = collateralSeat.getCurrentAllocation().Collateral; + const currProceeds = currencySeat.getCurrentAllocation().Currency; const transfers = distributeProportionalShares( - collatRaise, - currencyRaise, + collProceeds, + currProceeds, depositsForBrand, collateralSeat, currencySeat, @@ -188,7 +188,7 @@ export const start = async (zcf, privateArgs, baggage) => { } }; - const { publicMixin, creatorMixin, makeFarGovernorFacet, params } = + const { augmentPublicFacet, creatorMixin, makeFarGovernorFacet, params } = await handleParamGovernance( zcf, privateArgs.initialPoserInvitation, @@ -257,74 +257,88 @@ export const start = async (zcf, privateArgs, baggage) => { }; const getDepositInvitation = () => - zcf.makeInvitation(depositOfferHandler, 'deposit Collateral'); - - const publicFacet = Far('publicFacet', { - getBidInvitation(collateralBrand) { - const newBidHandler = (zcfSeat, bidSpec) => { - if (books.has(collateralBrand)) { - const auctionBook = books.get(collateralBrand); - auctionBook.addOffer(bidSpec, zcfSeat, isActive()); - return 'Your offer has been received'; - } else { - zcfSeat.exit(`No book for brand ${collateralBrand}`); - return 'Your offer was refused'; - } - }; + zcf.makeInvitation( + depositOfferHandler, + 'deposit Collateral', + undefined, + M.splitRecord({ give: { Collateral: AmountShape } }), + ); - return zcf.makeInvitation( - newBidHandler, - 'new bid', - {}, - FullProposalShape, - ); - }, - getSchedules() { - return E(scheduler).getSchedule(); - }, - getDepositInvitation, - ...publicMixin, - ...params, - }); + const publicFacet = augmentPublicFacet( + harden({ + getBidInvitation(collateralBrand) { + const newBidHandler = (zcfSeat, bidSpec) => { + if (books.has(collateralBrand)) { + const auctionBook = books.get(collateralBrand); + auctionBook.addOffer(bidSpec, zcfSeat, isActive()); + return 'Your offer has been received'; + } else { + zcfSeat.exit(`No book for brand ${collateralBrand}`); + return 'Your offer was refused'; + } + }; + const bidProposalShape = M.splitRecord( + { + give: { Currency: { brand: brands.Currency, value: M.nat() } }, + }, + { + want: M.or({ Collateral: AmountShape }, {}), + exit: FullProposalShape.exit, + }, + ); - const limitedCreatorFacet = Far('creatorFacet', { - /** - * @param {Issuer} issuer - * @param {Brand} collateralBrand - * @param {Keyword} kwd - */ - async addBrand(issuer, collateralBrand, kwd) { - zcf.assertUniqueKeyword(kwd); - !baggage.has(kwd) || - Fail`cannot add brand with keyword ${kwd}. it's in use`; - - zcf.saveIssuer(issuer, kwd); - baggage.init(kwd, makeScalarBigMapStore(kwd, { durable: true })); - const newBook = await makeAuctionBook( - baggage.get(kwd), - zcf, - brands.Currency, - collateralBrand, - priceAuthority, - ); + return zcf.makeInvitation( + newBidHandler, + 'new bid', + {}, + bidProposalShape, + ); + }, + getSchedules() { + return E(scheduler).getSchedule(); + }, + getDepositInvitation, + ...params, + }), + ); - // These three store.init() calls succeed or fail atomically - deposits.init(collateralBrand, harden([])); - books.init(collateralBrand, newBook); - brandToKeyword.init(collateralBrand, kwd); - }, - // XXX if it's in public, doesn't also need to be in creatorFacet. - getDepositInvitation, - /** @returns {Promise} */ - getSchedule() { - return E(scheduler).getSchedule(); - }, - ...creatorMixin, - }); + const creatorFacet = makeFarGovernorFacet( + Far('Auctioneer creatorFacet', { + /** + * @param {Issuer} issuer + * @param {Keyword} kwd + */ + async addBrand(issuer, kwd) { + zcf.assertUniqueKeyword(kwd); + !baggage.has(kwd) || + Fail`cannot add brand with keyword ${kwd}. it's in use`; + const { brand } = await zcf.saveIssuer(issuer, kwd); + + baggage.init(kwd, makeScalarBigMapStore(kwd, { durable: true })); + const newBook = await makeAuctionBook( + baggage.get(kwd), + zcf, + brands.Currency, + brand, + priceAuthority, + ); - const governorFacet = makeFarGovernorFacet(limitedCreatorFacet); + // These three store.init() calls succeed or fail atomically + deposits.init(brand, harden([])); + books.init(brand, newBook); + brandToKeyword.init(brand, kwd); + }, + // XXX if it's in public, doesn't also need to be in creatorFacet. + getDepositInvitation, + /** @returns {Promise} */ + getSchedule() { + return E(scheduler).getSchedule(); + }, + ...creatorMixin, + }), + ); - return { publicFacet, creatorFacet: governorFacet }; + return { publicFacet, creatorFacet }; }; /** @typedef {ContractOf} AuctioneerContract */ diff --git a/packages/inter-protocol/test/auction/test-auctionContract.js b/packages/inter-protocol/test/auction/test-auctionContract.js index eb61a219476..fab8a4b946a 100644 --- a/packages/inter-protocol/test/auction/test-auctionContract.js +++ b/packages/inter-protocol/test/auction/test-auctionContract.js @@ -200,7 +200,6 @@ const makeAuctionDriver = async (t, customTerms, params = defaultParams) => { await E(creatorFacet).addBrand( issuerKit.issuer, - collateralBrand, collateralBrand.getAllegedName(), ); return depositCollateral(collateralAmount, issuerKit); @@ -899,3 +898,12 @@ test.serial('multiple bidders at one auction step', async t => { t.true(await E(liqSeat).hasExited()); await assertPayouts(t, liqSeat, currency, collateral, 347n, 0n); }); + +test('deposit unregistered collateral', async t => { + const asset = withAmountUtils(makeIssuerKit('Asset')); + const driver = await makeAuctionDriver(t); + + await t.throwsAsync(() => driver.depositCollateral(asset.make(500n), asset), { + message: /no ordinal/, + }); +});