Commit 21e47e1f authored by ben's avatar ben Committed by Mark Tyneway

fix(contracts): prevent L2->L1 calls to system contracts

parent 26b39199
---
'@eth-optimism/contracts': patch
---
A small change to the L1 Messenger, which prevents an L2 to L1 call from send calling the CTC.
......@@ -252,6 +252,11 @@ contract OVM_L1CrossDomainMessenger is
"Provided message has been blocked."
);
require(
_target != resolve("OVM_CanonicalTransactionChain"),
"Cannot send L2->L1 messages to L1 system contracts."
);
xDomainMsgSender = _sender;
(bool success, ) = _target.call(_message);
xDomainMsgSender = DEFAULT_XDOMAIN_SENDER;
......
......@@ -66,8 +66,8 @@ Implementation addresses. DO NOT use these addresses directly.
Use their proxied counterparts seen above.
OVM_L1CrossDomainMessenger:
- 0x16393737D09d2722AD13DcA3cA8C3DB957699F1D
- https://etherscan.io/address/0x16393737D09d2722AD13DcA3cA8C3DB957699F1D
- 0xbfba066b5cA610Fe70AdCE45FcB622F945891bb0
- https://etherscan.io/address/0xbfba066b5cA610Fe70AdCE45FcB622F945891bb0)
OVM_L1ETHGateway:
- 0x40c9067ec8087EcF101FC10d2673636955b81A32
......@@ -100,8 +100,8 @@ Implementation addresses. DO NOT use these addresses directly.
Use their proxied counterparts seen above.
OVM_L1CrossDomainMessenger:
- 0xa172330C2E6Ec2bF04662Bb9b67ae857910b7f7f
- https://kovan.etherscan.io/address/0xa172330C2E6Ec2bF04662Bb9b67ae857910b7f7f)
- 0x333d2674E2D7e1e7327dc076030ce9615183709C
- https://kovan.etherscan.io/address/0x333d2674E2D7e1e7327dc076030ce9615183709C)
OVM_L1StandardBridge:
- 0x8293ab0dc701a1387031a13786276f1baa3fcd4e
- https://kovan.etherscan.io/address/0x8293ab0dc701a1387031a13786276f1baa3fcd4e)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -257,25 +257,25 @@ describe('OVM_L1CrossDomainMessenger', () => {
})
})
describe('relayMessage', () => {
let target: string
let message: string
let sender: string
let proof: any
let calldata: string
before(async () => {
target = Mock__TargetContract.address
message = Mock__TargetContract.interface.encodeFunctionData('setTarget', [
NON_ZERO_ADDRESS,
])
sender = await signer.getAddress()
calldata = encodeXDomainCalldata(target, sender, message, 0)
const generateMockRelayMessageProof = async (
target: string,
sender: string,
message: string,
messageNonce: number = 0
): Promise<{
calldata: string
proof: any
}> => {
const calldata = encodeXDomainCalldata(
target,
sender,
message,
messageNonce
)
const storageKey = keccak256(
keccak256(
calldata + remove0x(Mock__OVM_L2CrossDomainMessenger.address)
) + '00'.repeat(32)
keccak256(calldata + remove0x(Mock__OVM_L2CrossDomainMessenger.address)) +
'00'.repeat(32)
)
const storageGenerator = await TrieTestGenerator.fromNodes({
nodes: [
......@@ -300,19 +300,44 @@ describe('OVM_L1CrossDomainMessenger', () => {
secure: true,
})
proof = {
const proof = {
stateRoot: toHexString(generator._trie.root),
stateRootBatchHeader: DUMMY_BATCH_HEADERS[0],
stateRootProof: DUMMY_BATCH_PROOFS[0],
stateTrieWitness: (
await generator.makeAccountProofTest(
predeploys.OVM_L2ToL1MessagePasser
)
await generator.makeAccountProofTest(predeploys.OVM_L2ToL1MessagePasser)
).accountTrieWitness,
storageTrieWitness: (
await storageGenerator.makeInclusionProofTest(storageKey)
).proof,
}
return {
calldata,
proof,
}
}
describe('relayMessage', () => {
let target: string
let sender: string
let message: string
let proof: any
let calldata: string
before(async () => {
target = Mock__TargetContract.address
message = Mock__TargetContract.interface.encodeFunctionData('setTarget', [
NON_ZERO_ADDRESS,
])
sender = await signer.getAddress()
const mockProof = await generateMockRelayMessageProof(
target,
sender,
message
)
proof = mockProof.proof
calldata = mockProof.calldata
})
beforeEach(async () => {
......@@ -348,6 +373,26 @@ describe('OVM_L1CrossDomainMessenger', () => {
).to.be.revertedWith('Provided message could not be verified.')
})
it('should revert if attempting to relay a message sent to an L1 system contract', async () => {
const maliciousProof = await generateMockRelayMessageProof(
OVM_CanonicalTransactionChain.address,
sender,
message
)
await expect(
OVM_L1CrossDomainMessenger.relayMessage(
OVM_CanonicalTransactionChain.address,
sender,
message,
0,
maliciousProof.proof
)
).to.be.revertedWith(
'Cannot send L2->L1 messages to L1 system contracts.'
)
})
it('should revert if provided an invalid state root proof', async () => {
Mock__OVM_StateCommitmentChain.smocked.verifyStateCommitment.will.return.with(
false
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment