Skip to content

Commit

Permalink
chore: chain policy limits
Browse files Browse the repository at this point in the history
  • Loading branch information
0xpatrickdev committed Jan 9, 2025
1 parent 35a27c1 commit 5043b8d
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 30 deletions.
14 changes: 4 additions & 10 deletions multichain-testing/test/fast-usdc/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { IBCChannelID } from '@agoric/vats';
import type { FeedPolicy } from '@agoric/fast-usdc/src/types.js';

export const oracleMnemonics = {
oracle1:
Expand All @@ -10,19 +11,12 @@ export const oracleMnemonics = {
};
harden(oracleMnemonics);

export const makeFeedPolicy = (nobleAgoricChannelId: IBCChannelID) => {
export const makeFeedPolicy = (
nobleAgoricChannelId: IBCChannelID,
): Omit<FeedPolicy, 'chainPolicies'> => {
return {
nobleAgoricChannelId,
nobleDomainId: 4,
chainPolicies: {
Arbitrum: {
attenuatedCttpBridgeAddress:
'0xe298b93ffB5eA1FB628e0C0D55A43aeaC268e347',
cctpTokenMessengerAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A',
chainId: 42161,
confirmations: 2,
},
},
};
};
harden(makeFeedPolicy);
4 changes: 2 additions & 2 deletions packages/boot/test/fast-usdc/fast-usdc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ test.serial(
},
);

test.serial('writes feed policy to vstorage', async t => {
test.serial('writes chain policy to vstorage', async t => {
const { storage } = t.context;
const opts = {
node: 'fastUsdc.feedPolicy',
owner: 'the general and chain-specific policies for the Fast USDC feed',
showValue: JSON.parse,
showValue: defaultSerializer.parse,
};
await documentStorageSchema(t, storage, opts);
});
Expand Down
12 changes: 11 additions & 1 deletion packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The actual snapshot is saved in `fast-usdc.test.ts.snap`.

Generated by [AVA](https://avajs.dev).

## writes feed policy to vstorage
## writes chain policy to vstorage

> Under "published", the "fastUsdc.feedPolicy" node is delegated to the general and chain-specific policies for the Fast USDC feed.
> The example below illustrates the schema of the data published there.
Expand All @@ -18,33 +18,43 @@ Generated by [AVA](https://avajs.dev).
chainPolicies: {
Arbitrum: {
attenuatedCttpBridgeAddress: '0xe298b93ffB5eA1FB628e0C0D55A43aeaC268e347',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A',
chainId: 42161,
confirmations: 2,
maxAmountPerBlockWindow: 20000000000n,
},
Base: {
attenuatedCttpBridgeAddress: '0xB6615B2662b35fc3533F8479002e62D0523341De',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x1682Ae6375C4E4A97e4B583BC394c861A46D8962',
chainId: 8453,
confirmations: 2,
maxAmountPerBlockWindow: 20000000000n,
},
Ethereum: {
attenuatedCttpBridgeAddress: '0xBC8552339dA68EB65C8b88B414B5854E0E366cFc',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0xBd3fa81B58Ba92a82136038B25aDec7066af3155',
chainId: 1,
confirmations: 2,
maxAmountPerBlockWindow: 20000000000n,
},
Optimism: {
attenuatedCttpBridgeAddress: '0x48C5417ED570928eC85D5e3AD4e7E0EeD7dB1E2A',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x2B4069517957735bE00ceE0fadAE88a26365528f',
chainId: 10,
confirmations: 2,
maxAmountPerBlockWindow: 20000000000n,
},
Polygon: {
attenuatedCttpBridgeAddress: '0x32cb9574650AFF312c80edc4B4343Ff5500767cA',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x9daF8c91AEFAE50b9c0E69629D3F6Ca40cA3B3FE',
chainId: 137,
confirmations: 2,
maxAmountPerBlockWindow: 20000000000n,
},
},
nobleAgoricChannelId: 'channel-21',
Expand Down
Binary file modified packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap
Binary file not shown.
10 changes: 9 additions & 1 deletion packages/builders/scripts/fast-usdc/init-fast-usdc.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,15 @@ export default async (homeP, endowments) => {
return configurations[net].feedPolicy;
}
if (!feedPolicy) throw Error(feedPolicyUsage);
return JSON.parse(feedPolicy);
const parsed = JSON.parse(feedPolicy);
if (!parsed.chainPolicies) {
// chainPolicies contain bigints which can't be stringified
return {
// @ts-expect-error spreading CopyRecord & Passable
...configurations.MAINNET.feedPolicy,
...parsed,
};
}
};

const parseOracleArgs = () => {
Expand Down
19 changes: 13 additions & 6 deletions packages/fast-usdc/src/fast-usdc-policy.core.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { E } from '@endo/far';
import { fromExternalConfig } from './utils/config-marshal.js';
import { FeedPolicyShape } from './type-guards.js';
import { makePublishingStorageKit } from './fast-usdc.start.js';

/**
* @import {Passable} from '@endo/pass-style'
Expand All @@ -18,11 +19,13 @@ const FEED_POLICY = 'feedPolicy';
* XXX copied from fast-usdc.start.js
*
* @param {ERef<StorageNode>} node
* @param {FeedPolicy} policy
* @param {ERef<Marshaller>} marshaller
* @param {FeedPolicy & Passable} policy
*/
const publishFeedPolicy = async (node, policy) => {
const publishFeedPolicy = async (node, marshaller, policy) => {
const feedPolicy = E(node).makeChildNode(FEED_POLICY);
await E(feedPolicy).setValue(JSON.stringify(policy));
const value = await E(marshaller).toCapData(policy);
await E(feedPolicy).setValue(JSON.stringify(value));
};

/**
Expand All @@ -32,7 +35,7 @@ const publishFeedPolicy = async (node, policy) => {
* @param {{ options: LegibleCapData<{feedPolicy: FeedPolicy & Passable}> }} config
*/
export const updateFastUsdcPolicy = async (
{ consume: { agoricNames, chainStorage } },
{ consume: { agoricNames, board, chainStorage } },
config,
) => {
/** @type {Issuer<'nat'>} */
Expand All @@ -46,9 +49,12 @@ export const updateFastUsdcPolicy = async (
harden({ feedPolicy: FeedPolicyShape }),
);

const storageNode = await E(chainStorage).makeChildNode(contractName);
const { storageNode, marshaller } = await makePublishingStorageKit(
contractName,
{ board, chainStorage },
);

await publishFeedPolicy(storageNode, feedPolicy);
await publishFeedPolicy(storageNode, marshaller, feedPolicy);
};

/**
Expand All @@ -67,6 +73,7 @@ export const getManifestForUpdateFastUsdcPolicy = (_utils, { options }) => {

// widely shared: name services
agoricNames: true,
board: true,
},
},
},
Expand Down
16 changes: 11 additions & 5 deletions packages/fast-usdc/src/fast-usdc.start.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { fromExternalConfig } from './utils/config-marshal.js';
* @import {Board} from '@agoric/vats'
* @import {ManifestBundleRef} from '@agoric/deploy-script-support/src/externalTypes.js'
* @import {BootstrapManifest} from '@agoric/vats/src/core/lib-boot.js'
* @import {Passable} from '@endo/pass-style'
* @import {LegibleCapData} from './utils/config-marshal.js'
* @import {FastUsdcSF} from './fast-usdc.contract.js'
* @import {FeedPolicy, FastUSDCConfig} from './types.js'
Expand Down Expand Up @@ -57,7 +58,10 @@ export const FastUSDCConfigShape = M.splitRecord({
* board: ERef<Board>;
* }} io
*/
const makePublishingStorageKit = async (path, { chainStorage, board }) => {
export const makePublishingStorageKit = async (
path,
{ chainStorage, board },
) => {
const storageNode = await E(chainStorage).makeChildNode(path);

const marshaller = await E(board).getPublishingMarshaller();
Expand Down Expand Up @@ -89,11 +93,13 @@ const POOL_METRICS = 'poolMetrics';

/**
* @param {ERef<StorageNode>} node
* @param {FeedPolicy} policy
* @param {ERef<Marshaller>} marshaller
* @param {FeedPolicy & Passable} policy
*/
const publishFeedPolicy = async (node, policy) => {
const publishFeedPolicy = async (node, marshaller, policy) => {
const feedPolicy = E(node).makeChildNode(FEED_POLICY);
await E(feedPolicy).setValue(JSON.stringify(policy));
const value = await E(marshaller).toCapData(policy);
await E(feedPolicy).setValue(JSON.stringify(value));
};

/**
Expand Down Expand Up @@ -211,7 +217,7 @@ export const startFastUSDC = async (
fastUsdcKit.resolve(harden({ ...kit, privateArgs }));
const { instance, creatorFacet } = kit;

await publishFeedPolicy(storageNode, feedPolicy);
await publishFeedPolicy(storageNode, marshaller, feedPolicy);

const {
issuers: fastUsdcIssuers,
Expand Down
2 changes: 2 additions & 0 deletions packages/fast-usdc/src/type-guards.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,11 @@ harden(PoolMetricsShape);
/** @type {TypedPattern<ChainPolicy>} */
export const ChainPolicyShape = {
attenuatedCttpBridgeAddress: EvmHashShape,
blockWindowSize: M.number(),
cctpTokenMessengerAddress: EvmHashShape,
confirmations: M.number(),
chainId: M.number(),
maxAmountPerBlockWindow: M.bigint(),
};
harden(ChainPolicyShape);

Expand Down
4 changes: 4 additions & 0 deletions packages/fast-usdc/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,16 @@ export interface PoolMetrics extends PoolStats {
export interface ChainPolicy {
/** `msg.sender` of DepositAndBurn to TokenMessenger must be an attenuated wrapper contract that does not contain `replaceDepositForBurn` */
attenuatedCttpBridgeAddress: EvmHash;
/** the number of blocks to consider for `maxAmountPerBlockWindow` */
blockWindowSize: number;
/** @see {@link https://developers.circle.com/stablecoins/evm-smart-contracts} */
cctpTokenMessengerAddress: EvmHash;
/** e.g., `1` for ETH mainnet 42161 for Arbitrum One. @see {@link https://chainlist.org/} */
chainId: EvmChainID;
/** the number of block confirmations to observe before reporting */
confirmations: number;
/** do not advance more than this amount per block window */
maxAmountPerBlockWindow: bigint;
}

export interface FeedPolicy {
Expand Down
30 changes: 25 additions & 5 deletions packages/fast-usdc/src/utils/chain-policies.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,70 +5,90 @@ export const ChainPolicies = /** @type {const} */ ({
MAINNET: {
Arbitrum: {
attenuatedCttpBridgeAddress: '0xe298b93ffB5eA1FB628e0C0D55A43aeaC268e347',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A',
chainId: 42161,
confirmations: 2,
confirmations: 2, // TODO mocked
maxAmountPerBlockWindow: 20_000_000_000n, // TODO mocked
},
Base: {
attenuatedCttpBridgeAddress: '0xB6615B2662b35fc3533F8479002e62D0523341De',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x1682Ae6375C4E4A97e4B583BC394c861A46D8962',
chainId: 8453,
confirmations: 2,
confirmations: 2, // TODO mocked
maxAmountPerBlockWindow: 20_000_000_000n, // TODO mocked
},
Ethereum: {
attenuatedCttpBridgeAddress: '0xBC8552339dA68EB65C8b88B414B5854E0E366cFc',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0xBd3fa81B58Ba92a82136038B25aDec7066af3155',
chainId: 1,
confirmations: 2,
confirmations: 2, // TODO mocked
maxAmountPerBlockWindow: 20_000_000_000n, // TODO mocked
},
Optimism: {
attenuatedCttpBridgeAddress: '0x48C5417ED570928eC85D5e3AD4e7E0EeD7dB1E2A',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x2B4069517957735bE00ceE0fadAE88a26365528f',
chainId: 10,
confirmations: 2,
confirmations: 2, // TODO mocked
maxAmountPerBlockWindow: 20_000_000_000n, // TODO mocked
},
Polygon: {
attenuatedCttpBridgeAddress: '0x32cb9574650AFF312c80edc4B4343Ff5500767cA',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x9daF8c91AEFAE50b9c0E69629D3F6Ca40cA3B3FE',
chainId: 137,
confirmations: 2,
confirmations: 2, // TODO mocked
maxAmountPerBlockWindow: 20_000_000_000n, // TODO mocked
},
},
TESTNET: {
// Arbitrum Sepolia
Arbitrum: {
attenuatedCttpBridgeAddress: '0xTODO',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
chainId: 421614,
confirmations: 2,
maxAmountPerBlockWindow: 20_000_000_000n,
},
// Base Sepolia
Base: {
attenuatedCttpBridgeAddress: '0xTODO',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
chainId: 84532,
confirmations: 2,
maxAmountPerBlockWindow: 20_000_000_000n,
},
// Ethereum Sepolia
Ethereum: {
attenuatedCttpBridgeAddress: '0xTODO',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
chainId: 11155111,
confirmations: 2,
maxAmountPerBlockWindow: 20_000_000_000n,
},
// OP Sepolia
Optimism: {
attenuatedCttpBridgeAddress: '0xTODO',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
chainId: 11155420,
confirmations: 2,
maxAmountPerBlockWindow: 20_000_000_000n,
},
// Polygon PoS Amoy
Polygon: {
attenuatedCttpBridgeAddress: '0xTODO',
blockWindowSize: 10,
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
chainId: 80002,
confirmations: 2,
maxAmountPerBlockWindow: 20_000_000_000n,
},
},
});
Expand Down

0 comments on commit 5043b8d

Please sign in to comment.