Commit 6e8fe1b9 authored by smartcontracts's avatar smartcontracts Committed by GitHub

refactor[contracts]: Remove two unused contracts (#549)

* refactor[contracts]: Remove two unused contracts

* chore[contracts]: Add changeset

* docs[contracts]: Added a comment to explain removal of 0x42..05
parent d4ee2d7d
---
"@eth-optimism/l2geth": patch
"@eth-optimism/contracts": patch
---
Removes mockOVM_ECDSAContractAccount and OVM_ProxySequencerEntrypoint, two unused contracts.
......@@ -139,7 +139,6 @@ type Context struct {
OriginalTargetReached bool
OvmExecutionManager dump.OvmDumpAccount
OvmStateManager dump.OvmDumpAccount
OvmMockAccount dump.OvmDumpAccount
OvmSafetyChecker dump.OvmDumpAccount
}
......@@ -190,7 +189,6 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
if chainConfig != nil && chainConfig.StateDump != nil {
ctx.OvmExecutionManager = chainConfig.StateDump.Accounts["OVM_ExecutionManager"]
ctx.OvmStateManager = chainConfig.StateDump.Accounts["OVM_StateManager"]
ctx.OvmMockAccount = chainConfig.StateDump.Accounts["mockOVM_ECDSAContractAccount"]
ctx.OvmSafetyChecker = chainConfig.StateDump.Accounts["OVM_SafetyChecker"]
}
......
// SPDX-License-Identifier: MIT
pragma solidity >0.5.0 <0.8.0;
/* Library Imports */
import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";
/**
* @title OVM_ProxySequencerEntrypoint
* @dev The Proxy Sequencer Entrypoint is a predeployed proxy to the implementation of the
* Sequencer Entrypoint. This will enable the Optimism team to upgrade the Sequencer Entrypoint
* contract.
*
* Compiler used: solc
* Runtime target: OVM
*/
contract OVM_ProxySequencerEntrypoint {
/*********************
* Fallback Function *
*********************/
fallback()
external
{
Lib_SafeExecutionManagerWrapper.safeDELEGATECALL(
gasleft(),
_getImplementation(),
msg.data
);
}
/********************
* Public Functions *
********************/
function init(
address _implementation,
address _owner
)
external
{
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
_getOwner() == address(0),
"ProxySequencerEntrypoint has already been inited"
);
_setOwner(_owner);
_setImplementation(_implementation);
}
function upgrade(
address _implementation
)
external
{
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
_getOwner() == Lib_SafeExecutionManagerWrapper.safeCALLER(),
"Only owner can upgrade the Entrypoint"
);
_setImplementation(_implementation);
}
/**********************
* Internal Functions *
**********************/
function _setImplementation(
address _implementation
)
internal
{
Lib_SafeExecutionManagerWrapper.safeSSTORE(
bytes32(uint256(0)),
bytes32(uint256(uint160(_implementation)))
);
}
function _getImplementation()
internal
returns (
address _implementation
)
{
return address(uint160(uint256(
Lib_SafeExecutionManagerWrapper.safeSLOAD(
bytes32(uint256(0))
)
)));
}
function _setOwner(
address _owner
)
internal
{
Lib_SafeExecutionManagerWrapper.safeSSTORE(
bytes32(uint256(1)),
bytes32(uint256(uint160(_owner)))
);
}
function _getOwner()
internal
returns (
address _owner
)
{
return address(uint160(uint256(
Lib_SafeExecutionManagerWrapper.safeSLOAD(
bytes32(uint256(1))
)
)));
}
}
// SPDX-License-Identifier: MIT
pragma solidity >0.5.0 <0.8.0;
pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_ECDSAContractAccount } from "../../iOVM/accounts/iOVM_ECDSAContractAccount.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol";
import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";
/**
* @title mockOVM_ECDSAContractAccount
*/
contract mockOVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
/********************
* Public Functions *
********************/
/**
* Executes a signed transaction.
* @param _transaction Signed EOA transaction.
* @param _signatureType Hashing scheme used for the transaction (e.g., ETH signed message).
* param _v Signature `v` parameter.
* param _r Signature `r` parameter.
* param _s Signature `s` parameter.
* @return _success Whether or not the call returned (rather than reverted).
* @return _returndata Data returned by the call.
*/
function execute(
bytes memory _transaction,
Lib_OVMCodec.EOASignatureType _signatureType,
uint8, // _v,
bytes32, // _r,
bytes32 // _s
)
override
public
returns (
bool _success,
bytes memory _returndata
)
{
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 nonce is right.
Lib_SafeExecutionManagerWrapper.safeREQUIRE(
decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(),
"Transaction nonce does not match the expected nonce."
);
// Contract creations are signalled by sending a transaction to the zero address.
if (decodedTx.to == address(0)) {
(address created, ) = Lib_SafeExecutionManagerWrapper.safeCREATE(
decodedTx.gasLimit,
decodedTx.data
);
// If the created address is the ZERO_ADDRESS then we know the deployment failed, though not why
return (created != address(0), abi.encode(created));
} else {
// We only want to bump the nonce for `ovmCALL` because `ovmCREATE` automatically bumps
// the nonce of the calling account. Normally an EOA would bump the nonce for both
// cases, but since this is a contract we'd end up bumping the nonce twice.
Lib_SafeExecutionManagerWrapper.safeINCREMENTNONCE();
return Lib_SafeExecutionManagerWrapper.safeCALL(
decodedTx.gasLimit,
decodedTx.to,
decodedTx.data
);
}
}
function qall(
uint256 _gasLimit,
address _to,
bytes memory _data
)
public
returns (
bool _success,
bytes memory _returndata
)
{
return Lib_SafeExecutionManagerWrapper.safeCALL(
_gasLimit,
_to,
_data
);
}
}
......@@ -222,12 +222,6 @@ export const makeContractDeployConfig = async (
OVM_SequencerEntrypoint: {
factory: getContractFactory('OVM_SequencerEntrypoint', undefined, true),
},
OVM_ProxySequencerEntrypoint: {
factory: getContractFactory('OVM_ProxySequencerEntrypoint'),
},
mockOVM_ECDSAContractAccount: {
factory: getContractFactory('mockOVM_ECDSAContractAccount'),
},
OVM_BondManager: {
factory: getContractFactory('mockOVM_BondManager'),
params: [AddressManager.address],
......
......@@ -146,14 +146,12 @@ export const makeStateDump = async (cfg: RollupDeployConfig): Promise<any> => {
'OVM_L2ToL1MessagePasser',
'OVM_ProxyEOA',
'OVM_ECDSAContractAccount',
'OVM_ProxySequencerEntrypoint',
'OVM_SequencerEntrypoint',
'OVM_L2CrossDomainMessenger',
'OVM_SafetyChecker',
'OVM_ExecutionManager',
'OVM_StateManager',
'OVM_ETH',
'mockOVM_ECDSAContractAccount',
],
deployOverrides: {},
waitForReceipts: false,
......
/**
* Predeploys are Solidity contracts that are injected into the initial L2 state and provide
* various useful functions.
*
* Notes:
* - 0x42...04 was the address of the OVM_ProxySequencerEntrypoint. This contract is no longer in
* use and has therefore been removed. We may place a new predeployed contract at this address
* in the future. See https://github.com/ethereum-optimism/optimism/pull/549 for more info.
*/
export const predeploys = {
OVM_L2ToL1MessagePasser: '0x4200000000000000000000000000000000000000',
OVM_L1MessageSender: '0x4200000000000000000000000000000000000001',
OVM_DeployerWhitelist: '0x4200000000000000000000000000000000000002',
OVM_ECDSAContractAccount: '0x4200000000000000000000000000000000000003',
OVM_ProxySequencerEntrypoint: '0x4200000000000000000000000000000000000004',
OVM_SequencerEntrypoint: '0x4200000000000000000000000000000000000005',
OVM_ETH: '0x4200000000000000000000000000000000000006',
OVM_L2CrossDomainMessenger: '0x4200000000000000000000000000000000000007',
......
import { expect } from '../../../setup'
/* External Imports */
import { ethers, waffle } from 'hardhat'
import { ContractFactory, Contract, Wallet, constants } from 'ethers'
import { MockContract, smockit } from '@eth-optimism/smock'
import { remove0x } from '@eth-optimism/core-utils'
/* Internal Imports */
import { decodeSolidityError } from '../../../helpers'
import { getContractFactory } from '../../../../src'
const callPredeploy = async (
Helper_PredeployCaller: Contract,
predeploy: Contract,
functionName: string,
functionParams?: any[]
): Promise<any> => {
return Helper_PredeployCaller.callPredeploy(
predeploy.address,
predeploy.interface.encodeFunctionData(functionName, functionParams || [])
)
}
const addrToBytes32 = (addr: string) =>
'0x' + '00'.repeat(12) + remove0x(addr.toLowerCase())
describe('OVM_ProxySequencerEntrypoint', () => {
let wallet: Wallet
before(async () => {
const provider = waffle.provider
;[wallet] = provider.getWallets()
})
let Factory__OVM_ProxySequencerEntrypoint: ContractFactory
before(async () => {
Factory__OVM_ProxySequencerEntrypoint = await ethers.getContractFactory(
'OVM_ProxySequencerEntrypoint'
)
})
let Mock__OVM_ExecutionManager: MockContract
let Helper_PredeployCaller: Contract
let OVM_SequencerEntrypoint: Contract
before(async () => {
Mock__OVM_ExecutionManager = await smockit(
await ethers.getContractFactory('OVM_ExecutionManager')
)
Mock__OVM_ExecutionManager.smocked.ovmCALLER.will.return.with(
await wallet.getAddress()
)
Mock__OVM_ExecutionManager.smocked.ovmEXTCODESIZE.will.return.with(0)
Mock__OVM_ExecutionManager.smocked.ovmCHAINID.will.return.with(420)
Helper_PredeployCaller = await (
await ethers.getContractFactory('Helper_PredeployCaller')
).deploy()
Helper_PredeployCaller.setTarget(Mock__OVM_ExecutionManager.address)
OVM_SequencerEntrypoint = await getContractFactory(
'OVM_SequencerEntrypoint',
wallet,
true
).deploy()
})
let OVM_ProxySequencerEntrypoint: Contract
beforeEach(async () => {
OVM_ProxySequencerEntrypoint = await Factory__OVM_ProxySequencerEntrypoint.deploy()
})
it(`should init the proxy with owner and implementation`, async () => {
Mock__OVM_ExecutionManager.smocked.ovmSLOAD.will.return.with(
`0x${'00'.repeat(32)}`
)
await callPredeploy(
Helper_PredeployCaller,
OVM_ProxySequencerEntrypoint,
'init',
[OVM_SequencerEntrypoint.address, await wallet.getAddress()]
)
const ovmSSTOREs: any = Mock__OVM_ExecutionManager.smocked.ovmSSTORE.calls
expect(ovmSSTOREs[0]._key).to.equal(`0x${'00'.repeat(31)}01`)
expect(ovmSSTOREs[0]._value).to.equal(
addrToBytes32(await wallet.getAddress())
)
expect(ovmSSTOREs[1]._key).to.equal(`0x${'00'.repeat(32)}`)
expect(ovmSSTOREs[1]._value).to.equal(
addrToBytes32(OVM_SequencerEntrypoint.address)
)
// expect(await OVM_ProxySequencerEntrypoint.implementation()).to.equal(
// OVM_SequencerEntrypoint.address
// )
})
it(`should revert if proxy has already been inited`, async () => {
Mock__OVM_ExecutionManager.smocked.ovmSLOAD.will.return.with(
addrToBytes32(await wallet.getAddress())
)
await callPredeploy(
Helper_PredeployCaller,
OVM_ProxySequencerEntrypoint,
'init',
[constants.AddressZero, constants.AddressZero]
)
const ovmREVERT: any = Mock__OVM_ExecutionManager.smocked.ovmREVERT.calls[0]
expect(decodeSolidityError(ovmREVERT._data)).to.equal(
'ProxySequencerEntrypoint has already been inited'
)
})
it(`should allow owner to upgrade Entrypoint`, async () => {
Mock__OVM_ExecutionManager.smocked.ovmSLOAD.will.return.with(
addrToBytes32(await wallet.getAddress())
)
await callPredeploy(
Helper_PredeployCaller,
OVM_ProxySequencerEntrypoint,
'upgrade',
[`0x${'12'.repeat(20)}`]
)
const ovmSSTORE: any = Mock__OVM_ExecutionManager.smocked.ovmSSTORE.calls[0]
expect(ovmSSTORE._key).to.equal(`0x${'00'.repeat(32)}`)
expect(ovmSSTORE._value).to.equal(addrToBytes32(`0x${'12'.repeat(20)}`))
})
it(`should revert if non-owner tries to upgrade Entrypoint`, async () => {
Mock__OVM_ExecutionManager.smocked.ovmSLOAD.will.return.with(
`0x${'00'.repeat(32)}`
)
await callPredeploy(
Helper_PredeployCaller,
OVM_ProxySequencerEntrypoint,
'upgrade',
[`0x${'12'.repeat(20)}`]
)
const ovmREVERT: any = Mock__OVM_ExecutionManager.smocked.ovmREVERT.calls[0]
expect(decodeSolidityError(ovmREVERT._data)).to.equal(
'Only owner can upgrade the Entrypoint'
)
})
it(`successfully calls ovmCREATEEOA through Entrypoint fallback`, async () => {
Mock__OVM_ExecutionManager.smocked.ovmSLOAD.will.return.with(
addrToBytes32(OVM_SequencerEntrypoint.address)
)
Mock__OVM_ExecutionManager.smocked.ovmDELEGATECALL.will.return.with([
true,
'0x',
])
const calldata = '0xdeadbeef'
await Helper_PredeployCaller.callPredeploy(
OVM_ProxySequencerEntrypoint.address,
calldata
)
const ovmDELEGATECALL: any =
Mock__OVM_ExecutionManager.smocked.ovmDELEGATECALL.calls[0]
expect(ovmDELEGATECALL._address).to.equal(OVM_SequencerEntrypoint.address)
expect(ovmDELEGATECALL._calldata).to.equal(calldata)
})
})
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