Conversation
🧪 E2E Test StatusE2E tests are non-blocking and validate real blockchain interactions. Failures may occur due to network issues, RPC rate limits, or external service downtime. Test Runs (Newest First):
|
Proof of TestRan |
PR SummaryMedium Risk Overview Updates the Also bumps Solidity compiler versions for the Written by Cursor Bugbot for commit 39dadc2. This will update automatically on new commits. Configure here. |
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
fabianhug
left a comment
There was a problem hiding this comment.
small change requests, I can approve. It's up to you if you want to implement them, I don't think they're blocking
| ): Promise<void> { | ||
| try { | ||
| await operation() | ||
| assert.fail(`Expected ${expectedErrorClass.name} to be thrown, but operation succeeded`) |
There was a problem hiding this comment.
when the operation succeeds, ie doesnt throw, this throws an err that will be caught by L16. L16 won't match the expected err class, and then produce a confusing double-wrapped err message instead of something clear like Operation succeeded but should have failed. I think this even affects every negative test in the suite.
Is this intentional?
| const expectedMessage = `Error Code: ${instance.name}. Error Number: ${instance.code.toString(10)}` | ||
|
|
||
| if ( | ||
| typeof error === 'object' && |
There was a problem hiding this comment.
| typeof error === 'object' && | |
| typeof error === 'object' && | |
| error !== null && |
typeof null === 'object' is true in JS, so the guard typeof error === 'object' passes for null. The func sig accepts unknown so it should be defensive.
| } | ||
|
|
||
| console.log(`Starting surfpool (${SURFPOOL_OFFLINE ? 'offline' : `upstream: ${UPSTREAM_RPC_URL}`})...`) | ||
| const logFd = fs.openSync(SURFPOOL_LOG, 'w') |
There was a problem hiding this comment.
this is never closed, I think we should close this via fs.closeSync(logFd) after spawn()
# Conflicts: # pnpm-lock.yaml
|
Note:
Refer to the error in the CI run: https://github.com/LayerZero-Labs/devtools/actions/runs/22680227992/job/65758017320?pr=1897#step:5:2160 |
|
Why evmVersion: 'cancun' was added to the Hardhat compiler settings: The mcopy opcode is a Cancun EVM feature — Forge already defaults to Cancun, but Hardhat's Solc 0.8.24 defaults to paris, which doesn't support mcopy. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| "lint:sol": "solhint 'contracts/**/*.sol'", | ||
| "test": "$npm_execpath run test:forge && $npm_execpath run test:hardhat", | ||
| "test:anchor": "anchor test", | ||
| "test:anchor": "OFT_ID=$(node scripts/resolve-oft-id.js) anchor build --no-idl && $npm_execpath exec ts-mocha -b -p ./tsconfig.json -t 10000000 test/anchor/index.test.ts", |
There was a problem hiding this comment.
OFT_ID env var not available to test runner
Low Severity
In the test:anchor script, the shell syntax OFT_ID=$(node scripts/resolve-oft-id.js) anchor build --no-idl && ... sets OFT_ID only as an inline env var for the anchor build command. After &&, the ts-mocha process does not inherit OFT_ID. The constants.ts file reads process.env.OFT_ID but will always fall through to the readKeypairPublicKey fallback. This works today because both paths read the same keypair file, but anchor build itself doesn't use the OFT_ID env var either — the assignment is effectively dead code on both sides. Using export OFT_ID=... && would match the apparent intent.


This PR combines 2 issues into one.
DEVREL-1132 test(oft-solana): add solana tests
Problem
Solution
Changes
examples/oft-solana/test/anchorwith suites, helpers, constants, and harness setup.examples/oft-solana/scripts/generate-features.tsand thetest:generate-featuresscript.examples/oft-solana/Anchor.toml,examples/oft-solana/package.json,.gitignore, andexamples/oft-solana/pnpm-lock.yaml.How to test
pnpm test:anchoranchor testAnchor.tomlscript to invokepnpm test:anchor.DEVREL-1077 migrate oft-solana anchor tests from solana-test-validator to Surfpool
Changes
test:generate-featuresscript withresolve-oft-id.jsfor dynamic OFT program ID resolution.index.test.tsto start Surfpool, clone LayerZero programs, and reset infrastructure accounts.got-shim.cjswith local program keypair generation for offline/local testing.layerzero-infrastructure.test.tsto use Surfpool RPC calls for program cloning.pnpm test:anchorwith Surfpool environment variables.generate-features.ts(92 lines) andtest:generate-featuresnpm script.Example Run
Setting up test environment...
Starting surfpool (upstream: https://api.mainnet-beta.solana.com)...
Waiting for surfnet to start...
Surfnet started.
Priming LayerZero programs from https://api.mainnet-beta.solana.com...
Cloning endpoint...
Cloning uln...
Cloning executor...
Cloning pricefeed...
Cloning dvn...
Program oft (27cGdR9zfM4G1TVXxZQqCv6ebHbhczBFp9rpdr9g9wRR) not found upstream; deploying locally.
Skipping program authority update for OFT: Surfnet RPC surfnet_setProgramAuthority failed: Invalid program account 27cGdR9zfM4G1TVXxZQqCv6ebHbhczBFp9rpdr9g9wRR
Deploying OFT program to Surfnet...
Program Id: 27cGdR9zfM4G1TVXxZQqCv6ebHbhczBFp9rpdr9g9wRR
Signature: 2qqG4GJVTupgkwNP5wVsJF1BnhAZL3jGk1EHuQHjGtZXEQvpkp2seMHN99t2J6tSbEAKmE34WXMDLYkJR5X4sSbH
Test environment ready.
LayerZero Infrastructure
LayerZero Infrastructure Setup
✔ Init Endpoint (1640ms)
✔ Init Executor (370ms)
✔ Init PriceFeed (392ms)
✔ Init DVN (400ms)
✔ Init UltraLightNode (1221ms)
✔ Init address lookup table (1185ms)
Instruction Tests
init_oft
✔ rejects init_oft when shared decimals exceed mint decimals (1316ms)
✔ initializes native and adapter OFTs (712ms)
✔ sets OApp libraries and nonces (784ms)
set_oft_config
native config
✔ rejects unauthorized config updates (461ms)
✔ rejects invalid default fee bps (40ms)
✔ sets minimum default fee bps (309ms)
✔ sets maximum default fee bps (410ms)
✔ updates admin, delegate, and fee (2017ms)
adapter config
✔ rejects unauthorized config updates (458ms)
✔ rejects invalid default fee bps (49ms)
✔ sets minimum default fee bps (304ms)
✔ sets maximum default fee bps (409ms)
✔ updates admin, delegate, and fee (1993ms)
set_peer_config
native peer config
✔ rejects unauthorized peer updates (521ms)
✔ rejects invalid fee bps (109ms)
✔ rejects invalid enforced options (80ms)
✔ sets peer addresses and enforced options (907ms)
✔ sets outbound rate limit values (790ms)
adapter peer config
✔ rejects unauthorized peer updates (511ms)
✔ rejects invalid fee bps (150ms)
✔ rejects invalid enforced options (89ms)
✔ sets peer addresses and enforced options (904ms)
✔ sets outbound rate limit values (793ms)
quote instructions
native quotes
✔ rejects slippage when min amount exceeds computed amount (337ms)
✔ returns quoteSend and quoteOft results (338ms)
adapter quotes
✔ rejects slippage when min amount exceeds computed amount (332ms)
✔ returns quoteSend and quoteOft results (345ms)
send instruction
native send failures
✔ rejects slippage when min amount exceeds computed amount (255ms)
✔ rejects invalid sender when remaining accounts are tampered (245ms)
adapter send failures
✔ rejects slippage when min amount exceeds computed amount (258ms)
✔ rejects invalid sender when remaining accounts are tampered (242ms)
LayerZero Simulation
✔ simulates send and receive for native (12990ms)
✔ simulates send and receive for adapter (3226ms)
withdraw_fee
native fee withdrawal
✔ rejects unauthorized fee withdrawal (449ms)
✔ rejects withdrawal above available fees (800ms)
✔ withdraws available fees (1191ms)
adapter fee withdrawal
✔ rejects unauthorized fee withdrawal (395ms)
✔ rejects withdrawal above available fees (860ms)
✔ withdraws available fees (1133ms)
Cleaning up test environment...
Cleanup completed.
45 passing (1m)
How to test
pnpm test:anchorfromexamples/oft-solana.