Skip to content

Commit

Permalink
OptimismPortal set initial balance through StorageSetter pattern (#250)
Browse files Browse the repository at this point in the history
* OptimismPortal revert

* tested & working

* test compilation fix

* spec test fix

* lint fix

* Revert "lint fix"

This reverts commit 77babf4.

* lint fix

* Semver lock

* semver2 fix

* snapshot update

* PR comments

* lint fix

---------

Co-authored-by: Maximilian Langenfeld <[email protected]>
  • Loading branch information
pahor167 and ezdac authored Oct 8, 2024
1 parent de71c06 commit fb72612
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 20 deletions.
27 changes: 27 additions & 0 deletions packages/contracts-bedrock/scripts/deploy/ChainAssertions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ISystemConfigV0 } from "scripts/interfaces/ISystemConfigV0.sol";
import { console2 as console } from "forge-std/console2.sol";

import { CeloTokenL1 } from "src/celo/CeloTokenL1.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

library ChainAssertions {
Vm internal constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
Expand Down Expand Up @@ -349,6 +350,32 @@ library ChainAssertions {
}
}

/// @notice Asserts the OptimismPortal custom gas token is setup correctly
function checkCustomGasTokenOptimismPortal(
Types.ContractSet memory _contracts,
DeployConfig _cfg,
bool _isProxy
)
internal
view
{
OptimismPortal portal = OptimismPortal(payable(_contracts.OptimismPortal));

uint256 expectedInitialBalance = 0;
if (_isProxy && _cfg.useCustomGasToken()) {
address customGasTokenAddress = _cfg.customGasTokenAddress();
IERC20 token = IERC20(customGasTokenAddress);
expectedInitialBalance = token.balanceOf(address(portal));
console.log("custom gas token expectedInitialBalance", expectedInitialBalance);
}

if (_isProxy) {
require(portal.balance() == expectedInitialBalance);
} else {
require(portal.balance() == 0);
}
}

/// @notice Asserts the OptimismPortal2 is setup correctly
function checkOptimismPortal2(
Types.ContractSet memory _contracts,
Expand Down
18 changes: 14 additions & 4 deletions packages/contracts-bedrock/scripts/deploy/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -413,13 +413,15 @@ contract Deploy is Deployer {

setupCustomGasToken();

address storageSetter = deployStorageSetter();

// Selectively initialize either the original OptimismPortal or the new OptimismPortal2. Since this will upgrade
// the proxy, we cannot initialize both.
if (cfg.useFaultProofs()) {
console.log("Fault proofs enabled. Initializing the OptimismPortal proxy with the OptimismPortal2.");
initializeOptimismPortal2();
} else {
initializeOptimismPortal();
initializeOptimismPortal(storageSetter);
}

initializeSystemConfig();
Expand All @@ -432,6 +434,8 @@ contract Deploy is Deployer {
initializeDelayedWETH();
initializePermissionedDelayedWETH();
initializeAnchorStateRegistry();

ChainAssertions.checkCustomGasTokenOptimismPortal({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
}

/// @notice Add AltDA setup to the OP chain
Expand Down Expand Up @@ -1275,7 +1279,7 @@ contract Deploy is Deployer {
}

/// @notice Initialize the OptimismPortal
function initializeOptimismPortal() public broadcast {
function initializeOptimismPortal(address strorageSetter) public broadcast {
console.log("Upgrading and initializing OptimismPortal proxy");
address optimismPortalProxy = mustGetAddress("OptimismPortalProxy");
address optimismPortal = mustGetAddress("OptimismPortal");
Expand All @@ -1289,6 +1293,13 @@ contract Deploy is Deployer {
customGasTokenAddress = cfg.customGasTokenAddress();
IERC20 token = IERC20(customGasTokenAddress);
initialBalance = token.balanceOf(optimismPortalProxy);

uint256 balanceStorageSlot = 61; // slot of _balance variable
_upgradeAndCallViaSafe({
_proxy: payable(optimismPortalProxy),
_implementation: strorageSetter,
_innerCallData: abi.encodeCall(StorageSetter.setUint, (bytes32(balanceStorageSlot), initialBalance))
});
}

_upgradeAndCallViaSafe({
Expand All @@ -1299,8 +1310,7 @@ contract Deploy is Deployer {
(
L2OutputOracle(l2OutputOracleProxy),
SystemConfig(systemConfigProxy),
SuperchainConfig(superchainConfigProxy),
initialBalance
SuperchainConfig(superchainConfigProxy)
)
)
});
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
"sourceCodeHash": "0x8e9a47583c4c3d711c2b7cc5e0f86495e29d4e79c38415dd3d342e1d1aae4fb7"
},
"src/L1/OptimismPortal.sol": {
"initCodeHash": "0x8f4ca1fa25ecc4602266e5f5eae6daa87afe8595c9d6b3e7e9e37cbe8c5643ed",
"sourceCodeHash": "0xd473cd0debf4a66f54e0932b6d260699e7b5eb55633b70f3e00dc2b1ad6c3a1d"
"initCodeHash": "0xfdc8cf0b0b26961f6ac493ee564761716447d263291bea4d366a7b94afe33392",
"sourceCodeHash": "0x9fe0a9001edecd2a04daada4ca9e17d66141b1c982f73653493b4703d2c675c4"
},
"src/L1/OptimismPortal2.sol": {
"initCodeHash": "0x12071439501e60420ab217cea4477306864014b66722d09b8cb8e01369f343ec",
Expand Down
5 changes: 0 additions & 5 deletions packages/contracts-bedrock/snapshots/abi/OptimismPortal.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,6 @@
"internalType": "contract SuperchainConfig",
"name": "_superchainConfig",
"type": "address"
},
{
"internalType": "uint256",
"name": "_initialBalance",
"type": "uint256"
}
],
"name": "initialize",
Expand Down
8 changes: 2 additions & 6 deletions packages/contracts-bedrock/src/L1/OptimismPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,18 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
initialize({
_l2Oracle: L2OutputOracle(address(0)),
_systemConfig: SystemConfig(address(0)),
_superchainConfig: SuperchainConfig(address(0)),
_initialBalance: 0
_superchainConfig: SuperchainConfig(address(0))
});
}

/// @notice Initializer.
/// @param _l2Oracle Contract of the L2OutputOracle.
/// @param _systemConfig Contract of the SystemConfig.
/// @param _superchainConfig Contract of the SuperchainConfig.
/// @param _initialBalance the initial balance assigned to the portal without using deposit txs.
function initialize(
L2OutputOracle _l2Oracle,
SystemConfig _systemConfig,
SuperchainConfig _superchainConfig,
uint256 _initialBalance
SuperchainConfig _superchainConfig
)
public
initializer
Expand All @@ -163,7 +160,6 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
if (l2Sender == address(0)) {
l2Sender = Constants.DEFAULT_L2_SENDER;
}
_balance = _initialBalance;
__ResourceMetering_init();
}

Expand Down
2 changes: 1 addition & 1 deletion packages/contracts-bedrock/test/Specs.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ contract Specification_Test is CommonTest {
});
_addSpec({ _name: "OptimismPortal", _sel: _getSel("finalizedWithdrawals(bytes32)") });
_addSpec({ _name: "OptimismPortal", _sel: _getSel("guardian()") });
_addSpec({ _name: "OptimismPortal", _sel: _getSel("initialize(address,address,address,uint256)") });
_addSpec({ _name: "OptimismPortal", _sel: _getSel("initialize(address,address,address)") });
_addSpec({ _name: "OptimismPortal", _sel: _getSel("isOutputFinalized(uint256)") });
_addSpec({ _name: "OptimismPortal", _sel: _getSel("l2Oracle()") });
_addSpec({ _name: "OptimismPortal", _sel: _getSel("l2Sender()") });
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/test/vendor/Initializable.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ contract Initializer_Test is Bridge_Initializer {
contracts.push(
InitializeableContract({
target: deploy.mustGetAddress("OptimismPortal"),
initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig, 0)),
initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)),
initializedSlotVal: deploy.loadInitializedSlot("OptimismPortal")
})
);
Expand All @@ -153,7 +153,7 @@ contract Initializer_Test is Bridge_Initializer {
contracts.push(
InitializeableContract({
target: address(optimismPortal),
initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig, 0)),
initCalldata: abi.encodeCall(optimismPortal.initialize, (l2OutputOracle, systemConfig, superchainConfig)),
initializedSlotVal: deploy.loadInitializedSlot("OptimismPortalProxy")
})
);
Expand Down

0 comments on commit fb72612

Please sign in to comment.