@@ -22,6 +22,7 @@ import { createExtendedL1Client } from './client.js';
2222import { type L1ContractsConfig , assertValidSlotDurations } from './config.js' ;
2323import { deployMulticall3 } from './contracts/multicall.js' ;
2424import { RollupContract } from './contracts/rollup.js' ;
25+ import { resolveFoundryBinary } from './foundry_binary.js' ;
2526import type { L1ContractAddresses } from './l1_contract_addresses.js' ;
2627import type { ExtendedViemWalletClient } from './types.js' ;
2728
@@ -93,11 +94,16 @@ function runProcess<T>(
9394
9495// Covers an edge where where we may have a cached BlobLib that is not meant for production.
9596// Despite the profile apparently sometimes cached code remains (so says Lasse after his ignition-monorepo arc).
96- async function maybeForgeForceProductionBuild ( l1ContractsPath : string , script : string , chainId : number ) {
97+ async function maybeForgeForceProductionBuild (
98+ forgeBin : string ,
99+ l1ContractsPath : string ,
100+ script : string ,
101+ chainId : number ,
102+ ) {
97103 if ( chainId === mainnet . id ) {
98104 logger . info ( `Recompiling ${ script } with production profile for mainnet deployment` ) ;
99105 logger . info ( 'This may take a minute but ensures production BlobLib is used.' ) ;
100- await runProcess ( 'forge' , [ 'build' , script , '--force' ] , { FOUNDRY_PROFILE : 'production' } , l1ContractsPath ) ;
106+ await runProcess ( forgeBin , [ 'build' , script , '--force' ] , { FOUNDRY_PROFILE : 'production' } , l1ContractsPath ) ;
101107 }
102108}
103109
@@ -320,8 +326,9 @@ export async function deployAztecL1Contracts(
320326 // Use foundry-artifacts from l1-artifacts package
321327 const l1ContractsPath = prepareL1ContractsForDeployment ( ) ;
322328
329+ const forgeBin = resolveFoundryBinary ( 'forge' ) ;
323330 const FORGE_SCRIPT = 'script/deploy/DeployAztecL1Contracts.s.sol' ;
324- await maybeForgeForceProductionBuild ( l1ContractsPath , FORGE_SCRIPT , chainId ) ;
331+ await maybeForgeForceProductionBuild ( forgeBin , l1ContractsPath , FORGE_SCRIPT , chainId ) ;
325332
326333 // Verify contracts on Etherscan when on mainnet/sepolia and ETHERSCAN_API_KEY is available.
327334 const isVerifiableChain = chainId === mainnet . id || chainId === sepolia . id ;
@@ -346,6 +353,8 @@ export async function deployAztecL1Contracts(
346353 ...( shouldVerify ? [ '--verify' ] : [ ] ) ,
347354 ] ;
348355 const forgeEnv = {
356+ // Resolved forge binary picked up by forge_broadcast.js, so it works without forge on PATH.
357+ FORGE_BIN : forgeBin ,
349358 // Env vars required by l1-contracts/script/deploy/DeploymentConfiguration.sol.
350359 NETWORK : getActiveNetworkName ( ) ,
351360 FOUNDRY_PROFILE : chainId === mainnet . id ? 'production' : undefined ,
@@ -613,12 +622,15 @@ export const deployRollupForUpgrade = async (
613622 // Use foundry-artifacts from l1-artifacts package
614623 const l1ContractsPath = prepareL1ContractsForDeployment ( ) ;
615624
625+ const forgeBin = resolveFoundryBinary ( 'forge' ) ;
616626 const FORGE_SCRIPT = 'script/deploy/DeployRollupForUpgrade.s.sol' ;
617- await maybeForgeForceProductionBuild ( l1ContractsPath , FORGE_SCRIPT , chainId ) ;
627+ await maybeForgeForceProductionBuild ( forgeBin , l1ContractsPath , FORGE_SCRIPT , chainId ) ;
618628
619629 const scriptPath = join ( getL1ContractsPath ( ) , 'scripts' , 'forge_broadcast.js' ) ;
620630 const forgeArgs = [ FORGE_SCRIPT , '--sig' , 'run()' , '--private-key' , privateKey , '--rpc-url' , rpcUrl ] ;
621631 const forgeEnv = {
632+ // Resolved forge binary picked up by forge_broadcast.js, so it works without forge on PATH.
633+ FORGE_BIN : forgeBin ,
622634 FOUNDRY_PROFILE : chainId === mainnet . id ? 'production' : undefined ,
623635 // Env vars required by l1-contracts/script/deploy/RollupConfiguration.sol.
624636 REGISTRY_ADDRESS : registryAddress . toString ( ) ,
0 commit comments