@@ -9,7 +9,7 @@ import { pickStrategy, rpcUrl } from "../../prompts";
9
9
import { getActiveDeploy } from "./utils" ;
10
10
import * as AllChains from "viem/chains" ;
11
11
import { canonicalPaths } from "../../../metadata/paths" ;
12
- import { TForgeRequest } from "../../../signing/strategy" ;
12
+ import { TForgeRequest , TGnosisRequest } from "../../../signing/strategy" ;
13
13
import { ForgeSolidityMetadata , TDeployedContractsManifest } from "../../../metadata/schema" ;
14
14
import { createPublicClient , hexToBytes , http , toHex } from "viem" ;
15
15
import { join } from "path" ;
@@ -254,6 +254,7 @@ async function handler(_user: TState, args: {env: string}) {
254
254
console . log ( chalk . green ( 'OK' ) ) ;
255
255
} else {
256
256
console . log ( chalk . red ( `FAILURE` ) ) ;
257
+ throw new Error ( `Deployed contracts did not match local copy.` )
257
258
}
258
259
259
260
try {
@@ -271,6 +272,44 @@ async function handler(_user: TState, args: {env: string}) {
271
272
console . error ( e )
272
273
}
273
274
}
275
+
276
+ if ( deploy . _ . segments [ deploy . _ . segmentId ] . type === 'multisig' ) {
277
+ // allow verifying the multisig txn hash.
278
+ console . log ( chalk . bold ( `This deploy has a multisig step ongoing. You can check that the provided gnosisTransactionHash matches what was submitted` ) )
279
+
280
+ const strategyId = await pickStrategy ( [
281
+ { id : 'gnosis.api.eoa' , description : 'Gnosis / Private Key' } ,
282
+ { id : 'gnosis.api.ledger' , description : 'Gnosis / Ledger' } ,
283
+ { id : 'cancel' , description : 'Cancel' }
284
+ ] , "How would you like to supply the signer used for simulation?" ) ;
285
+
286
+ if ( strategyId !== 'cancel' ) {
287
+ const strategy = await ( async ( ) => {
288
+ const all = await import ( '../../../signing/strategies/strategies' ) ;
289
+ const strategy = all . all . find ( s => new s ( deploy , metatxn , { nonInteractive : false , defaultArgs : { } } ) . id === strategyId ) ;
290
+ if ( ! strategy ) {
291
+ throw new Error ( `Unknown strategy` ) ;
292
+ }
293
+ return new strategy ( deploy , metatxn , { nonInteractive : false , defaultArgs : { rpcUrl : customRpcUrl , etherscanApiKey : false } } ) ;
294
+ } ) ( ) ;
295
+ const script = join ( deploy . _ . upgradePath , deploy . _ . segments [ deploy . _ . segmentId ] . filename ) ;
296
+ const request = await strategy . prepare ( script , deploy . _ ) ;
297
+ const gnosisTxnHash = ( request as TGnosisRequest ) . safeTxHash ;
298
+
299
+ const multisigRun = await metatxn . getJSONFile < TGnosisRequest > ( canonicalPaths . multisigRun ( { deployEnv : deploy . _ . env , deployName : deploy . _ . name , segmentId : deploy . _ . segmentId } ) )
300
+ const proposedTxHash = multisigRun . _ . safeTxHash ;
301
+
302
+ if ( proposedTxHash === gnosisTxnHash ) {
303
+ console . log ( `${ chalk . green ( '✔' ) } ${ script } (${ gnosisTxnHash } )` ) ;
304
+ } else {
305
+ console . error ( `${ chalk . red ( 'x' ) } ${ script } (local=${ gnosisTxnHash } ,reported=${ proposedTxHash } )` ) ;
306
+ throw new Error ( `Multisig transaction did not match (local=${ gnosisTxnHash } ,reported=${ proposedTxHash } )` ) ;
307
+ }
308
+ } else {
309
+ console . log ( chalk . italic ( `skipping gnosis verification` ) )
310
+ }
311
+ }
312
+
274
313
} catch ( e ) {
275
314
console . error ( `Failed to verify contracts.` ) ;
276
315
console . error ( e ) ;
0 commit comments