diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol index a7c2e2b1a457..c4654834ba8c 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol @@ -64,6 +64,12 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount { Lib_OVMCodec.EIP155Transaction memory decodedTx = Lib_OVMCodec.decodeEIP155Transaction(_transaction, isEthSign); + // Need to make sure that the transaction chainId is correct. + Lib_SafeExecutionManagerWrapper.safeREQUIRE( + decodedTx.chainId == Lib_SafeExecutionManagerWrapper.safeCHAINID(), + "Transaction chainId does not match expected OVM chainId." + ); + // Need to make sure that the transaction nonce is right. Lib_SafeExecutionManagerWrapper.safeREQUIRE( decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(), diff --git a/packages/contracts/contracts/optimistic-ethereum/mockOVM/accounts/mockOVM_ECDSAContractAccount.sol b/packages/contracts/contracts/optimistic-ethereum/mockOVM/accounts/mockOVM_ECDSAContractAccount.sol index d3a152da90ab..2ece58f9ea65 100644 --- a/packages/contracts/contracts/optimistic-ethereum/mockOVM/accounts/mockOVM_ECDSAContractAccount.sol +++ b/packages/contracts/contracts/optimistic-ethereum/mockOVM/accounts/mockOVM_ECDSAContractAccount.sol @@ -46,6 +46,12 @@ contract mockOVM_ECDSAContractAccount is iOVM_ECDSAContractAccount { bool isEthSign = _signatureType == Lib_OVMCodec.EOASignatureType.ETH_SIGNED_MESSAGE; Lib_OVMCodec.EIP155Transaction memory decodedTx = Lib_OVMCodec.decodeEIP155Transaction(_transaction, isEthSign); + // Need to make sure that the transaction chainId is correct. + Lib_SafeExecutionManagerWrapper.safeREQUIRE( + decodedTx.chainId == Lib_SafeExecutionManagerWrapper.safeCHAINID(), + "Transaction chainId does not match expected OVM chainId." + ); + // Need to make sure that the transaction nonce is right. Lib_SafeExecutionManagerWrapper.safeREQUIRE( decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(), diff --git a/packages/contracts/test/contracts/OVM/accounts/OVM_ECDSAContractAccount.spec.ts b/packages/contracts/test/contracts/OVM/accounts/OVM_ECDSAContractAccount.spec.ts index d3d89df84c1b..8a5cb60c4bd2 100644 --- a/packages/contracts/test/contracts/OVM/accounts/OVM_ECDSAContractAccount.spec.ts +++ b/packages/contracts/test/contracts/OVM/accounts/OVM_ECDSAContractAccount.spec.ts @@ -200,5 +200,32 @@ describe('OVM_ECDSAContractAccount', () => { 'Transaction nonce does not match the expected nonce.' ) }) + + it(`should revert on incorrect chainId`, async () => { + const alteredChainIdTx = { + ...DEFAULT_EIP155_TX, + chainId : 421 + } + const message = serializeNativeTransaction(alteredChainIdTx) + const sig = await signNativeTransaction(wallet, alteredChainIdTx) + + await callPrecompile( + Helper_PrecompileCaller, + OVM_ECDSAContractAccount, + 'execute', + [ + message, + 0, //isEthSignedMessage + `0x${sig.v}`, //v + `0x${sig.r}`, //r + `0x${sig.s}`, //s + ] + ) + const ovmREVERT: any = + Mock__OVM_ExecutionManager.smocked.ovmREVERT.calls[0] + expect(ethers.utils.toUtf8String(ovmREVERT._data)).to.equal( + 'Transaction chainId does not match expected OVM chainId.' + ) + }) }) }) diff --git a/packages/contracts/test/helpers/codec/encoding.ts b/packages/contracts/test/helpers/codec/encoding.ts index 4d3fe92f0df3..f2a10f1a6074 100644 --- a/packages/contracts/test/helpers/codec/encoding.ts +++ b/packages/contracts/test/helpers/codec/encoding.ts @@ -121,7 +121,7 @@ export const signNativeTransaction = async ( let [v, r, s] = getSignedComponents(transactionSignature).map((component) => { return remove0x(component) }) - v = '0' + (parseInt(v, 16) - 420 * 2 - 8 - 27) + v = '0' + (parseInt(v, 16) - transaction.chainId * 2 - 8 - 27) return { messageHash, v,