Skip to content

Commit

Permalink
feat: verify settlement account
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Dec 17, 2024
1 parent 0dc6bd3 commit 110d9c9
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 32 deletions.
33 changes: 26 additions & 7 deletions packages/fast-usdc/src/exos/transaction-feed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { makeTracer } from '@agoric/internal';
import { prepareDurablePublishKit } from '@agoric/notifier';
import { keyEQ, M } from '@endo/patterns';
import { Fail } from '@endo/errors';
import { decodeAddressHook } from '@agoric/cosmic-proto/address-hooks.js';
import { CctpTxEvidenceShape } from '../type-guards.js';
import { defineInertInvitation } from '../utils/zoe.js';
import { prepareOperatorKit } from './operator-kit.js';
Expand Down Expand Up @@ -54,7 +55,11 @@ export const prepareTransactionFeedKit = (zone, zcf) => {
return zone.exoClassKit(
'Fast USDC Feed',
TransactionFeedKitI,
() => {
/**
* @param {import('@agoric/orchestration').ChainAddress} settlementAccountAddress
*/
settlementAccountAddress => {
assert(settlementAccountAddress, 'missing settlementAccountAddress');
/** @type {MapStore<string, OperatorKit>} */
const operators = zone.mapStore('operators', {
durable: true,
Expand All @@ -63,7 +68,7 @@ export const prepareTransactionFeedKit = (zone, zcf) => {
const pending = zone.mapStore('pending', {
durable: true,
});
return { operators, pending };
return { operators, pending, settlementAccountAddress };
},
{
creator: {
Expand Down Expand Up @@ -125,13 +130,27 @@ export const prepareTransactionFeedKit = (zone, zcf) => {
* @param {string} operatorId
*/
attest(evidence, operatorId) {
const { operators, pending } = this.state;
const { operators, pending, settlementAccountAddress } = this.state;
trace('submitEvidence', operatorId, evidence);

// TODO validate that it's a valid for Fast USDC before accepting
// E.g. that the `recipientAddress` is the FU settlement account and that
// the EUD is a chain supported by FU.
const { txHash } = evidence;
const {
aux: { recipientAddress },
tx: { forwardingAddress },
txHash,
} = evidence;
assert(
forwardingAddress.startsWith('noble'),
'only Noble forwarding supported',
);
const hook = decodeAddressHook(recipientAddress);
assert.equal(
hook.baseAddress,
settlementAccountAddress.value,
'only Fast USDC settlementAccount supported as recipient',
);
// We could also verify that hook.query.EUD is chain officially
// supported by Fast USDC. We filter upstream to give the on-chain
// contract more flexibility.

// accept the evidence
{
Expand Down
6 changes: 4 additions & 2 deletions packages/fast-usdc/src/fast-usdc.contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,6 @@ export const contract = async (zcf, privateArgs, zone, tools) => {

const nobleAccountV = zone.makeOnce('NobleAccount', () => makeNobleAccount());

const feedKit = zone.makeOnce('Feed Kit', () => makeFeedKit());

const poolAccountV = zone.makeOnce('PoolAccount', () => makeLocalAccount());
const settleAccountV = zone.makeOnce('SettleAccount', () =>
makeLocalAccount(),
Expand All @@ -284,6 +282,10 @@ export const contract = async (zcf, privateArgs, zone, tools) => {
trace('settlementAccount', settlementAccount);
trace('poolAccount', poolAccount);

const feedKit = zone.makeOnce('Feed Kit', () =>
makeFeedKit(settlementAccount.getAddress()),
);

const [_agoric, _noble, agToNoble] = await vowTools.when(
chainHub.getChainsAndConnection('agoric', 'noble'),
);
Expand Down
13 changes: 11 additions & 2 deletions packages/fast-usdc/test/exos/transaction-feed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,27 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import { deeplyFulfilledObject } from '@agoric/internal';
import { makeHeapZone } from '@agoric/zone';
import type { ChainAddress } from '@agoric/orchestration';
import {
prepareTransactionFeedKit,
type TransactionFeedKit,
} from '../../src/exos/transaction-feed.js';
import { MockCctpTxEvidences } from '../fixtures.js';
import {
MockCctpTxEvidences,
mockSettlementAccountAddress,
} from '../fixtures.js';

const nullZcf = null as any;
const settlementAccountAddress: ChainAddress = {
chainId: 'agoric',
value: mockSettlementAccountAddress,
encoding: 'bech32',
};

const makeFeedKit = () => {
const zone = makeHeapZone();
const makeKit = prepareTransactionFeedKit(zone, nullZcf);
return makeKit();
return makeKit(settlementAccountAddress);
};

const makeOperators = (feedKit: TransactionFeedKit) => {
Expand Down
13 changes: 8 additions & 5 deletions packages/fast-usdc/test/fast-usdc.contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ import type { FastUsdcSF } from '../src/fast-usdc.contract.js';
import { PoolMetricsShape } from '../src/type-guards.js';
import type { CctpTxEvidence, FeeConfig, PoolMetrics } from '../src/types.js';
import { makeFeeTools } from '../src/utils/fees.js';
import { MockCctpTxEvidences } from './fixtures.js';
import {
MockCctpTxEvidences,
mockSettlementAccountAddress,
} from './fixtures.js';
import { commonSetup, uusdcOnAgoric } from './supports.js';

const dirname = path.dirname(new URL(import.meta.url).pathname);
Expand Down Expand Up @@ -135,7 +138,7 @@ const makeTestContext = async (t: ExecutionContext) => {
};

const mint = async (e: CctpTxEvidence) => {
const settlerAddr = 'agoric1fakeLCAAddress1'; // TODO: get from contract
const settlerAddr = mockSettlementAccountAddress; // TODO: get from contract
const rxd = await receiveUSDCAt(settlerAddr, e.tx.amount);
await VE(transferBridge).fromBridge(
buildVTransferEvent({
Expand Down Expand Up @@ -190,7 +193,7 @@ test('getStaticInfo', async t => {
t.deepEqual(await E(publicFacet).getStaticInfo(), {
addresses: {
poolAccount: 'agoric1fakeLCAAddress',
settlementAccount: 'agoric1fakeLCAAddress1',
settlementAccount: mockSettlementAccountAddress,
},
});
});
Expand Down Expand Up @@ -549,7 +552,7 @@ test.serial('STORY01: advancing happy path for 100 USDC', async t => {
t.deepEqual(inspectBankBridge().at(-1), {
amount: String(expectedAdvance.value),
denom: uusdcOnAgoric,
recipient: 'agoric1fakeLCAAddress',
recipient: mockSettlementAccountAddress,
type: 'VBANK_GIVE',
});

Expand Down Expand Up @@ -779,7 +782,7 @@ test.serial('Settlement for unknown transaction (operator down)', async t => {
},
{
amount: '20000000',
recipient: 'agoric1fakeLCAAddress1',
recipient: mockSettlementAccountAddress,
type: 'VBANK_GIVE',
},
],
Expand Down
26 changes: 11 additions & 15 deletions packages/fast-usdc/test/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const mockScenarios = [

type MockScenario = (typeof mockScenarios)[number];

export const mockSettlementAccountAddress =
'agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek';

export const Senders = {
default: '0xDefaultFakeEthereumAddress',
} as unknown as Record<string, EvmAddress>;
Expand All @@ -37,10 +40,9 @@ export const MockCctpTxEvidences: Record<
forwardingChannel: 'channel-21',
recipientAddress:
receiverAddress ||
encodeAddressHook(
'agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek',
{ EUD: 'osmo183dejcnmkka5dzcu9xw6mywq0p2m5peks28men' },
),
encodeAddressHook(mockSettlementAccountAddress, {
EUD: 'osmo183dejcnmkka5dzcu9xw6mywq0p2m5peks28men',
}),
},
chainId: 1,
}),
Expand All @@ -59,10 +61,9 @@ export const MockCctpTxEvidences: Record<
forwardingChannel: 'channel-21',
recipientAddress:
receiverAddress ||
encodeAddressHook(
'agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek',
{ EUD: 'dydx183dejcnmkka5dzcu9xw6mywq0p2m5peks28men' },
),
encodeAddressHook(mockSettlementAccountAddress, {
EUD: 'dydx183dejcnmkka5dzcu9xw6mywq0p2m5peks28men',
}),
},
chainId: 1,
}),
Expand All @@ -79,9 +80,7 @@ export const MockCctpTxEvidences: Record<
},
aux: {
forwardingChannel: 'channel-21',
recipientAddress:
receiverAddress ||
'agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek',
recipientAddress: receiverAddress || mockSettlementAccountAddress,
},
chainId: 1,
}),
Expand All @@ -100,10 +99,7 @@ export const MockCctpTxEvidences: Record<
forwardingChannel: 'channel-21',
recipientAddress:
receiverAddress ||
encodeAddressHook(
'agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek',
{ EUD: 'random1addr' },
),
encodeAddressHook(mockSettlementAccountAddress, { EUD: 'random1addr' }),
},
chainId: 1,
}),
Expand Down
4 changes: 3 additions & 1 deletion packages/fast-usdc/test/supports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ export const commonSetup = async (t: ExecutionContext<any>) => {
ibcSequenceNonce += 1n;
// let the promise for the transfer start
await eventLoopIteration();
const lastMsgTransfer = localBridgeMessages.at(-1).messages[0];
const lastLBM = localBridgeMessages.at(-1);
assert('messages' in lastLBM, 'expected a different localBridgeMessage');
const lastMsgTransfer = lastLBM.messages[0];
await E(transferBridge).fromBridge(
buildVTransferEvent({
receiver: lastMsgTransfer.receiver,
Expand Down

0 comments on commit 110d9c9

Please sign in to comment.