Commit 0d0df070 authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: cleanup

contracts-bedrock: fix deployment

lint: fix

contracts-bedrock: snapshot regenerate

contracts-bedrock: portal pausability in constructor

contracts-bedrock: cleanup

contracts-bedrock: better comments

contracts-bedrock: regenerate invariant docs
parent 41accd0b
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -123,6 +123,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) { ...@@ -123,6 +123,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Initialize the OptimismPortal without being paused
data, err = portalABI.Pack("initialize", false) data, err = portalABI.Pack("initialize", false)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot abi encode initialize for OptimismPortal: %w", err) return nil, fmt.Errorf("cannot abi encode initialize for OptimismPortal: %w", err)
...@@ -290,11 +291,15 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend) ...@@ -290,11 +291,15 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend)
}, },
}, },
{ {
// The implementation of the OptimismPortal is deployed
// as being paused to prevent invalid usage of the network
// as only the proxy should be used
Name: "OptimismPortal", Name: "OptimismPortal",
Args: []interface{}{ Args: []interface{}{
predeploys.DevL2OutputOracleAddr, predeploys.DevL2OutputOracleAddr,
config.FinalSystemOwner, config.FinalSystemOwner,
uint642Big(config.FinalizationPeriodSeconds), uint642Big(config.FinalizationPeriodSeconds),
true, // _paused
}, },
}, },
{ {
...@@ -359,6 +364,7 @@ func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep ...@@ -359,6 +364,7 @@ func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep
deployment.Args[0].(common.Address), deployment.Args[0].(common.Address),
deployment.Args[1].(common.Address), deployment.Args[1].(common.Address),
deployment.Args[2].(*big.Int), deployment.Args[2].(*big.Int),
deployment.Args[3].(bool),
) )
case "L1CrossDomainMessenger": case "L1CrossDomainMessenger":
_, tx, _, err = bindings.DeployL1CrossDomainMessenger( _, tx, _, err = bindings.DeployL1CrossDomainMessenger(
......
This diff is collapsed.
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
| l2Sender | address | 50 | 0 | 20 | contracts/L1/OptimismPortal.sol:OptimismPortal | | l2Sender | address | 50 | 0 | 20 | contracts/L1/OptimismPortal.sol:OptimismPortal |
| finalizedWithdrawals | mapping(bytes32 => bool) | 51 | 0 | 32 | contracts/L1/OptimismPortal.sol:OptimismPortal | | finalizedWithdrawals | mapping(bytes32 => bool) | 51 | 0 | 32 | contracts/L1/OptimismPortal.sol:OptimismPortal |
| provenWithdrawals | mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal) | 52 | 0 | 32 | contracts/L1/OptimismPortal.sol:OptimismPortal | | provenWithdrawals | mapping(bytes32 => struct OptimismPortal.ProvenWithdrawal) | 52 | 0 | 32 | contracts/L1/OptimismPortal.sol:OptimismPortal |
| paused | bool | 53 | 0 | 1 | contracts/L1/OptimismPortal.sol:OptimismPortal |
======================= =======================
➡ contracts/L1/SystemConfig.sol:SystemConfig ➡ contracts/L1/SystemConfig.sol:SystemConfig
......
...@@ -85,7 +85,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -85,7 +85,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
* deposits and withdrawals are paused. This may be removed in the * deposits and withdrawals are paused. This may be removed in the
* future. * future.
*/ */
bool public paused = false; bool public paused;
/** /**
* @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event * @notice Emitted when a transaction is deposited from L1 to L2. The parameters of this event
...@@ -145,21 +145,23 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -145,21 +145,23 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
} }
/** /**
* @custom:semver 1.0.0 * @custom:semver 1.1.0
* *
* @param _l2Oracle Address of the L2OutputOracle contract. * @param _l2Oracle Address of the L2OutputOracle contract.
* @param _guardian Address that can pause deposits and withdrawals. * @param _guardian Address that can pause deposits and withdrawals.
* @param _finalizationPeriodSeconds Output finalization time in seconds. * @param _finalizationPeriodSeconds Output finalization time in seconds.
* @param _paused Sets the contract's pausability state.
*/ */
constructor( constructor(
L2OutputOracle _l2Oracle, L2OutputOracle _l2Oracle,
address _guardian, address _guardian,
uint256 _finalizationPeriodSeconds uint256 _finalizationPeriodSeconds,
bool _paused
) Semver(1, 1, 0) { ) Semver(1, 1, 0) {
L2_ORACLE = _l2Oracle; L2_ORACLE = _l2Oracle;
GUARDIAN = _guardian; GUARDIAN = _guardian;
FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds; FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
initialize(true); initialize(_paused);
} }
/** /**
......
...@@ -319,7 +319,7 @@ contract SystemDictator is OwnableUpgradeable { ...@@ -319,7 +319,7 @@ contract SystemDictator is OwnableUpgradeable {
) )
); );
// Upgrade and initialize the OptimismPortal as paused. // Upgrade and initialize the OptimismPortal.
config.globalConfig.proxyAdmin.upgradeAndCall( config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.optimismPortalProxy), payable(config.proxyAddressConfig.optimismPortalProxy),
address(config.implementationAddressConfig.optimismPortalImpl), address(config.implementationAddressConfig.optimismPortalImpl),
......
...@@ -12,7 +12,8 @@ contract EchidnaFuzzOptimismPortal { ...@@ -12,7 +12,8 @@ contract EchidnaFuzzOptimismPortal {
portal = new OptimismPortal({ portal = new OptimismPortal({
_l2Oracle: L2OutputOracle(address(0)), _l2Oracle: L2OutputOracle(address(0)),
_guardian: address(0), _guardian: address(0),
_finalizationPeriodSeconds: 10 _finalizationPeriodSeconds: 10,
_paused: false
}); });
} }
......
...@@ -119,6 +119,7 @@ contract L2OutputOracle_Initializer is CommonTest { ...@@ -119,6 +119,7 @@ contract L2OutputOracle_Initializer is CommonTest {
} }
function setUp() public virtual override { function setUp() public virtual override {
super.setUp();
guardian = makeAddr("guardian"); guardian = makeAddr("guardian");
// By default the first block has timestamp and number zero, which will cause underflows in the // By default the first block has timestamp and number zero, which will cause underflows in the
...@@ -169,7 +170,8 @@ contract Portal_Initializer is L2OutputOracle_Initializer { ...@@ -169,7 +170,8 @@ contract Portal_Initializer is L2OutputOracle_Initializer {
opImpl = new OptimismPortal({ opImpl = new OptimismPortal({
_l2Oracle: oracle, _l2Oracle: oracle,
_guardian: guardian, _guardian: guardian,
_finalizationPeriodSeconds: 7 days _finalizationPeriodSeconds: 7 days,
_paused: true
}); });
Proxy proxy = new Proxy(multisig); Proxy proxy = new Proxy(multisig);
vm.prank(multisig); vm.prank(multisig);
...@@ -232,7 +234,8 @@ contract Messenger_Initializer is L2OutputOracle_Initializer { ...@@ -232,7 +234,8 @@ contract Messenger_Initializer is L2OutputOracle_Initializer {
op = new OptimismPortal({ op = new OptimismPortal({
_l2Oracle: oracle, _l2Oracle: oracle,
_guardian: guardian, _guardian: guardian,
_finalizationPeriodSeconds: 7 days _finalizationPeriodSeconds: 7 days,
_paused: false
}); });
vm.label(address(op), "OptimismPortal"); vm.label(address(op), "OptimismPortal");
vm.prank(op.GUARDIAN()); vm.prank(op.GUARDIAN());
......
...@@ -21,6 +21,9 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -21,6 +21,9 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), false); assertEq(op.paused(), false);
} }
/**
* @notice The OptimismPortal can be paused by the GUARDIAN
*/
function test_pause_succeeds() external { function test_pause_succeeds() external {
address guardian = op.GUARDIAN(); address guardian = op.GUARDIAN();
...@@ -35,6 +38,10 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -35,6 +38,10 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), true); assertEq(op.paused(), true);
} }
/**
* @notice The OptimismPortal reverts when an account that is not the
* GUARDIAN calls `pause()`
*/
function test_pause_onlyOwner_reverts() external { function test_pause_onlyOwner_reverts() external {
assertEq(op.paused(), false); assertEq(op.paused(), false);
...@@ -46,6 +53,9 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -46,6 +53,9 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), false); assertEq(op.paused(), false);
} }
/**
* @notice The OptimismPortal can be unpaused by the GUARDIAN
*/
function test_unpause_succeeds() external { function test_unpause_succeeds() external {
address guardian = op.GUARDIAN(); address guardian = op.GUARDIAN();
...@@ -61,6 +71,10 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -61,6 +71,10 @@ contract OptimismPortal_Test is Portal_Initializer {
assertEq(op.paused(), false); assertEq(op.paused(), false);
} }
/**
* @notice The OptimismPortal reverts when an account that is not
* the GUARDIAN calls `unpause()`
*/
function test_unpause_onlyOwner_reverts() external { function test_unpause_onlyOwner_reverts() external {
address guardian = op.GUARDIAN(); address guardian = op.GUARDIAN();
......
...@@ -13,13 +13,28 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -13,13 +13,28 @@ const deployFn: DeployFunction = async (hre) => {
'L2OutputOracleProxy' 'L2OutputOracleProxy'
) )
const finalSystemOwner = hre.deployConfig.finalSystemOwner
const finalSystemOwnerCode = await hre.ethers.provider.getCode(
finalSystemOwner
)
if (finalSystemOwnerCode === '0x') {
console.log(
`WARNING: setting OptimismPortal.GUARDIAN to ${finalSystemOwner} and it has no code`
)
}
// Deploy the OptimismPortal implementation as paused to
// ensure that users do not interact with it and instead
// interact with the proxied contract.
// The `finalSystemOwner` is set at the GUARDIAN.
await deploy({ await deploy({
hre, hre,
name: 'OptimismPortal', name: 'OptimismPortal',
args: [ args: [
L2OutputOracleProxy.address, L2OutputOracleProxy.address,
hre.deployConfig.finalSystemOwner, finalSystemOwner,
hre.deployConfig.finalizationPeriodSeconds, hre.deployConfig.finalizationPeriodSeconds,
true, // paused
], ],
postDeployAction: async (contract) => { postDeployAction: async (contract) => {
await assertContractVariable( await assertContractVariable(
......
...@@ -294,11 +294,15 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -294,11 +294,15 @@ const deployFn: DeployFunction = async (hre) => {
if (await isStep(SystemDictator, 6)) { if (await isStep(SystemDictator, 6)) {
console.log(` console.log(`
Unpause the OptimismPortal Unpause the OptimismPortal. The GUARDIAN account should be used. In practice
this is the multisig. In test networks, the OptimismPortal is initialized
without being paused.
`) `)
if (isLiveDeployer) { if (isLiveDeployer) {
console.log('OptimismPortal already not paused.') console.log('WARNING: OptimismPortal configured to not be paused')
console.log('This should only happen for test environments')
await assertContractVariable(OptimismPortal, 'paused', false)
} else { } else {
const tx = await OptimismPortal.populateTransaction.unpause() const tx = await OptimismPortal.populateTransaction.unpause()
console.log(`Please unpause the OptimismPortal...`) console.log(`Please unpause the OptimismPortal...`)
...@@ -309,7 +313,8 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -309,7 +313,8 @@ const deployFn: DeployFunction = async (hre) => {
await awaitCondition( await awaitCondition(
async () => { async () => {
return !OptimismPortal.paused() const paused = await OptimismPortal.paused()
return !paused
}, },
30000, 30000,
1000 1000
......
...@@ -19,6 +19,6 @@ This invariant asserts that there is no chain of calls that can be made that wil ...@@ -19,6 +19,6 @@ This invariant asserts that there is no chain of calls that can be made that wil
## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`.
**Test:** [`FuzzOptimismPortal.sol#L37`](../contracts/echidna/FuzzOptimismPortal.sol#L37) **Test:** [`FuzzOptimismPortal.sol#L42`](../contracts/echidna/FuzzOptimismPortal.sol#L42)
All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed.
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