Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,33 @@ evm_version = 'paris'
43 = { key = "empty", url = "https://evmx.cloud.blockscout.com/api?" }
421614 = { key = "${ARBISCAN_API_KEY}", url = "https://api-sepolia.arbiscan.io/api?" }
11155420 = { key = "${OPTIMISM_API_KEY}", url = "https://optimism-sepolia.blockscout.com/api?" }

[labels]
0x935b06902cA5C8bb4C76e18738561c294D377A93 = "AddressResolver"
0xD1586EaaA0d473E6655c11A927cE4FbED648F3BF = "AddressResolverImpl"
0xECa623A443F21B705714D4A0f810d0A5D135FF6F = "AsyncDeployer"
0x1B0ea1b79B526dD3d5889Bb33Dbd24f790C23102 = "AsyncDeployerImpl"
0xD044f27A9c5EE4f92EF0e38685276adFDF13E90E = "AuctionManager"
0xC72BE9e639DA23570fa1eF2fF2cb7901a081916F = "AuctionManagerImpl"
0x72f4C225B4B4f0F9608a50aEe17dA9e11dcb94b2 = "Configurations"
0x351De7e4275dA7f49F75363e4E7ea86Dfe050501 = "ConfigurationsImpl"
0x5E9d1072B60D6c752B1593F5937393413372E5eF = "DeployForwarder"
0x1b7752F0039E80Aa38f7CF8b5d18798dD2ac1597 = "DeployForwarderImpl"
0x526796AC60e45CBB9b17c654C9447Baf160C084d = "ERC1967Factory"
0xA07208F9e7aE243F922317ab6604DC9F86822406 = "FeesManager"
0xbD22EDD6559B28614f44D1c768EC26491CDE1cDD = "FeesManagerImpl"
0xe2054B575664dfDBD7a7FbAf2B12420ae88DE0FF = "FeesPool"
0x38e24A2F157817b830F36A35b862F24B1494d1aD = "PromiseResolver"
0x39b5D3FBBa1BC28438e25955aaB412C7576eCd61 = "ReadPrecompile"
0x2E928C000bdC1f90716B05cE2D7182C9FA081d31 = "RequestHandler"
0xD38ae1a6C410c7681ac464bd60009198406035Ed = "RequestHandlerImpl"
0xb14a7763f09eCbd47bC5230D6170547a22834a82 = "SchedulePrecompile"
0x4C846eCa55ad8cF19B9D5d906225da7b565174C1 = "Watcher"
0x2920F4FB50343EF2b33096650cE234E8aF9E8556 = "WatcherImpl"
0x393007B660a00970b25E34FEd6506CE96120f8e2 = "WritePrecompile"
0x0026c4736E57fE2817b53f6df1E0808c3a61984d = "WritePrecompileImpl"
0xee1Aef0b06f63Aa1c881838794Dd0876462c2B0d = "ContractFactoryPlug"
0xbDE0D2da12F703Ccd275d721214745BccDCAD124 = "FastSwitchboard"
0x5F77550E3072c913A20B2fbdAb14026fe0E8B450 = "FeesPlug"
0x5e1641B190B71ECCc85b1ECe934F31cD9b3dcF7a = "Socket"
0xaC61f5696e0E2636dA7bD69827380f2Ab41A3C38 = "SocketBatcher"
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"upload": "tsx script/runIntegrationTests.ts -u",
"scheduler": "tsx script/runIntegrationTests.ts -s",
"insufficient": "tsx script/runIntegrationTests.ts -i",
"revert": "tsx script/runIntegrationTests.ts -v"
"revert": "tsx script/runIntegrationTests.ts -v",
"deployment": "tsx script/runIntegrationTests.ts -d"
}
}
20 changes: 13 additions & 7 deletions script/runIntegrationTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { executeUploadTests } from './tests/upload_tests.js';
import { executeSchedulerTests } from './tests/scheduler_tests.js';
import { executeInsufficientFeesTests } from './tests/insufficient_tests.js';
import { executeRevertTests } from './tests/revert_tests.js';
import { executeDeployTests } from './tests/deploy_tests.js';

