From 2e699e7cc9410bf275e05a89e56dcfc8835fbf43 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Tue, 19 Nov 2024 18:53:43 -0500 Subject: [PATCH] test: `Advancer` contract test --- packages/fast-usdc/src/fast-usdc.contract.js | 4 +- .../fast-usdc/test/fast-usdc.contract.test.ts | 111 ++++++++++++++---- packages/fast-usdc/test/supports.ts | 8 +- 3 files changed, 97 insertions(+), 26 deletions(-) diff --git a/packages/fast-usdc/src/fast-usdc.contract.js b/packages/fast-usdc/src/fast-usdc.contract.js index 2ecd9ba52be8..68c3307fe0eb 100644 --- a/packages/fast-usdc/src/fast-usdc.contract.js +++ b/packages/fast-usdc/src/fast-usdc.contract.js @@ -119,7 +119,7 @@ export const contract = async (zcf, privateArgs, zone, tools) => { * @param {{ USDC: Amount<'nat'>}} amounts */ testBorrow(amounts) { - console.log('🚧🚧 UNTIL: borrow is integrated 🚧🚧', amounts); + console.log('🚧🚧 UNTIL: borrow is integrated (#10388) 🚧🚧', amounts); const { zcfSeat: tmpAssetManagerSeat } = zcf.makeEmptySeatKit(); // eslint-disable-next-line no-use-before-define poolKit.borrower.borrow(tmpAssetManagerSeat, amounts); @@ -132,7 +132,7 @@ export const contract = async (zcf, privateArgs, zone, tools) => { * @returns {Promise} */ async testRepay(amounts, payments) { - console.log('🚧🚧 UNTIL: repay is integrated 🚧🚧', amounts); + console.log('🚧🚧 UNTIL: repay is integrated (#10388) 🚧🚧', amounts); const { zcfSeat: tmpAssetManagerSeat } = zcf.makeEmptySeatKit(); await depositToSeat( zcf, diff --git a/packages/fast-usdc/test/fast-usdc.contract.test.ts b/packages/fast-usdc/test/fast-usdc.contract.test.ts index 427ca2cf9d2c..789e0337c1d2 100644 --- a/packages/fast-usdc/test/fast-usdc.contract.test.ts +++ b/packages/fast-usdc/test/fast-usdc.contract.test.ts @@ -23,6 +23,7 @@ import { commonSetup } from './supports.js'; import type { FastUsdcTerms } from '../src/fast-usdc.contract.js'; import { makeFeeTools } from '../src/utils/fees.js'; import type { PoolMetrics } from '../src/types.js'; +import { addressTools } from '../src/utils/address.js'; const dirname = path.dirname(new URL(import.meta.url).pathname); @@ -52,6 +53,14 @@ const startContract = async ( const { zoe, bundleAndInstall } = await setUpZoeForTest({ setJig: jig => { jig.chainHub.registerChain('osmosis', fetchedChainInfo.osmosis); + jig.chainHub.registerChain('agoric', fetchedChainInfo.agoric); + // TODO #10445 register noble<>agoric and noble<>osmosis instead + // for PFM routing. also will need to call `registerAsset` + jig.chainHub.registerConnection( + fetchedChainInfo.agoric.chainId, + fetchedChainInfo.osmosis.chainId, + fetchedChainInfo.agoric.connections['osmosis-1'], + ); }, }); const installation: Installation = @@ -69,26 +78,6 @@ const startContract = async ( return { ...startKit, zoe }; }; -// FIXME this makeTestPushInvitation forces evidence, which triggers advancing, -// which doesn't yet work -test.skip('advancing', async t => { - const common = await commonSetup(t); - - const { publicFacet, zoe } = await startContract(common); - - const e1 = await E(MockCctpTxEvidences.AGORIC_PLUS_DYDX)(); - - const inv = await E(publicFacet).makeTestPushInvitation(e1); - // the invitation maker itself pushes the evidence - - // the offer is still safe to make - const seat = await E(zoe).offer(inv); - t.is( - await E(seat).getOfferResult(), - 'inert; nothing should be expected from this offer', - ); -}); - test('oracle operators have closely-held rights to submit evidence of CCTP transactions', async t => { const common = await commonSetup(t); const { creatorFacet, zoe } = await startContract(common); @@ -551,3 +540,85 @@ test('baggage', async t => { const tree = inspectMapStore(contractBaggage); t.snapshot(tree, 'contract baggage after start'); }); + +test('advancing happy path', async t => { + const common = await commonSetup(t); + const { + brands: { usdc }, + commonPrivateArgs, + utils: { inspectLocalBridge, inspectBankBridge, transmitTransferAck }, + } = common; + + const { instance, publicFacet, zoe } = await startContract(common); + const terms = await E(zoe).getTerms(instance); + const { subscriber } = E.get( + E.get(E(publicFacet).getPublicTopics()).poolMetrics, + ); + const feeTools = makeFeeTools(commonPrivateArgs.feeConfig); + const { makeLP, purseOf } = makeLpTools(t, common, { + publicFacet, + subscriber, + terms, + zoe, + }); + + const evidence = await E(MockCctpTxEvidences.AGORIC_PLUS_OSMO)(); + + // seed pool with funds + const alice = makeLP('Alice', purseOf(evidence.tx.amount)); + await alice.deposit(evidence.tx.amount); + + // the invitation maker itself pushes the evidence + const inv = await E(publicFacet).makeTestPushInvitation(evidence); + const seat = await E(zoe).offer(inv); + t.is( + await E(seat).getOfferResult(), + 'inert; nothing should be expected from this offer', + ); + + // calculate advance net of fees + const expectedAdvance = feeTools.calculateAdvance( + usdc.make(evidence.tx.amount), + ); + t.log('Expecting to observe advance of', expectedAdvance); + + await eventLoopIteration(); // let Advancer do work + + // advance sent from PoolSeat to PoolAccount + t.deepEqual(inspectBankBridge().at(-1), { + amount: String(expectedAdvance.value), + denom: 'ibc/usdconagoric', + recipient: 'agoric1fakeLCAAddress', + type: 'VBANK_GIVE', + }); + + // ibc transfer sent over localChain bridge + const localBridgeMsg = inspectLocalBridge().at(-1); + const ibcTransferMsg = localBridgeMsg.messages[0]; + t.is(ibcTransferMsg['@type'], '/ibc.applications.transfer.v1.MsgTransfer'); + + const expectedReceiver = addressTools.getQueryParams( + evidence.aux.recipientAddress, + ).EUD; + t.is(ibcTransferMsg.receiver, expectedReceiver, 'sent to correct address'); + t.deepEqual(ibcTransferMsg.token, { + amount: String(expectedAdvance.value), + denom: 'ibc/usdconagoric', + }); + + // TODO #10445 expect PFM memo + t.is(ibcTransferMsg.memo, '', 'TODO expecting PFM memo'); + + // TODO #10445 expect routing through noble, not osmosis + t.is( + ibcTransferMsg.sourceChannel, + fetchedChainInfo.agoric.connections['osmosis-1'].transferChannel.channelId, + 'TODO expecting routing through Noble', + ); + + await transmitTransferAck(); + // 'Advance transfer fulfilled' observed in logs instead of ending on 'No + // match yet. Save the pattern for later.' + // Consider supplying a `log: LogFn` to Advancer we can access in testing to + // verify the message. +}); diff --git a/packages/fast-usdc/test/supports.ts b/packages/fast-usdc/test/supports.ts index 82e8955c4bcc..8ce9d7b12ea8 100644 --- a/packages/fast-usdc/test/supports.ts +++ b/packages/fast-usdc/test/supports.ts @@ -52,7 +52,7 @@ export const commonSetup = async (t: ExecutionContext) => { onToBridge: obj => bankBridgeMessages.push(obj), }); await E(bankManager).addAsset( - 'uusdc', + 'ibc/usdconagoric', 'USDC', 'USD Circle Stablecoin', usdc.issuerKit, @@ -64,13 +64,13 @@ export const commonSetup = async (t: ExecutionContext) => { // TODO https://github.com/Agoric/agoric-sdk/issues/9966 await makeWellKnownSpaces(agoricNamesAdmin, t.log, ['vbankAsset']); await E(E(agoricNamesAdmin).lookupAdmin('vbankAsset')).update( - 'uusdc', + 'ibc/usdconagoric', /** @type {AssetInfo} */ harden({ brand: usdc.brand, issuer: usdc.issuer, - issuerName: 'IST', + issuerName: 'USDC', denom: 'uusdc', - proposedName: 'IST', + proposedName: 'USDC', displayInfo: { IOU: true }, }), );