Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: advancer validates settlementAccount address #10723

Merged
merged 4 commits into from
Dec 18, 2024

Conversation

0xpatrickdev
Copy link
Member

@0xpatrickdev 0xpatrickdev commented Dec 17, 2024

closes: #10726

Description

Primary aim is to validate evidence reported to FUSDC contains the expected settlementAccount address. This supports C8 - Contract MUST be able to initialize settlement process when Noble mints USDC.

To facilitate this change:

  • add makeTestAddress helper in @agoric/orchestration/tools that returns a valid bech32 address
    • since encodeAddressHook throws when presented agoric1FakeLCAAddress
  • bootstrap's VLOCALCHAIN_ALLOCATE_ADDRESS now returns a valid (mocked) bech32 address
  • makeFakeLocalchainBridge accepts makeAddressFn

Security Considerations

Hardens FUSDC implementation.

Scaling Considerations

None

Documentation Considerations

None

Testing Considerations

Includes new tests (see advancer.test.ts) and updates existing tests

Upgrade Considerations

None, unreleased code

@0xpatrickdev 0xpatrickdev force-pushed the pc/validate-settlement-account branch from d7089f7 to 2ab0286 Compare December 17, 2024 23:55
Copy link

cloudflare-workers-and-pages bot commented Dec 17, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: e06f12a
Status: ✅  Deploy successful!
Preview URL: https://43cc6152.agoric-sdk.pages.dev
Branch Preview URL: https://pc-validate-settlement-accou.agoric-sdk.pages.dev

View logs

@0xpatrickdev 0xpatrickdev force-pushed the pc/validate-settlement-account branch from 28bef35 to 0087d71 Compare December 18, 2024 01:16
@0xpatrickdev 0xpatrickdev added the force:integration Force integration tests to run on PR label Dec 18, 2024
@0xpatrickdev 0xpatrickdev force-pushed the pc/validate-settlement-account branch from 0087d71 to d52f76d Compare December 18, 2024 19:28
@0xpatrickdev 0xpatrickdev marked this pull request as ready for review December 18, 2024 19:34
@0xpatrickdev 0xpatrickdev requested a review from a team as a code owner December 18, 2024 19:34
@0xpatrickdev 0xpatrickdev force-pushed the pc/validate-settlement-account branch from d52f76d to c8e0529 Compare December 18, 2024 19:42
Comment on lines +6 to +7
t.is(makeTestAddress(), 'agoric1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqp7zqht');
t.is(makeTestAddress(1), 'agoric1qyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc09z0g');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider making the index human readable in the address and/or allowing the caller to add a string to give meaning to the address. That makes it easier to follow in logs what is happening.

Maybe it's a different function. I could see it coming in a separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very open to a "vanity address" that's more readable. A constraint on inserting a readable string is the checksum encodeAddressHook performs.

export const makeFakeLocalchainBridge = (
zone,
onToBridge = () => {},
makeAddressFn,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
makeAddressFn,
makeAddressFn = index => `${LOCALCHAIN_DEFAULT_ADDRESS}${index || ''}`

@@ -233,7 +234,13 @@ test.serial('makes usdc advance', async t => {
});
await eventLoopIteration();

const evidence = MockCctpTxEvidences.AGORIC_PLUS_OSMO();
const accountsData = storage.data.get('published.fastUsdc');
const { settlementAccount } = JSON.parse(JSON.parse(accountsData!).values[0]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think storage.getDeserialized would help here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL. Not here, but elsewhere in this file it seems we could use something similar for feeConfig.

const { settlementAccount } = JSON.parse(JSON.parse(accountsData!).values[0]);
const evidence = MockCctpTxEvidences.AGORIC_PLUS_OSMO(
encodeAddressHook(settlementAccount, {
EUD: 'osmo183dejcnmkka5dzcu9xw6mywq0p2m5peks28men',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic string should be a const

const { recipientAddress } = evidence.aux;
const decoded = decodeAddressHook(recipientAddress);
mustMatch(decoded, AddressHookShape);
if (!settlementAddress?.value) {
throw Fail`⚠️ No 'settlementAddress'. must call 'publishAddresses' first.`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

publishAddresses is outside the concern of this module. It only knows about setSettlementAddress

since handleTransactionEvent will fail if setSettlementAddress hasn't been called, maybe the contract shouldn't start the watcher until it has.

but… why not require settlementAddress when making the exo? It's known at that time. Then you can rely on it being set and not have to handle mutations.

Copy link
Member Author

@0xpatrickdev 0xpatrickdev Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only have the account object at the time the exo is created, not the address one. Agree it would be better to require it at make time. If awaiting getAddress() doesn't break the upgrade test, I'm up for it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave it a try in ac84a97. Let's see how force:integration does with it.

Another reason to make the change is POLA… advancer should not be able to access funds from the settlementAccount.

@@ -543,7 +549,7 @@ test.serial('STORY01: advancing happy path for 100 USDC', async t => {
bridges: { snapshot, since },
mint,
} = t.context;
const cust1 = makeCustomer('Carl', cctp, txPub.publisher, feeConfig);
const cust1 = makeCustomer('Carl', cctp, txPub.publisher, feeConfig, storage);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const cust1 = makeCustomer('Carl', cctp, txPub.publisher, feeConfig, storage);
const cust1 = makeCustomer('Carl', cctp, txPub.publisher, feeConfig);

all the methods of cust1 already have access to context and thus storage.

t is passed in with every call. That could be refactored but is out of scope

export const settlementAddress: ChainAddress = harden({
chainId: 'agoric-3',
encoding: 'bech32' as const,
value: 'agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

random? if it's not encoding any data let's put something descriptive in it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These was extracted from existing code on master. I don't think it's encoding anything - it's supposed to represent an LCA. Maybe better to use makeTestAddress().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is in a fixtures module I'd propose a fixed value. makeTestAddress values could collide. We might also consider having a global counter so each call produces a unique address. That will help prevent using magic strings: when we need values to match put them in a constant.

@turadg turadg self-assigned this Dec 18, 2024
- returns valid bech32 address for tests
- instead of `agoric1fakeLCAAddress`, `agoric1fakeLCAAddress1`
- to support `encodeAddressHook` which relies on valid bech32
@turadg turadg force-pushed the pc/validate-settlement-account branch from ac84a97 to e06f12a Compare December 18, 2024 22:13
Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the requested changes as agreed. Approving.

@turadg turadg added the automerge:rebase Automatically rebase updates, then merge label Dec 18, 2024
@mergify mergify bot merged commit 7b7ceb9 into master Dec 18, 2024
86 of 95 checks passed
@mergify mergify bot deleted the pc/validate-settlement-account branch December 18, 2024 23:03
@@ -271,6 +277,7 @@ export const prepareAdvancerKit = (
borrowerFacet: M.remotable(),
poolAccount: M.remotable(),
intermediateRecipient: M.opt(ChainAddressShape),
settlementAddress: M.opt(ChainAddressShape),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: should remove M.opt

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking it over again. e49ad00 coming in another PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge force:integration Force integration tests to run on PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

fusdc: advancer validates settler address
2 participants