// Help function
function showHelp(): void {
Expand Down Expand Up @@ -38,6 +39,7 @@ function parseFlags(args: string[]): TestFlags {
scheduler: args.includes('-s') || args.includes('-a'),
insufficient: args.includes('-i') || args.includes('-a'),
revert: args.includes('-v') || args.includes('-a'),
deployment: args.includes('-d') || args.includes('-a'),
all: args.includes('-a')
};
}
Expand All @@ -59,31 +61,35 @@ async function main(): Promise<void> {

// Execute tests based on flags
if (flags.write) {
await executeWriteTests(chains.evmxChain, chains.arbChain);
await executeWriteTests(chains);
}

if (flags.read) {
await executeReadTests(chains.evmxChain, chains.arbChain);
await executeReadTests(chains);
}

if (flags.trigger) {
await executeTriggerTests(chains.evmxChain, chains.arbChain, chains.opChain);
await executeTriggerTests(chains);
}

if (flags.upload) {
await executeUploadTests(chains.evmxChain, chains.arbChain);
await executeUploadTests(chains);
}

if (flags.scheduler) {
await executeSchedulerTests(chains.evmxChain, chains.arbChain);
await executeSchedulerTests(chains);
}

if (flags.insufficient) {
await executeInsufficientFeesTests(chains.evmxChain, chains.arbChain);
await executeInsufficientFeesTests(chains);
}

if (flags.revert) {
await executeRevertTests(chains.evmxChain, chains.arbChain);
await executeRevertTests(chains);
}

if (flags.deployment) {
await executeDeployTests(chains);
}

console.log(`${COLORS.GREEN}All selected tests completed successfully!${COLORS.NC}`);
Expand Down
115 changes: 115 additions & 0 deletions script/tests/deploy_tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { parseAbi, type Address } from 'viem';
import { deployAppGateway, deployOnchain, sendTransaction } from '../utils/deployer.js';
import { depositFunds, withdrawFunds } from '../utils/fees-manager.js';
import { fetchForwarderAndOnchainAddress, getTxDetails, selectRandomChains } from '../utils/helpers.js';
import { ContractAddresses, ChainConfig } from '../utils/types.js';
import { COLORS, URLS } from '../utils/constants.js';

// Deploy AppGateway from onchain tests
export async function runDeployAppGatewayTests(
addresses: ContractAddresses,
evmxChain: ChainConfig,
selectedChains: ChainConfig[]
): Promise<void> {
console.log(`${COLORS.CYAN}Running all AppGateway onchain deployment tests...${COLORS.NC}`);

if (!addresses.appGateway) {
throw new Error('Required addresses not found');
}

console.log(`${COLORS.CYAN}Validate all deployments from AppGateway${COLORS.NC}`);

const appGatewayAbi = parseAbi([
'function contractValidation(uint32 chainSlug_) external'
]);

const hash = await sendTransaction(
addresses.appGateway,
'contractValidation',
[selectedChains[0].chainId],
evmxChain,
appGatewayAbi
);

// Waiting for transaction finalized
console.log(`${COLORS.CYAN}Waiting for transaction finalized${COLORS.NC}`);
let attempt = 0;
let status = '';
const interval = 1000; // 1 seconds
const maxAttempts = 60; // 60 seconds
const maxSeconds = interval * maxAttempts / 1000;
const endpoint = `${URLS.EVMX_API_BASE}/getDetailsByTxHash`;

while (true) {
const response = await getTxDetails(endpoint, hash);
status = response?.response?.[0]?.status;

if (status === 'COMPLETED') {
console.log(`Transaction completed as expected.`);
if (attempt > 0) process.stdout.write('\r\x1b[2K');
break;
}

if (attempt >= maxAttempts) {
console.log();
throw new Error(`Could not validate transaction completion after ${maxSeconds} seconds. Current status: ${status}`);
}

const elapsed = attempt * interval / 1000;
process.stdout.write(`\r${COLORS.YELLOW}Waiting for transaction completion:${COLORS.NC} ${elapsed}s / ${maxSeconds}s`);

await new Promise(resolve => setTimeout(resolve, interval));
attempt++;
}

console.log(`${COLORS.GREEN}All trigger tests completed successfully!${COLORS.NC}`);
}

export async function executeDeployTests(
chains: Record<string, ChainConfig>,
): Promise<void> {
console.log(`${COLORS.GREEN}=== Running Deployment Tests ===${COLORS.NC}`);

const addresses: ContractAddresses = {
appGateway: await deployAppGateway('DeploymentAppGateway', chains.evmxChain),
deployForwarders: [] as Address[],
deployOnchain: [] as Address[],
};

await depositFunds(addresses.appGateway, chains.arbMainnetChain, chains.evmxChain);

// Selects two random chains out of the available ones
const randomChains = selectRandomChains(chains, 1);

try {
await deployOnchain(randomChains[0].chainId, addresses.appGateway, chains.evmxChain);

let chainAddresses = await fetchForwarderAndOnchainAddress('noPlugNoInititialize', randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
addresses.deployForwarders!.push(chainAddresses.forwarder);
addresses.deployOnchain!.push(chainAddresses.onchain);

chainAddresses = await fetchForwarderAndOnchainAddress('noPlugInitialize', randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
addresses.deployForwarders!.push(chainAddresses.forwarder);
addresses.deployOnchain!.push(chainAddresses.onchain);

chainAddresses = await fetchForwarderAndOnchainAddress('plugNoInitialize', randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
addresses.deployForwarders!.push(chainAddresses.forwarder);
addresses.deployOnchain!.push(chainAddresses.onchain);

chainAddresses = await fetchForwarderAndOnchainAddress('plugInitialize', randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
addresses.deployForwarders!.push(chainAddresses.forwarder);
addresses.deployOnchain!.push(chainAddresses.onchain);

chainAddresses = await fetchForwarderAndOnchainAddress('plugInitializeTwice', randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
addresses.deployForwarders!.push(chainAddresses.forwarder);
addresses.deployOnchain!.push(chainAddresses.onchain);

chainAddresses = await fetchForwarderAndOnchainAddress('plugNoInitInitialize', randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
addresses.deployForwarders!.push(chainAddresses.forwarder);
addresses.deployOnchain!.push(chainAddresses.onchain);

await runDeployAppGatewayTests(addresses, chains.evmxChain, randomChains);
} finally {
await withdrawFunds(addresses.appGateway, chains.arbMainnetChain, chains.evmxChain);
}
}
24 changes: 16 additions & 8 deletions script/tests/insufficient_tests.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { parseAbi, type Address, type Hash } from 'viem';
import { deployAppGateway, deployOnchain, sendTransaction } from '../utils/deployer.js';
import { depositFunds, withdrawFunds } from '../utils/fees-manager.js';
import { selectRandomChains } from '../utils/helpers.js';
import { ChainConfig } from '../utils/types.js';
import { COLORS, CHAIN_IDS, AMOUNTS } from '../utils/constants.js';
import { COLORS, AMOUNTS } from '../utils/constants.js';

// Insufficient fees tests
export async function runInsufficientFeesTests(
Expand Down Expand Up @@ -104,15 +105,22 @@ export async function runInsufficientFeesTests(
}

export async function executeInsufficientFeesTests(
evmxChain: ChainConfig,
arbChain: ChainConfig
chains: Record<string, ChainConfig>,
): Promise<void> {
console.log(`${COLORS.GREEN}=== Running Insufficient fees Tests ===${COLORS.NC}`);

const appGateway = await deployAppGateway('ReadAppGateway', evmxChain, 0n);
const appGateway = await deployAppGateway('ReadAppGateway', chains.evmxChain, 0n);

await depositFunds(appGateway, arbChain, evmxChain);
await deployOnchain(CHAIN_IDS.OP_SEP, appGateway, evmxChain);
await runInsufficientFeesTests('multichain', CHAIN_IDS.OP_SEP, appGateway, evmxChain);
await withdrawFunds(appGateway, arbChain, evmxChain);
await depositFunds(appGateway, chains.arbMainnetChain, chains.evmxChain);

// Select one random chain for insufficient fees tests
const randomChains = selectRandomChains(chains, 1);
const selectedChain = randomChains[0];

try {
await deployOnchain(selectedChain.chainId, appGateway, chains.evmxChain);
await runInsufficientFeesTests('multichain', selectedChain.chainId, appGateway, chains.evmxChain);
} finally {
await withdrawFunds(appGateway, chains.arbMainnetChain, chains.evmxChain);
}
}
48 changes: 27 additions & 21 deletions script/tests/read_tests.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { parseAbi, type Address } from 'viem';
import { parseAbi } from 'viem';
import { deployAppGateway, deployOnchain, sendTransaction } from '../utils/deployer.js';
import { depositFunds, withdrawFunds } from '../utils/fees-manager.js';
import { awaitEvents, fetchForwarderAndOnchainAddress } from '../utils/helpers.js';
import { awaitEvents, fetchForwarderAndOnchainAddress, selectRandomChains } from '../utils/helpers.js';
import { ContractAddresses, ChainConfig } from '../utils/types.js';
import { COLORS, CHAIN_IDS } from '../utils/constants.js';
import { COLORS } from '../utils/constants.js';

// Read tests
export async function runReadTests(
Expand All @@ -18,7 +18,7 @@ export async function runReadTests(
'function triggerAltRead(address forwarder1, address forwarder2) external'
]);

if (!addresses.appGateway || !addresses.opForwarder || !addresses.arbForwarder) {
if (!addresses.appGateway || !addresses.chain2Forwarder || !addresses.chain1Forwarder) {
throw new Error('Required addresses not found');
}

Expand All @@ -32,7 +32,7 @@ export async function runReadTests(
await sendTransaction(
addresses.appGateway,
'triggerParallelRead',
[addresses.arbForwarder],
[addresses.chain1Forwarder],
evmxChain,
abi
);
Expand All @@ -42,35 +42,41 @@ export async function runReadTests(
await sendTransaction(
addresses.appGateway,
'triggerAltRead',
[addresses.opForwarder, addresses.arbForwarder],
[addresses.chain2Forwarder, addresses.chain1Forwarder],
evmxChain,
abi
);
await awaitEvents(numberOfRequests * 2n, 'ValueRead(address,uint256,uint256)', addresses.appGateway, evmxChain);
await awaitEvents(numberOfRequests, 'ValueRead(address,uint256,uint256)', addresses.appGateway, evmxChain);
}

export async function executeReadTests(
evmxChain: ChainConfig,
arbChain: ChainConfig
chains: Record<string, ChainConfig>,
): Promise<void> {
console.log(`${COLORS.GREEN}=== Running Read Tests ===${COLORS.NC}`);

const addresses: ContractAddresses = {
appGateway: await deployAppGateway('ReadAppGateway', evmxChain)
appGateway: await deployAppGateway('ReadAppGateway', chains.evmxChain)
};

await depositFunds(addresses.appGateway, arbChain, evmxChain);
await deployOnchain(CHAIN_IDS.ARB_SEP, addresses.appGateway, evmxChain);
await deployOnchain(CHAIN_IDS.OP_SEP, addresses.appGateway, evmxChain);
await depositFunds(addresses.appGateway, chains.arbMainnetChain, chains.evmxChain);

// Selects two random chains out of the available ones
const randomChains = selectRandomChains(chains, 2);

const arbAddresses = await fetchForwarderAndOnchainAddress('multichain', CHAIN_IDS.ARB_SEP, addresses.appGateway, evmxChain);
addresses.arbForwarder = arbAddresses.forwarder;
addresses.arbOnchain = arbAddresses.onchain;
try {
await deployOnchain(randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
await deployOnchain(randomChains[1].chainId, addresses.appGateway, chains.evmxChain);

const opAddresses = await fetchForwarderAndOnchainAddress('multichain', CHAIN_IDS.OP_SEP, addresses.appGateway, evmxChain);
addresses.opForwarder = opAddresses.forwarder;
addresses.opOnchain = opAddresses.onchain;
const chain1Addresses = await fetchForwarderAndOnchainAddress('multichain', randomChains[0].chainId, addresses.appGateway, chains.evmxChain);
addresses.chain1Forwarder = chain1Addresses.forwarder;
addresses.chain1Onchain = chain1Addresses.onchain;

await runReadTests(addresses, evmxChain);
await withdrawFunds(addresses.appGateway, arbChain, evmxChain);
const chain2Addresses = await fetchForwarderAndOnchainAddress('multichain', randomChains[1].chainId, addresses.appGateway, chains.evmxChain);
addresses.chain2Forwarder = chain2Addresses.forwarder;
addresses.chain2Onchain = chain2Addresses.onchain;

await runReadTests(addresses, chains.evmxChain);
} finally {
await withdrawFunds(addresses.appGateway, chains.arbMainnetChain, chains.evmxChain);
}
}
Loading