@@ -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
@@ -95,11 +96,16 @@ function runProcess<T>(
9596
9697// Covers an edge where where we may have a cached BlobLib that is not meant for production.
9798// Despite the profile apparently sometimes cached code remains (so says Lasse after his ignition-monorepo arc).
98- async function maybeForgeForceProductionBuild ( l1ContractsPath : string , script : string , chainId : number ) {
99+ async function maybeForgeForceProductionBuild (
100+ forgeBin : string ,
101+ l1ContractsPath : string ,
102+ script : string ,
103+ chainId : number ,
104+ ) {
99105 if ( chainId === mainnet . id ) {
100106 logger . info ( `Recompiling ${ script } with production profile for mainnet deployment` ) ;
101107 logger . info ( 'This may take a minute but ensures production BlobLib is used.' ) ;
102- await runProcess ( 'forge' , [ 'build' , script , '--force' ] , { FOUNDRY_PROFILE : 'production' } , l1ContractsPath ) ;
108+ await runProcess ( forgeBin , [ 'build' , script , '--force' ] , { FOUNDRY_PROFILE : 'production' } , l1ContractsPath ) ;
103109 }
104110}
105111
@@ -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 ,
@@ -618,12 +627,15 @@ export const deployRollupForUpgrade = async (
618627 // Use foundry-artifacts from l1-artifacts package
619628 const l1ContractsPath = prepareL1ContractsForDeployment ( ) ;
620629
630+ const forgeBin = resolveFoundryBinary ( 'forge' ) ;
621631 const FORGE_SCRIPT = 'script/deploy/DeployRollupForUpgrade.s.sol' ;
622- await maybeForgeForceProductionBuild ( l1ContractsPath , FORGE_SCRIPT , chainId ) ;
632+ await maybeForgeForceProductionBuild ( forgeBin , l1ContractsPath , FORGE_SCRIPT , chainId ) ;
623633
624634 const scriptPath = join ( getL1ContractsPath ( ) , 'scripts' , 'forge_broadcast.js' ) ;
625635 const forgeArgs = [ FORGE_SCRIPT , '--sig' , 'run()' , '--private-key' , privateKey , '--rpc-url' , rpcUrl ] ;
626636 const forgeEnv = {
637+ // Resolved forge binary picked up by forge_broadcast.js, so it works without forge on PATH.
638+ FORGE_BIN : forgeBin ,
627639 FOUNDRY_PROFILE : chainId === mainnet . id ? 'production' : undefined ,
628640 // Env vars required by l1-contracts/script/deploy/RollupConfiguration.sol.
629641 REGISTRY_ADDRESS : registryAddress . toString ( ) ,
0 commit comments