feat(deploy): enhance Hardhat configuration and add deployment patches#949
Open
lionakhnazarov wants to merge 69 commits into
Open
feat(deploy): enhance Hardhat configuration and add deployment patches#949lionakhnazarov wants to merge 69 commits into
lionakhnazarov wants to merge 69 commits into
Conversation
…rget logic Added a new constant to handle minimum difficulty blocks in Bitcoin testnet scenarios. Updated the retarget logic to accommodate this new target, ensuring that the relay can correctly validate post-retarget conditions. Enhanced test coverage to verify behavior with the new difficulty target in various scenarios.
- Updated to load environment variables from a parent directory and set timeouts and gas prices based on environment variables. - Introduced new deployment scripts for Sepolia, including for initializing LightRelay with Bitcoin testnet genesis block. - Added deployment patches to handle existing deployments gracefully, including checks for already deployed contracts and avoiding redundant operations. - Implemented a script to apply patches to vendored deploy scripts, ensuring compatibility with existing deployment processes. - Enhanced the script for approving DKG results with additional command-line options and error handling.
…upport - Loaded environment variables from a parent directory to improve configuration management. - Updated deployment settings to include timeouts and gas prices based on environment variables. - Added support for Bitcoin Testnet4 in the Electrum client and updated network handling. - Introduced new error types and functions in the WalletRegistry contract for better governance and error handling. - Updated deployment artifacts for Sepolia with new contract addresses and transaction hashes.
lrsaturnino
reviewed
Apr 13, 2026
Member
lrsaturnino
left a comment
There was a problem hiding this comment.
yarn lint in typescript/ fails with 15 new errors across files introduced by this PR — all absent on main.
Affected files:
scripts/approve-dkg-result.ts— 3 prettier + 1 new-cap (line 170)scripts/e2e-deposit.ts— 2 prettierscripts/request-redemption.ts— 2 prettiersrc/lib/bitcoin/client-with-network-override.ts— 4 prettiersrc/lib/electrum/client.ts— 1 prettier + 2 valid-jsdoc (line 280, missing@returnsand@param electrumongetNetworkFromElectrum)
12 of the 15 are auto-fixable with yarn lint --fix. The remaining 3 need manual attention: the new-cap violation in approve-dkg-result.ts:170 and the two JSDoc gaps in client.ts:280.
- Added new-cap rule exceptions for specific constructors in ESLint configuration to accommodate BigNumber usage. - Introduced a new .yarnrc.yml file to set the node linker to node-modules for Yarn. - Updated package.json to remove duplicate dependency entry for @mysten/sui. - Refactored various scripts for improved readability and consistency in logging.
- Updated package.json and yarn.lock to change the version of @solana/web3.js from ^1.98.0 to ~1.97.0 for better compatibility with existing code.
…tions - Updated package.json to include a resolutions field for secp256k1 version 4.0.3. - Modified yarn.lock to reflect the updated version of secp256k1 and its dependencies, including elliptic.
…kage.json - Introduced an overrides field in package.json to ensure secp256k1 version 4.0.3 is used consistently across the project.
…olutions - Updated package.json to specify secp256k1 version 4.0.4 in the resolutions field. - Modified yarn.lock to reflect the updated version of secp256k1 and its dependencies.
…lows - Updated Node.js version from 14.x to 18.15.0 in multiple workflow jobs. - Upgraded setup-node action from v3 to v4 for improved compatibility. - Added Corepack enablement step to utilize Yarn from the lockfile. - Adjusted package.json to reflect the new Node.js engine requirement and added Yarn version specification.
…pport - Introduced .pnp.cjs and .pnp.loader.mjs files to enable Yarn Plug'n'Play (PnP) functionality. - Updated package.json to remove the overrides for secp256k1 and adjusted resolutions accordingly. - Modified yarn.lock to reflect the new dependencies and their versions, including elliptic and node-addon-api.
…dling - Updated package.json to specify Yarn version 4.12.0. - Modified .pnp.cjs to include a new pnpZipBackend configuration for improved zip handling. - Refactored the read method in FileHandle class to support both Buffer and ArrayBufferView types. - Introduced LibZipImpl class for enhanced zip file management and error handling.
- Added .yarn/install-state.gz to .gitignore to exclude Yarn 4 local state files. - Removed obsolete .pnp.cjs and .pnp.loader.mjs files as they are no longer needed for the project.
- Introduced function to handle ether balance checks for contracts in fraud tests. - Added function to streamline assertions in redemption tests, ensuring consistent comparison of proposal tuples. - Updated multiple test cases to utilize these new utility functions for improved readability and maintainability. - Refactored gas reimbursement checks in BTC depositor tests for clarity and consistency.
…nd yarn.lock - Added @solana/web3.js version 1.97.0 to the resolutions and overrides fields in package.json. - Updated yarn.lock to reflect the new version of @solana/web3.js and its dependencies.
- Reorganized environment variable loading in hardhat.config.ts for consistency. - Enhanced formatting in deployment scripts for better readability, including consistent indentation and line breaks. - Updated log messages for clarity in various deployment patches. - Removed unnecessary strict mode declarations from deployment scripts.
…thod data - Expanded gasReporterOutput.json to include detailed method information for various contracts. - Added gas data and call counts for methods in BTCUtils, EcdsaDkgValidator, and WalletRegistry. - Enhanced the structure of the output file for better readability and analysis of gas usage.
- Updated the gas limit in MaintainerProxy tests to allow for a small headroom, ensuring more accurate gas usage measurements across different environments. - This change enhances the reliability of gas consumption assertions in the test suite.
- Introduced new Bitcoin address configurations for testnet4, including P2PKH, P2WPKH, P2SH, and P2WSH types. - Added corresponding redeemer output scripts and scriptPubKeys for each address type. - Enhanced the btcAddressFromPublicKey mapping with testnet4 public keys and addresses for improved testing coverage.
- Added missing newline characters at the end of Bridge.json, TBTC.json, TBTCVault.json, and WalletRegistry.json to comply with JSON formatting standards. - This change ensures better compatibility with various tools and prevents potential issues during file parsing.
… details - Expanded gasReporterOutput.json to include a comprehensive list of methods and their respective gas data for multiple contracts. - Enhanced the output structure for improved readability and analysis of gas usage metrics across the project.
- Add BREAKING CHANGE notice to initializeSepolia() JSDoc: testnet3 to testnet4 migration is silent at compile/runtime due to shared address prefixes (tb1/m/2) -- callers must update their Bitcoin tooling - Narrow Electrum server.features error swallow to JSON-RPC -32601 only; previously caught any error containing "not found" - Wrap Promise.all in getTransactionHistory with try/catch to surface per-transaction fetch errors with context - Reorder testnet4 Electrum URLs: SSL endpoints first, TCP last - Remove --private-key CLI flag from approve-dkg-result.ts; private keys in argv are visible in ps aux and shell history; use PRIVATE_KEY env var - Make loadWalletRegistryAbi async and use fs.promises.readFile; wrap JSON.parse in try/catch for better error messages - Fix NaN propagation in hardhat.config.ts gasPrice when GAS_PRICE_GWEI is absent or malformed; default to 5 gwei - Add version pins to all ten deploy-patches header comments; replace fs.writeFileSync with fs.promises.writeFile and add try/catch for JSON.parse in 07_deploy_token_staking.js - Add .ubsignore to suppress vendor coding-style warnings in deploy-patches - Add break; semicolons to switch cases (UBS requires semicolons on break)
3 tasks
Extract difficulty determination from evaluateProofDifficulty into a dedicated helper that skips leading MIN_DIFFICULTY_TARGET headers (testnet4 BIP94 exception) and reverts if no non-minimum-difficulty header matches the relay epoch. Removes the implicit return 1 path that allowed an attacker to pass SPV proofs using only trivial DIFF1 headers.
…Relay Add virtual isValidPreRetargetTarget / isValidPostRetargetTarget helpers to LightRelay (strict by default) and wire them into the retarget proof loop. SepoliaLightRelay overrides both to also accept MIN_DIFFICULTY_TARGET headers, which is the correct scope for the testnet4 BIP94 exception.
…util Replace import * as crypto from "crypto" (Node.js-only) with BitcoinHashUtils.computeHash256 (uses ethers sha256, works in browser and Node). Also replace the switch in fromDefaultConfig with an object lookup map and convert getTransactionHistory to Promise.allSettled for explicit rejection surfacing.
Skip minimum-difficulty (DIFF1) headers in determineRequestedDifficulty only when the relay's current and previous epoch difficulty is above 1. When the relay epoch is already difficulty 1 (dev/test setups using SepoliaLightRelay.setDifficultyFromHeaders with DIFF1 headers), DIFF1 proof headers must match the epoch directly instead of being skipped. Also reformat LightRelay.sol and SepoliaLightRelay.sol to satisfy the contracts-format CI Prettier check.
Convert the getTransactionHistory promise chain to async/await to satisfy the pre-commit hook and Prettier checks. The collectTxs helper and the redundant no-op .catch() are inlined, preserving identical runtime behaviour. Also convert a pre-existing FIXME marker to a plain comment (technical note preserved).
…dity Regenerate TypeScript api-reference after line number shifts in client.ts (caused by the recent format commit removing a blank line). Remove packageManager field from solidity/package.json. The field was set to yarn@4.12.0 but the lockfile is yarn 1.x format, making them inconsistent. The reusable solidity-docs CI workflow uses yarn 1.22.22 without Corepack, so the field caused yarn install to fail with a version mismatch error.
…bility When the CI Yarn v1 shim resolves @openzeppelin/hardhat-upgrades@1.22.0 transitive deps without the Berry lockfile, it selects the latest @openzeppelin/upgrades-core@^1.20.0 (currently 1.44.2), which pulls in cbor@^10. cbor@10 requires Node >=20 and breaks the install on Node 18. Pin upgrades-core to the version already recorded in the Berry lockfile (1.20.0) so Yarn v1 also uses the Node-18-compatible cbor@^8.0.0.
…errides Add direct unit tests for the two security-critical changes introduced in the testnet4 fix commits: 1. BitcoinTx.determineRequestedDifficulty: expose the internal library function via TestBitcoinTx and test six cases covering the new conditional DIFF1 skip (epoch > 1 skips; epoch = 1 does not skip; all-DIFF1 headers revert; mismatched difficulty reverts; empty input reverts). 2. SepoliaLightRelay: add TestSepoliaLightRelay wrapper that surfaces the internal isValidPreRetargetTarget / isValidPostRetargetTarget overrides as public functions, then test setDifficultyFromHeaders and both target-validation hooks (DIFF1 accepted; matching target accepted; mismatched non-DIFF1 rejected; non-owner reverts).
CI jobs run Yarn v1.22.22 (corepack enable does not override the setup-node shim) and re-resolve deps fresh from npm, ignoring the Berry lockfile. Transitive packages pulled in via github: deps -- notably @typescript-eslint/parser via thesis/eslint-config HEAD -- have drifted to require Node >=18.18.0 while CI uses Node 18.15.0. Add a Yarn v1 .yarnrc with ignore-engines to prevent install failures. Yarn Berry reads .yarnrc.yml and ignores .yarnrc entirely, so this change has no effect on local Berry installs or Berry-based CI steps.
actions/setup-node@v4 installs Yarn v1 and its shim takes precedence over corepack. Without a packageManager field in package.json, corepack cannot infer the Berry version. Explicitly calling corepack prepare forces Berry 4.12.0, which can read the Berry-format lockfile and resolves the correct pinned versions (smock 2.3.4, hardhat 2.12.5, upgrades-core 1.20.0) instead of re-resolving from npm registry.
The root yarn.lock is Classic-format. When Berry is activated globally via corepack, it tries to migrate the root lockfile but --immutable blocks the write. Install root deps with the default Yarn v1 first, then activate Berry 4.12.0 for the solidity subdirectory install.
- Use template literals for DIFF1_HEADER strings (prefer-template) - Reformat context() call to single-line where description fits in 80 chars - Switch template literals for "0x" + variable concatenations - Reformat long function call arguments to multi-line - Replace ;[a, b] = destructure with explicit signers[0]/[1] assignment (avoids @typescript-eslint/no-extra-semi) - Flatten single-line method chain (prettier)
Use const [g, o] = getSigners() destructuring then assign to the outer let variables, avoiding both no-extra-semi (from ;[...]) and prefer-destructuring (from arr[index] assignment).
…orkflow The reusable keep-network/ci workflow runs yarn install --frozen-lockfile using Yarn v1 which cannot read the Berry-format lockfile. Use the preProcessingCommand hook (runs before install) to activate Berry 4.12.0 via corepack so the install step uses the correct Yarn version.
corepack enable installs a newer corepack version that calls URL.canParse internally, which requires Node >=18.17.0. Since the reusable workflow pins Node 18.15.0, corepack crashes before Berry even launches. Installing yarn@4.12.0 directly via npm bypasses corepack entirely; the resulting yarn shim runs Berry with whichever node is active (18.15.0), which works fine.
The reusable keep-network/ci solidity-docs workflow runs under Node 20 during preProcessingCommand but then switches to Node 18.15.0 via setup-node@v3. A corepack shim installed under Node 20 calls URL.canParse which is unavailable in Node 18.15.0, causing failures. Instead, use corepack only to download Berry to a temp COREPACK_HOME, then create a direct /tmp/yarn wrapper that invokes the Berry .cjs file via node directly -- no corepack shim involved, so node version switch does not matter.
…yout corepack >=0.24 (bundled with Node 20) stores Berry at v1/yarn/<version>/yarn.js, not under a bin/ subdirectory. The previous find pattern returned empty, producing a broken shim that caused Node to hang reading stdin when setup-node called yarn --version during environment setup.
… dead .yarnrc The root workspace uses a Yarn Classic lockfile; Yarn Classic does not recognise --immutable (a Berry-only flag) and silently skips lockfile enforcement. Use --frozen-lockfile, which is the Classic equivalent. Remove solidity/.yarnrc (ignore-engines true). After corepack activates Berry for all solidity/ installs, Yarn Classic never runs in that directory and Berry ignores .yarnrc entirely, making the file dead code.
… order and ESLint workaround Revised comments in the contracts workflow to emphasize the importance of the installation order for Yarn Classic and Berry. Clarified the rationale behind the ESLint workaround related to the configuration. Updated documentation in the BitcoinTx library to reflect changes in difficulty handling and added new test cases for asymmetric DIFF1 skipping scenarios in BitcoinTx tests. Enhanced comments in the ElectrumClient class to improve understanding of retry parameters.
…pdate Syncs line anchors and fromUrl parameter docs with client.ts for CI git diff check.
… retry defaults (threshold-network#964) Small follow-up on fix/testnet4-security-followup: improves on-chain documentation for asymmetric relay difficulties, adds regression tests for those cases, tightens workflow comments so Classic vs Berry install order is hard to break, and fixes misleading JSDoc on ElectrumClient.fromUrl retry defaults. Revised comments in the contracts workflow to emphasize the importance of the installation order for Yarn Classic and Berry. Clarified the rationale behind the ESLint workaround related to the configuration. Updated documentation in the BitcoinTx library to reflect changes in difficulty handling and added new test cases for asymmetric DIFF1 skipping scenarios in BitcoinTx tests. Enhanced comments in the ElectrumClient class to improve understanding of retry parameters. ## Changes ### `solidity/contracts/bridge/BitcoinTx.sol` - Expand `@notice` on `determineRequestedDifficulty` to spell out: - **DIFF1 stripping** only when **both** `currentEpochDifficulty` and `previousEpochDifficulty` are **above minimum**. - If **either** side is **1**, **leading DIFF1 headers are not skipped** and are matched like any other header (**asymmetric oracle** case). - **Mainnet-style** relays are **not expected** to report **epoch difficulty 1**. ### `solidity/test/bridge/BitcoinTx.test.ts` - Add `determineRequestedDifficulty` tests for **asymmetric** `(current, prev)`: - **High current** + **`prev == 1`**, chain **DIFF1 then normal** → first header binds to **previous (1)** (DIFF1 **not** skipped). - **`current == 1`** + **high previous**, single **DIFF1** header → binds to **current (1)**. ### `.github/workflows/contracts.yml` (`contracts-format` job) - Replace/extend the comment above **root** `yarn install --frozen-lockfile` with an **IMPORTANT** guard: - **Root Yarn Classic** install must **stay before** `corepack prepare yarn@4` / Berry for `solidity/`. - **Rationale:** wrong order breaks Classic lockfile/flags; Berry is for `solidity/` only. - **Keep** the **ESLint** / root **`.prettierrc`** dependency explanation. ### `typescript/src/lib/electrum/client.ts` - **`fromUrl` JSDoc:** document real defaults — `retryBackoffStep` **1000 ms** here vs **10000 ms** on the default constructor; clarify `connectionTimeout` in **milliseconds**. - Remove incorrect inline `// 10 seconds` on **`1000`** (**1000 ms ≠ 10 s**). ## Test plan - [x] `cd solidity && npx hardhat test test/bridge/BitcoinTx.test.ts` - [ ] `cd solidity && yarn test` (full Solidity suite) - [ ] `cd typescript && yarn tsc --noEmit` (TS verification aligned with CI)
…eshold-network#959) ## Summary Follow-up to threshold-network#949 addressing three validated security and compatibility findings from the multi-lens review. ### Security / correctness fixes - **[P0]** \`BitcoinTx.determineRequestedDifficulty\`: removed the \`return 1\` fallback that let an attacker mine 6 trivial DIFF1 headers (~microseconds per ASIC) to pass SPV proof verification on mainnet, bypassing the relay oracle entirely. Now reverts if all headers are minimum-difficulty with no relay-epoch match — operators must call \`SepoliaLightRelay.setDifficultyFromHeaders\` with actual headers before accepting all-DIFF1 proofs. - **[P1]** \`LightRelay.retarget\`: the base contract previously accepted \`MIN_DIFFICULTY_TARGET\` headers in the retarget proof window, weakening relay epoch integrity for mainnet. Extracted target checks into \`isValidPreRetargetTarget\` / \`isValidPostRetargetTarget\` virtual helpers (strict by default). \`SepoliaLightRelay\` now overrides both to permit DIFF1, which is the correct scope for the testnet4 BIP94 exception. - **[P2]** \`ElectrumClient\`: replaced \`import * as crypto from "crypto"\` (Node.js-only) with \`BitcoinHashUtils.computeHash256\` which uses \`ethers.utils.sha256\` and works in browser and Node environments. Also replaced the \`switch\` in \`fromDefaultConfig\` with a lookup map (removes static-analysis false-positive) and converted \`getTransactionHistory\` to \`Promise.allSettled\` (explicit rejection surfacing). ### CI fixes (Yarn Berry migration from threshold-network#949) threshold-network#949 introduced a Berry 4.x lockfile (\`__metadata: version: 8\`) in \`solidity/\` but left CI workflows using bare \`corepack enable\`, which cannot auto-detect the Berry version without a \`packageManager\` field. This PR completes the migration: - **\`contracts.yml\`** — add \`corepack prepare yarn@4.12.0 --activate\` to all 7 jobs so Berry is explicitly activated before \`yarn install\`. Move the root-workspace install (Classic lockfile) before Berry activation so each lockfile is handled by the correct Yarn version. Use \`--frozen-lockfile\` (Classic flag) instead of \`--immutable\` (Berry-only) for that step. - **\`contracts-docs.yml\`** — the reusable \`keep-network/ci\` workflow runs Yarn Classic internally and cannot be modified. Use \`preProcessingCommand\` to download Berry via corepack and install a thin shell shim at \`/tmp/yarn\` so subsequent steps see Berry. Fixed shim construction to use the corepack v1 storage path (\`v1/yarn/4.12.0/yarn.js\`) rather than a non-existent \`bin/\` subdirectory. - **\`solidity/package.json\`** — removed \`packageManager: yarn@4.12.0\`; the reusable docs workflow treats that field as a hard version pin and fails when it encounters Classic. - **\`@openzeppelin/upgrades-core\`** — pinned to 1.20.0 to avoid a transitive dep that requires Node >=18.17.0 while CI pins Node 18.15.0. - **\`solidity/.yarnrc\`** — removed; was added as a band-aid for Classic accidentally running in \`solidity/\`, but is unreachable now that Berry handles all \`solidity/\` installs (Berry ignores \`.yarnrc\`). ## Test plan - [x] \`cd solidity && yarn hardhat compile\` — compiles without errors - [x] \`cd typescript && yarn tsc --noEmit\` — no type errors in changed files - [ ] CI passes on this branch
…t' into feat/testnet4-deployment-support
- Regenerated yarn.lock to update dependencies. - Added missing newlines at the end of several JSON files in the Ethereum artifacts directory (Bridge.json, TBTC.json, TBTCVault.json, WalletRegistry.json) to ensure proper formatting.
- Changed the Node.js version from 18.15.0 to 20.19.0 in multiple jobs of the contracts.yml workflow to ensure compatibility with updated dependencies.
- Updated the Node.js setup action from v3 to v4 and changed the node version from 18 to 20.19.0 across multiple jobs in the cross-chain-arbitrum.yml workflow for improved compatibility and performance.
…d Yarn Berry - Upgraded actions in the deployment-artifacts.yml workflow to use Node.js setup v4 and Yarn version 4.12.0. - Changed the Node.js version to 20.19.0 for improved compatibility. - Updated the yarn install command to use the --immutable flag for Yarn Berry. - Added corepack prepare command to ensure the correct Yarn version is activated before installation.
- Updated the deployment function name from a generic `async function` to `async function runDeployment` in multiple deployment scripts for improved clarity and consistency. - Added missing newline at the end of the `.gitignore` file to ensure proper formatting.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR delivers the full
feat/testnet4-deployment-supportdelta, including protocol/security fixes, deployment and artifact updates, TypeScript SDK/runtime improvements, and CI/workflow hardening needed to keep the branch mergeable.1) Bridge/Relay security and correctness (Testnet4 handling)
2) Electrum + TypeScript SDK robustness
BitcoinClientWithNetworkOverrideand updated SDK-facing docs/API references accordingly.3) Deployment pipeline and on-chain artifacts
4) Solidity deploy script lint/format compliance
func-names) by naming async deploy functions in affected scripts..gitignore) to satisfycontracts-format.5) CI/workflow hardening (multi-workflow)
20.19.0andactions/setup-node@v4where dependency engines required newer runtimes.--immutablevs Classic flags) to align with lockfile/tooling expectations per workflow.contracts.ymlcross-chain-arbitrum.ymldeployment-artifacts.ymlWhy
The branch had multiple independent breakpoints:
This PR brings those streams together so the feature branch is functionally correct, security-reviewed, and CI-stable.
Test plan
Notable areas touched