From 6333d9716622937278462533fa24a63bc2993624 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Fri, 15 Apr 2022 16:27:29 -0400 Subject: [PATCH] maint(ct): clean up L2xDM tests Cleans up the L2CrossDomainMessenger tests in the same manner as previous cleanup PRs. --- .../messaging/L2CrossDomainMessenger.spec.ts | 193 ++++++++++-------- .../test/helpers/utils/impersonation.ts | 23 +++ .../contracts/test/helpers/utils/index.ts | 1 + 3 files changed, 131 insertions(+), 86 deletions(-) create mode 100644 packages/contracts/test/helpers/utils/impersonation.ts diff --git a/packages/contracts/test/contracts/L2/messaging/L2CrossDomainMessenger.spec.ts b/packages/contracts/test/contracts/L2/messaging/L2CrossDomainMessenger.spec.ts index f7cc20878b820..6a3c0206aa1d5 100644 --- a/packages/contracts/test/contracts/L2/messaging/L2CrossDomainMessenger.spec.ts +++ b/packages/contracts/test/contracts/L2/messaging/L2CrossDomainMessenger.spec.ts @@ -1,24 +1,21 @@ -/* External Imports */ -import hre, { ethers } from 'hardhat' -import { Signer, ContractFactory, Contract } from 'ethers' +import { ethers } from 'hardhat' +import { Contract } from 'ethers' import { applyL1ToL2Alias } from '@eth-optimism/core-utils' -import { - smock, - MockContractFactory, - FakeContract, -} from '@defi-wonderland/smock' +import { smock, FakeContract, MockContract } from '@defi-wonderland/smock' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' -/* Internal Imports */ import { expect } from '../../../setup' +import { predeploys } from '../../../../src' import { + impersonate, + deploy, NON_NULL_BYTES32, NON_ZERO_ADDRESS, encodeXDomainCalldata, } from '../../../helpers' -import { predeploys } from '../../../../src' describe('L2CrossDomainMessenger', () => { - let signer: Signer + let signer: SignerWithAddress before(async () => { ;[signer] = await ethers.getSigners() }) @@ -37,49 +34,27 @@ describe('L2CrossDomainMessenger', () => { ) }) - let impersonatedL1CrossDomainMessengerSender: Signer - before(async () => { - const impersonatedAddress = applyL1ToL2Alias( - Fake__L1CrossDomainMessenger.address - ) - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [impersonatedAddress], - }) - await hre.network.provider.request({ - method: 'hardhat_setBalance', - params: [impersonatedAddress, '0xFFFFFFFFFFFFFFFFF'], - }) - impersonatedL1CrossDomainMessengerSender = await ethers.getSigner( - impersonatedAddress - ) - }) - - let Factory__L2CrossDomainMessenger: ContractFactory + let impersonatedL1CrossDomainMessengerSender: SignerWithAddress before(async () => { - Factory__L2CrossDomainMessenger = await ethers.getContractFactory( - 'L2CrossDomainMessenger' + impersonatedL1CrossDomainMessengerSender = await impersonate( + applyL1ToL2Alias(Fake__L1CrossDomainMessenger.address), + '0xFFFFFFFFFFFFFFFFF' ) }) let L2CrossDomainMessenger: Contract beforeEach(async () => { - L2CrossDomainMessenger = await Factory__L2CrossDomainMessenger.deploy( - Fake__L1CrossDomainMessenger.address - ) + L2CrossDomainMessenger = await deploy('L2CrossDomainMessenger', { + args: [Fake__L1CrossDomainMessenger.address], + }) }) describe('xDomainMessageSender', () => { - let Mock__Factory__L2CrossDomainMessenger: MockContractFactory - let Mock__L2CrossDomainMessenger + let Mock__L2CrossDomainMessenger: MockContract before(async () => { - Mock__Factory__L2CrossDomainMessenger = await smock.mock( - 'L2CrossDomainMessenger' - ) - Mock__L2CrossDomainMessenger = - await Mock__Factory__L2CrossDomainMessenger.deploy( - Fake__L1CrossDomainMessenger.address - ) + Mock__L2CrossDomainMessenger = await ( + await smock.mock('L2CrossDomainMessenger') + ).deploy(Fake__L1CrossDomainMessenger.address) }) it('should return the xDomainMsgSender address', async () => { @@ -87,6 +62,7 @@ describe('L2CrossDomainMessenger', () => { 'xDomainMsgSender', '0x0000000000000000000000000000000000000000' ) + expect( await Mock__L2CrossDomainMessenger.xDomainMessageSender() ).to.equal('0x0000000000000000000000000000000000000000') @@ -94,49 +70,53 @@ describe('L2CrossDomainMessenger', () => { }) describe('sendMessage', () => { - const target = NON_ZERO_ADDRESS - const message = NON_NULL_BYTES32 - const gasLimit = 100_000 - it('should be able to send a single message', async () => { await expect( - L2CrossDomainMessenger.sendMessage(target, message, gasLimit) + L2CrossDomainMessenger.sendMessage( + NON_ZERO_ADDRESS, + NON_NULL_BYTES32, + 100_000 + ) ).to.not.be.reverted expect( Fake__OVM_L2ToL1MessagePasser.passMessageToL1.getCall(0).args[0] ).to.deep.equal( - encodeXDomainCalldata(target, await signer.getAddress(), message, 0) + encodeXDomainCalldata( + NON_ZERO_ADDRESS, + await signer.getAddress(), + NON_NULL_BYTES32, + 0 + ) ) }) it('should be able to send the same message twice', async () => { - await L2CrossDomainMessenger.sendMessage(target, message, gasLimit) + await L2CrossDomainMessenger.sendMessage( + NON_ZERO_ADDRESS, + NON_NULL_BYTES32, + 100_000 + ) await expect( - L2CrossDomainMessenger.sendMessage(target, message, gasLimit) + L2CrossDomainMessenger.sendMessage( + NON_ZERO_ADDRESS, + NON_NULL_BYTES32, + 100_000 + ) ).to.not.be.reverted }) }) describe('relayMessage', () => { - let target: string - let message: string - let sender: string - before(async () => { - target = Fake__TargetContract.address - message = Fake__TargetContract.interface.encodeFunctionData('setTarget', [ - NON_ZERO_ADDRESS, - ]) - sender = await signer.getAddress() - }) - it('should revert if the L1 message sender is not the L1CrossDomainMessenger', async () => { await expect( L2CrossDomainMessenger.connect(signer).relayMessage( - target, - sender, - message, + Fake__TargetContract.address, + signer.address, + Fake__TargetContract.interface.encodeFunctionData('setTarget', [ + NON_ZERO_ADDRESS, + ]), 0 ) ).to.be.revertedWith('Provided message could not be verified.') @@ -145,7 +125,14 @@ describe('L2CrossDomainMessenger', () => { it('should send a call to the target contract', async () => { await L2CrossDomainMessenger.connect( impersonatedL1CrossDomainMessengerSender - ).relayMessage(target, sender, message, 0) + ).relayMessage( + Fake__TargetContract.address, + signer.address, + Fake__TargetContract.interface.encodeFunctionData('setTarget', [ + NON_ZERO_ADDRESS, + ]), + 0 + ) expect(Fake__TargetContract.setTarget.getCall(0).args[0]).to.deep.equal( NON_ZERO_ADDRESS @@ -159,7 +146,14 @@ describe('L2CrossDomainMessenger', () => { await L2CrossDomainMessenger.connect( impersonatedL1CrossDomainMessengerSender - ).relayMessage(target, sender, message, 0) + ).relayMessage( + Fake__TargetContract.address, + signer.address, + Fake__TargetContract.interface.encodeFunctionData('setTarget', [ + NON_ZERO_ADDRESS, + ]), + 0 + ) await expect( L2CrossDomainMessenger.xDomainMessageSender() @@ -169,45 +163,72 @@ describe('L2CrossDomainMessenger', () => { it('should revert if trying to send the same message twice', async () => { await L2CrossDomainMessenger.connect( impersonatedL1CrossDomainMessengerSender - ).relayMessage(target, sender, message, 0) + ).relayMessage( + Fake__TargetContract.address, + signer.address, + Fake__TargetContract.interface.encodeFunctionData('setTarget', [ + NON_ZERO_ADDRESS, + ]), + 0 + ) await expect( L2CrossDomainMessenger.connect( impersonatedL1CrossDomainMessengerSender - ).relayMessage(target, sender, message, 0) + ).relayMessage( + Fake__TargetContract.address, + signer.address, + Fake__TargetContract.interface.encodeFunctionData('setTarget', [ + NON_ZERO_ADDRESS, + ]), + 0 + ) ).to.be.revertedWith('Provided message has already been received.') }) it('should not make a call if the target is the L2 MessagePasser', async () => { - target = predeploys.OVM_L2ToL1MessagePasser - message = Fake__OVM_L2ToL1MessagePasser.interface.encodeFunctionData( - 'passMessageToL1(bytes)', - [NON_NULL_BYTES32] - ) - const resProm = L2CrossDomainMessenger.connect( impersonatedL1CrossDomainMessengerSender - ).relayMessage(target, sender, message, 0) + ).relayMessage( + predeploys.OVM_L2ToL1MessagePasser, + signer.address, + Fake__OVM_L2ToL1MessagePasser.interface.encodeFunctionData( + 'passMessageToL1(bytes)', + [NON_NULL_BYTES32] + ), + 0 + ) // The call to relayMessage() should succeed. await expect(resProm).to.not.be.reverted // There should be no 'relayedMessage' event logged in the receipt. - const logs = ( - await Fake__OVM_L2ToL1MessagePasser.provider.getTransactionReceipt( - ( - await resProm - ).hash - ) - ).logs - expect(logs).to.deep.equal([]) + expect( + ( + await Fake__OVM_L2ToL1MessagePasser.provider.getTransactionReceipt( + ( + await resProm + ).hash + ) + ).logs + ).to.deep.equal([]) // The message should be registered as successful. expect( await L2CrossDomainMessenger.successfulMessages( ethers.utils.solidityKeccak256( ['bytes'], - [encodeXDomainCalldata(target, sender, message, 0)] + [ + encodeXDomainCalldata( + predeploys.OVM_L2ToL1MessagePasser, + signer.address, + Fake__OVM_L2ToL1MessagePasser.interface.encodeFunctionData( + 'passMessageToL1(bytes)', + [NON_NULL_BYTES32] + ), + 0 + ), + ] ) ) ).to.be.true diff --git a/packages/contracts/test/helpers/utils/impersonation.ts b/packages/contracts/test/helpers/utils/impersonation.ts new file mode 100644 index 0000000000000..4cb55ebd9e6ac --- /dev/null +++ b/packages/contracts/test/helpers/utils/impersonation.ts @@ -0,0 +1,23 @@ +import { toRpcHexString } from '@eth-optimism/core-utils' +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers' +import { BigNumber } from 'ethers' +import hre from 'hardhat' + +export const impersonate = async ( + address: string, + balance?: string | number | BigNumber +): Promise => { + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [address], + }) + + if (balance !== undefined) { + await hre.network.provider.request({ + method: 'hardhat_setBalance', + params: [address, toRpcHexString(BigNumber.from(balance))], + }) + } + + return hre.ethers.getSigner(address) +} diff --git a/packages/contracts/test/helpers/utils/index.ts b/packages/contracts/test/helpers/utils/index.ts index c7d4b27add422..2c1c4fd59b45d 100644 --- a/packages/contracts/test/helpers/utils/index.ts +++ b/packages/contracts/test/helpers/utils/index.ts @@ -1,2 +1,3 @@ export * from './eth-time' export * from './deploy' +export * from './impersonation'