diff --git a/packages/inter-protocol/src/stakeFactory/stakeFactory.js b/packages/inter-protocol/src/stakeFactory/stakeFactory.js index 5cbc901fbac0..26f4d2b876c6 100644 --- a/packages/inter-protocol/src/stakeFactory/stakeFactory.js +++ b/packages/inter-protocol/src/stakeFactory/stakeFactory.js @@ -1,6 +1,7 @@ // @jessie-check import { AmountMath } from '@agoric/ertp'; import { handleParamGovernance, ParamTypes } from '@agoric/governance'; +import { M } from '@agoric/store'; import { atomicRearrange } from '@agoric/zoe/src/contractSupport/atomicTransfer.js'; import { E, Far } from '@endo/far'; import { makeMakeCollectFeesInvitation } from '../collectFees.js'; @@ -100,9 +101,11 @@ export const start = async ( /** @type {ZCFMint<'nat'>} */ const debtMint = await zcf.registerFeeMint(KW.Debt, feeMintAccess); const { brand: debtBrand } = debtMint.getIssuerRecord(); + const debtAmountShape = debtBrand.getAmountShape(); const att = await makeAttestationFacets(zcf, stakeBrand, lienBridge); const attestBrand = await E(att.publicFacet).getBrand(); + const attestAmountShape = attestBrand.getAmountShape(); const { augmentPublicFacet, makeGovernorFacet, params } = await handleParamGovernance( @@ -173,6 +176,15 @@ export const start = async ( { timerService, chargingPeriod, recordingPeriod, startTimeStamp }, ); + const StakeFactoryCloseProposalShape = M.splitRecord({ + give: { + [KW.Debt]: debtAmountShape, + }, + want: { + [KW.Attestation]: attestAmountShape, + }, + }); + /** * @param {ZCFSeat} seat */ @@ -190,16 +202,35 @@ export const start = async ( 'AdjustBalances', ), CloseVault: () => - zcf.makeInvitation(seatx => helper.closeHook(seatx), 'CloseVault'), + zcf.makeInvitation( + seatx => helper.closeHook(seatx), + 'CloseVault', + undefined, + StakeFactoryCloseProposalShape, + ), }), vault: pot, }); }; + const MakeStakeFactoryProposalShape = M.splitRecord({ + give: { + [KW.Attestation]: attestAmountShape, + }, + want: { + [KW.Debt]: debtAmountShape, + }, + }); + const publicFacet = augmentPublicFacet( harden({ makeLoanInvitation: () => - zcf.makeInvitation(offerHandler, 'make stakeFactory'), + zcf.makeInvitation( + offerHandler, + 'make stakeFactory', + undefined, + MakeStakeFactoryProposalShape, + ), makeReturnAttInvitation: att.publicFacet.makeReturnAttInvitation, }), ); diff --git a/packages/inter-protocol/src/stakeFactory/stakeFactoryKit.js b/packages/inter-protocol/src/stakeFactory/stakeFactoryKit.js index 21d2f0cb35ad..f7136d836222 100644 --- a/packages/inter-protocol/src/stakeFactory/stakeFactoryKit.js +++ b/packages/inter-protocol/src/stakeFactory/stakeFactoryKit.js @@ -4,10 +4,7 @@ import { bindAllMethods, makeTracer } from '@agoric/internal'; import { makePublishKit } from '@agoric/notifier'; import { M, matches } from '@agoric/store'; import { defineKindMulti } from '@agoric/vat-data'; -import { - assertProposalShape, - atomicRearrange, -} from '@agoric/zoe/src/contractSupport/index.js'; +import { atomicRearrange } from '@agoric/zoe/src/contractSupport/index.js'; import { ceilMultiplyBy } from '@agoric/zoe/src/contractSupport/ratio.js'; import { addSubtract } from '../contractSupport.js'; import { calculateCurrentDebt, reverseInterest } from '../interest-math.js'; @@ -74,12 +71,6 @@ const initState = (zcf, startSeat, manager) => { const emptyDebt = AmountMath.makeEmpty(debtBrand); const initialDebt = (() => { - // What `makeInvitation` call does this correspond to? - // TODO use a proposalShape there and kill the `assertProposalShape` here. - assertProposalShape(startSeat, { - give: { [KW.Attestation]: null }, - want: { [KW.Debt]: null }, - }); const { give: { [KW.Attestation]: attestationGiven }, want: { [KW.Debt]: runWanted }, @@ -375,26 +366,25 @@ const potBehavior = { const { helper } = facets; assert(state.open); - // Or should this be more like the AdjustBalancesProposalShape in - // vaultFactory, that allows both records to have both properties? - const AdjustBalancesProposalShape = M.or( - M.splitRecord({ - give: { - Attestation: AmountShape, // TODO brand specific AmountShape - }, - want: { - Debt: AmountShape, // TODO brand specific AmountShape - }, - }), - M.splitRecord({ - give: { - Debt: AmountShape, // TODO brand specific AmountShape + // Adjustments must be able to specify just the 'give' or the 'want'. + const AdjustBalancesProposalShape = M.splitRecord({ + give: M.splitRecord( + {}, + { + Attestation: AmountShape, // TODO get amount shape from brand + Debt: AmountShape, // TODO get amount shape from brand }, - want: { - Attestation: AmountShape, // TODO brand specific AmountShape + {}, + ), + want: M.splitRecord( + {}, + { + Attestation: AmountShape, // TODO get amount shape from brand + Debt: AmountShape, // TODO get amount shape from brand }, - }), - ); + {}, + ), + }); return zcf.makeInvitation( seat => helper.adjustBalancesHook(seat), @@ -411,10 +401,10 @@ const potBehavior = { const CloseProposalShape = M.splitRecord({ give: { - [KW.Debt]: AmountShape, // TODO brand specific AmountShape + [KW.Debt]: AmountShape, // TODO get amount shape from brand }, want: { - [KW.Attestation]: AmountShape, // TODO brand specific AmountShape + [KW.Attestation]: AmountShape, // TODO get amount shape from brand }, }); diff --git a/packages/inter-protocol/src/vaultFactory/vault.js b/packages/inter-protocol/src/vaultFactory/vault.js index 489d453b67dc..710cada5214e 100644 --- a/packages/inter-protocol/src/vaultFactory/vault.js +++ b/packages/inter-protocol/src/vaultFactory/vault.js @@ -193,42 +193,6 @@ const VaultStateShape = harden({ export const prepareVault = (baggage, makeRecorderKit, zcf) => { const makeVaultKit = prepareVaultKit(baggage, makeRecorderKit); - const AdjustBalancesProposalShape = M.splitRecord({ - give: M.splitRecord( - {}, - { - Collateral: AmountShape, // TODO brand specific AmountShape - Minted: AmountShape, // TODO brand specific AmountShape - }, - {}, - ), - want: M.splitRecord( - {}, - { - Collateral: AmountShape, // TODO brand specific AmountShape - Minted: AmountShape, // TODO brand specific AmountShape - }, - {}, - ), - }); - - const CloseProposalShape = M.splitRecord({ - give: M.splitRecord( - {}, - { - Minted: AmountShape, // TODO brand specific AmountShape - }, - {}, - ), - want: M.splitRecord( - {}, - { - Collateral: AmountShape, // TODO brand specific AmountShape - }, - {}, - ), - }); - const maker = prepareExoClassKit( baggage, 'Vault', diff --git a/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js b/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js index dc66880b8d84..455259e6ba5c 100644 --- a/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js +++ b/packages/inter-protocol/test/stakeFactory/test-stakeFactory.js @@ -442,7 +442,8 @@ test('extra offer keywords are rejected', async t => { harden({ [KW.Attestation]: attPmt }), ); await t.throwsAsync(E(seat).getOfferResult(), { - message: /Pony.*did not match/, + message: + /^"make stakeFactory" proposal: want: .* - Must not have unexpected properties: \["Pony"\]$/, }); }); diff --git a/packages/pegasus/src/pegasus.js b/packages/pegasus/src/pegasus.js index 69c0f30b1950..de70eccc751b 100644 --- a/packages/pegasus/src/pegasus.js +++ b/packages/pegasus/src/pegasus.js @@ -19,9 +19,9 @@ import { makeCourierMaker, getCourierPK } from './courier.js'; const DEFAULT_DENOM_TRANSFORMER = IBCSourceTraceDenomTransformer; const DEFAULT_TRANSFER_PROTOCOL = ICS20TransferProtocol; -const TRANSFER_PROPOSAL_SHAPE = M.splitRecord({ +const TransferProposalShape = M.splitRecord({ give: { - Transfer: AmountShape, // TODO brand specific AmountShape + Transfer: AmountShape, // TODO get amount shape from brand }, }); @@ -486,7 +486,7 @@ const makePegasus = (zcf, board, namesByAddress) => { offerHandler, `pegasus ${sendDenom} transfer`, undefined, - TRANSFER_PROPOSAL_SHAPE, + TransferProposalShape, ); }, }); diff --git a/packages/zoe/src/contractSupport/zoeHelpers.js b/packages/zoe/src/contractSupport/zoeHelpers.js index 67bef1ea0c19..d6be1760d33d 100644 --- a/packages/zoe/src/contractSupport/zoeHelpers.js +++ b/packages/zoe/src/contractSupport/zoeHelpers.js @@ -1,4 +1,4 @@ -import { mustMatch, keyEQ, M } from '@agoric/store'; +import { mustMatch, keyEQ } from '@agoric/store'; import { E } from '@endo/eventual-send'; import { makePromiseKit } from '@endo/promise-kit'; import { AssetKind } from '@agoric/ertp'; @@ -10,6 +10,7 @@ import { fromOnly, toOnly, } from './atomicTransfer.js'; +import { AmountKeywordRecordShape } from '../typeGuards.js'; export const defaultAcceptanceMsg = `The offer has been accepted. Once the contract has been completed, please check your payout`; @@ -207,7 +208,7 @@ export const depositToSeat = async (zcf, recipientSeat, amounts, payments) => { 'temporary seat for deposit', undefined, harden({ - give: M.any(), + give: AmountKeywordRecordShape, want: {}, exit: { onDemand: null }, }), diff --git a/packages/zoe/src/contracts/auction/index.js b/packages/zoe/src/contracts/auction/index.js index 98af8bd579e5..64a036e54ab1 100644 --- a/packages/zoe/src/contracts/auction/index.js +++ b/packages/zoe/src/contracts/auction/index.js @@ -117,19 +117,19 @@ const start = zcf => { const BidProposalShape = M.splitRecord({ give: { - Bid: AmountShape, // TODO brand specific AmountShape + Bid: AmountShape, // TODO get amount shape from brand }, want: { - Asset: AmountShape, // TODO brand specific AmountShape + Asset: AmountShape, // TODO get amount shape from brand }, }); const SellProposalShape = M.splitRecord({ give: { - Asset: AmountShape, // TODO brand specific AmountShape + Asset: AmountShape, // TODO get amount shape from brand }, want: { - Ask: AmountShape, // TODO brand specific AmountShape + Ask: AmountShape, // TODO get amount shape from brand }, exit: { // The auction is not over until the deadline according to the