From 7b45fd339ea9dbd2c2ab5c73994a8262cff27ec7 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 7 Nov 2025 16:21:34 -0500 Subject: [PATCH 1/9] Add DeployFeesDepositor script --- .../scripts/deploy/DeployFeesDepositor.s.sol | 165 ++++++++++++++++++ .../test/opcm/DeployFeesDepositor.t.sol | 126 +++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol create mode 100644 packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol new file mode 100644 index 00000000000..28c1c28dafa --- /dev/null +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Script } from "forge-std/Script.sol"; +import { console2 as console } from "forge-std/console2.sol"; + +import { FeesDepositor } from "src/L1/FeesDepositor.sol"; +import { IFeesDepositor } from "interfaces/L1/IFeesDepositor.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; +import { IProxy } from "interfaces/universal/IProxy.sol"; + +import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; + +/// @title DeployFeesDepositor +/// @notice Script used to deploy and initialize the FeesDepositor contract. +contract DeployFeesDepositor is Script { + /// @notice Output addresses from deployment. + struct Output { + /// @notice The deployed FeesDepositor implementation address. + address feesDepositorImpl; + /// @notice The deployed FeesDepositor proxy address. + address feesDepositorProxy; + } + + bytes32 internal _salt = DeployUtils.DEFAULT_SALT; + + address deployer; + + /// @notice Deploys and initializes the FeesDepositor contract. + /// @param _proxyAdmin The address that will be the admin of the proxy. + /// @param _minDepositAmount The threshold at which fees are deposited. + /// @param _l2Recipient The L2 recipient of the fees. + /// @param _messenger The L1CrossDomainMessenger contract address. + /// @param _gasLimit The gas limit for the deposit transaction. + /// @return output_ The deployment output addresses. + function run( + address _proxyAdmin, + uint96 _minDepositAmount, + address _l2Recipient, + address _messenger, + uint32 _gasLimit + ) + public + returns (Output memory output_) + { + deployer = msg.sender; + + assertValidInput(_proxyAdmin, _l2Recipient, _messenger, _minDepositAmount, _gasLimit); + + // Deploy the implementation. + deployImplementation(output_); + + // Deploy the proxy. + deployProxy(_proxyAdmin, output_); + + // Initialize the proxy. + initializeProxy(_minDepositAmount, _l2Recipient, _messenger, _gasLimit, output_); + + // Transfer the ownership of the proxy to the final proxy. + transferToFinalProxyAdmin(_proxyAdmin, output_); + + // Log the results. + logResults(output_); + } + + /// @notice Deploys the FeesDepositor implementation contract. + /// @param _output The output struct to populate. + function deployImplementation(Output memory _output) internal { + FeesDepositor impl = FeesDepositor( + DeployUtils.createDeterministic({ + _name: "FeesDepositor", + _args: DeployUtils.encodeConstructor(abi.encodeCall(IFeesDepositor.__constructor__, ())), + _salt: _salt + }) + ); + + vm.label(address(impl), "FeesDepositorImpl"); + _output.feesDepositorImpl = address(impl); + } + + /// @notice Deploys the Proxy contract for FeesDepositor. + /// @param _proxyAdmin The address that will be the admin of the proxy. + /// @param _output The output struct to populate. + function deployProxy(address _proxyAdmin, Output memory _output) internal { + IProxy proxy = IProxy( + DeployUtils.createDeterministic({ + _name: "Proxy", + _args: DeployUtils.encodeConstructor(abi.encodeCall(IProxy.__constructor__, (deployer))), + _salt: _salt + }) + ); + + vm.label(address(proxy), "FeesDepositorProxy"); + _output.feesDepositorProxy = address(proxy); + } + + /// @notice Initializes the FeesDepositor proxy contract. + /// @param _minDepositAmount The threshold at which fees are deposited. + /// @param _l2Recipient The L2 recipient of the fees. + /// @param _messenger The L1CrossDomainMessenger contract address. + /// @param _gasLimit The gas limit for the deposit transaction. + /// @param _output The deployment output addresses. + function initializeProxy( + uint96 _minDepositAmount, + address _l2Recipient, + address _messenger, + uint32 _gasLimit, + Output memory _output + ) + internal + { + bytes memory initData = abi.encodeCall( + FeesDepositor.initialize, (_minDepositAmount, _l2Recipient, IL1CrossDomainMessenger(_messenger), _gasLimit) + ); + + console.log("Proxy admin:", deployer); + console.logBytes32( + vm.load(address(_output.feesDepositorProxy), bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)) + ); + vm.broadcast(deployer); + IProxy(payable(_output.feesDepositorProxy)) + .upgradeToAndCall({ _implementation: _output.feesDepositorImpl, _data: initData }); + } + + /// @notice Transfers the ownership of the proxy to the final proxy. + /// @param _proxyAdmin The address that will be the admin of the proxy. + function transferToFinalProxyAdmin(address _proxyAdmin, Output memory _output) internal { + vm.broadcast(deployer); + IProxy(payable(_output.feesDepositorProxy)).changeAdmin(_proxyAdmin); + } + + /// @notice Validates the input parameters. + /// @param _proxyAdmin The address that will be the admin of the proxy. + /// @param _l2Recipient The L2 recipient of the fees. + /// @param _messenger The L1CrossDomainMessenger contract address. + /// @param _minDepositAmount The threshold at which fees are deposited. + /// @param _gasLimit The gas limit for the deposit transaction. + function assertValidInput( + address _proxyAdmin, + address _l2Recipient, + address _messenger, + uint96 _minDepositAmount, + uint32 _gasLimit + ) + internal + pure + { + require(_proxyAdmin != address(0), "DeployFeesDepositor: proxyAdmin cannot be zero address"); + require(_l2Recipient != address(0), "DeployFeesDepositor: l2Recipient cannot be zero address"); + require(_messenger != address(0), "DeployFeesDepositor: messenger cannot be zero address"); + require(_minDepositAmount > 0, "DeployFeesDepositor: minDepositAmount must be greater than zero"); + require(_gasLimit > 0, "DeployFeesDepositor: gasLimit must be greater than zero"); + } + + /// @notice Logs the deployment results. + /// @param _output The deployment output addresses. + function logResults(Output memory _output) internal view { + console.log("=== FeesDepositor Deployment ==="); + console.log("Implementation:", _output.feesDepositorImpl); + console.log("Proxy:", _output.feesDepositorProxy); + console.log("================================"); + } +} + diff --git a/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol new file mode 100644 index 00000000000..489103f9261 --- /dev/null +++ b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import { Test } from "forge-std/Test.sol"; + +// Interfaces +import { IFeesDepositor } from "interfaces/L1/IFeesDepositor.sol"; +import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; +import { IProxy } from "interfaces/universal/IProxy.sol"; + +import { DeployFeesDepositor } from "scripts/deploy/DeployFeesDepositor.s.sol"; +import { FeesDepositor } from "src/L1/FeesDepositor.sol"; +import { Proxy } from "src/universal/Proxy.sol"; +import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; + +contract DeployFeesDepositor_Test is Test { + DeployFeesDepositor deployFeesDepositor; + + // Define default input variables for testing. + address defaultProxyAdmin = makeAddr("defaultProxyAdmin"); + address defaultL2Recipient = makeAddr("defaultL2Recipient"); + IL1CrossDomainMessenger defaultMessenger = IL1CrossDomainMessenger(makeAddr("defaultMessenger")); + uint96 defaultMinDepositAmount = 1 ether; + uint32 defaultGasLimit = 200_000; + + function setUp() public { + deployFeesDepositor = new DeployFeesDepositor(); + } + + function testFuzz_run_succeeds( + address _proxyAdmin, + uint96 _minDepositAmount, + address _l2Recipient, + address _messenger, + uint32 _gasLimit + ) + public + { + vm.assume(_proxyAdmin != address(0)); + vm.assume(_l2Recipient != address(0)); + vm.assume(_messenger != address(0)); + vm.assume(_minDepositAmount > 0); + vm.assume(_gasLimit > 0); + + // Run the deployment script. + DeployFeesDepositor.Output memory output1 = + deployFeesDepositor.run(_proxyAdmin, _minDepositAmount, _l2Recipient, _messenger, _gasLimit); + + // Verify the implementation is deployed correctly. + FeesDepositor impl = new FeesDepositor(); + assertEq(output1.feesDepositorImpl.code, address(impl).code, "Implementation code mismatch"); + + // Verify the proxy is deployed correctly. + Proxy proxy = new Proxy(_proxyAdmin); + assertEq(output1.feesDepositorProxy.code, address(proxy).code, "Proxy code mismatch"); + + // Verify the proxy admin is set correctly. + assertEq(EIP1967Helper.getAdmin(output1.feesDepositorProxy), _proxyAdmin, "Proxy admin mismatch"); + + // Verify the proxy implementation is set correctly. + assertEq( + EIP1967Helper.getImplementation(output1.feesDepositorProxy), + output1.feesDepositorImpl, + "Proxy implementation mismatch" + ); + + // Verify the FeesDepositor is initialized correctly. + FeesDepositor feesDepositor = FeesDepositor(payable(output1.feesDepositorProxy)); + assertEq(feesDepositor.minDepositAmount(), _minDepositAmount, "MinDepositAmount mismatch"); + assertEq(feesDepositor.l2Recipient(), _l2Recipient, "L2Recipient mismatch"); + assertEq(address(feesDepositor.messenger()), _messenger, "Messenger mismatch"); + assertEq(feesDepositor.gasLimit(), _gasLimit, "GasLimit mismatch"); + } + + function test_run_nullInput_reverts() public { + // Test zero proxyAdmin + vm.expectRevert("DeployFeesDepositor: proxyAdmin cannot be zero address"); + deployFeesDepositor.run( + address(0), defaultMinDepositAmount, defaultL2Recipient, address(defaultMessenger), defaultGasLimit + ); + + // Test zero l2Recipient + vm.expectRevert("DeployFeesDepositor: l2Recipient cannot be zero address"); + deployFeesDepositor.run( + defaultProxyAdmin, defaultMinDepositAmount, address(0), address(defaultMessenger), defaultGasLimit + ); + + // Test zero messenger + vm.expectRevert("DeployFeesDepositor: messenger cannot be zero address"); + deployFeesDepositor.run( + defaultProxyAdmin, defaultMinDepositAmount, defaultL2Recipient, address(0), defaultGasLimit + ); + + // Test zero minDepositAmount + vm.expectRevert("DeployFeesDepositor: minDepositAmount must be greater than zero"); + deployFeesDepositor.run(defaultProxyAdmin, 0, defaultL2Recipient, address(defaultMessenger), defaultGasLimit); + + // Test zero gasLimit + vm.expectRevert("DeployFeesDepositor: gasLimit must be greater than zero"); + deployFeesDepositor.run( + defaultProxyAdmin, defaultMinDepositAmount, defaultL2Recipient, address(defaultMessenger), 0 + ); + } + + function test_run_defaultInput_succeeds() public { + DeployFeesDepositor.Output memory output = deployFeesDepositor.run( + defaultProxyAdmin, defaultMinDepositAmount, defaultL2Recipient, address(defaultMessenger), defaultGasLimit + ); + + // Verify addresses are non-zero. + assertNotEq(output.feesDepositorImpl, address(0), "Implementation address is zero"); + assertNotEq(output.feesDepositorProxy, address(0), "Proxy address is zero"); + + // Verify contracts have code. + assertGt(output.feesDepositorImpl.code.length, 0, "Implementation has no code"); + assertGt(output.feesDepositorProxy.code.length, 0, "Proxy has no code"); + + // Verify the FeesDepositor is initialized correctly. + FeesDepositor feesDepositor = FeesDepositor(payable(output.feesDepositorProxy)); + assertEq(feesDepositor.minDepositAmount(), defaultMinDepositAmount, "MinDepositAmount mismatch"); + assertEq(feesDepositor.l2Recipient(), defaultL2Recipient, "L2Recipient mismatch"); + assertEq(address(feesDepositor.messenger()), address(defaultMessenger), "Messenger mismatch"); + assertEq(feesDepositor.gasLimit(), defaultGasLimit, "GasLimit mismatch"); + } +} + From 7c16f55009fa957317143ecb32095b7bbce85985 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 8 Nov 2025 10:13:50 -0500 Subject: [PATCH 2/9] Refactor deploy script to remove Output struct --- .../scripts/deploy/DeployFeesDepositor.s.sol | 69 +++++++------------ .../test/opcm/DeployFeesDepositor.t.sol | 26 +++---- 2 files changed, 38 insertions(+), 57 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol index 28c1c28dafa..67f62c53803 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -15,14 +15,6 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; /// @title DeployFeesDepositor /// @notice Script used to deploy and initialize the FeesDepositor contract. contract DeployFeesDepositor is Script { - /// @notice Output addresses from deployment. - struct Output { - /// @notice The deployed FeesDepositor implementation address. - address feesDepositorImpl; - /// @notice The deployed FeesDepositor proxy address. - address feesDepositorProxy; - } - bytes32 internal _salt = DeployUtils.DEFAULT_SALT; address deployer; @@ -33,7 +25,6 @@ contract DeployFeesDepositor is Script { /// @param _l2Recipient The L2 recipient of the fees. /// @param _messenger The L1CrossDomainMessenger contract address. /// @param _gasLimit The gas limit for the deposit transaction. - /// @return output_ The deployment output addresses. function run( address _proxyAdmin, uint96 _minDepositAmount, @@ -42,57 +33,50 @@ contract DeployFeesDepositor is Script { uint32 _gasLimit ) public - returns (Output memory output_) + returns (IFeesDepositor feesDepositorImpl, IProxy feesDepositorProxy) { deployer = msg.sender; assertValidInput(_proxyAdmin, _l2Recipient, _messenger, _minDepositAmount, _gasLimit); // Deploy the implementation. - deployImplementation(output_); + IFeesDepositor impl = deployImplementation(); // Deploy the proxy. - deployProxy(_proxyAdmin, output_); + IProxy proxy = deployProxy(); // Initialize the proxy. - initializeProxy(_minDepositAmount, _l2Recipient, _messenger, _gasLimit, output_); + initializeProxy(proxy, impl, _minDepositAmount, _l2Recipient, _messenger, _gasLimit); // Transfer the ownership of the proxy to the final proxy. - transferToFinalProxyAdmin(_proxyAdmin, output_); + transferToFinalProxyAdmin(_proxyAdmin, proxy); // Log the results. - logResults(output_); + logResults(impl, proxy); + + return (impl, proxy); } /// @notice Deploys the FeesDepositor implementation contract. - /// @param _output The output struct to populate. - function deployImplementation(Output memory _output) internal { - FeesDepositor impl = FeesDepositor( + function deployImplementation() internal returns (IFeesDepositor) { + return IFeesDepositor( DeployUtils.createDeterministic({ _name: "FeesDepositor", _args: DeployUtils.encodeConstructor(abi.encodeCall(IFeesDepositor.__constructor__, ())), _salt: _salt }) ); - - vm.label(address(impl), "FeesDepositorImpl"); - _output.feesDepositorImpl = address(impl); } /// @notice Deploys the Proxy contract for FeesDepositor. - /// @param _proxyAdmin The address that will be the admin of the proxy. - /// @param _output The output struct to populate. - function deployProxy(address _proxyAdmin, Output memory _output) internal { - IProxy proxy = IProxy( + function deployProxy() internal returns (IProxy) { + return IProxy( DeployUtils.createDeterministic({ _name: "Proxy", _args: DeployUtils.encodeConstructor(abi.encodeCall(IProxy.__constructor__, (deployer))), _salt: _salt }) ); - - vm.label(address(proxy), "FeesDepositorProxy"); - _output.feesDepositorProxy = address(proxy); } /// @notice Initializes the FeesDepositor proxy contract. @@ -100,34 +84,30 @@ contract DeployFeesDepositor is Script { /// @param _l2Recipient The L2 recipient of the fees. /// @param _messenger The L1CrossDomainMessenger contract address. /// @param _gasLimit The gas limit for the deposit transaction. - /// @param _output The deployment output addresses. function initializeProxy( + IProxy _feesDepositorProxy, + IFeesDepositor _feesDepositorImpl, uint96 _minDepositAmount, address _l2Recipient, address _messenger, - uint32 _gasLimit, - Output memory _output + uint32 _gasLimit ) internal { bytes memory initData = abi.encodeCall( - FeesDepositor.initialize, (_minDepositAmount, _l2Recipient, IL1CrossDomainMessenger(_messenger), _gasLimit) + IFeesDepositor.initialize, (_minDepositAmount, _l2Recipient, IL1CrossDomainMessenger(_messenger), _gasLimit) ); - console.log("Proxy admin:", deployer); - console.logBytes32( - vm.load(address(_output.feesDepositorProxy), bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)) - ); vm.broadcast(deployer); - IProxy(payable(_output.feesDepositorProxy)) - .upgradeToAndCall({ _implementation: _output.feesDepositorImpl, _data: initData }); + IProxy(_feesDepositorProxy) + .upgradeToAndCall({ _implementation: address(_feesDepositorImpl), _data: initData }); } /// @notice Transfers the ownership of the proxy to the final proxy. /// @param _proxyAdmin The address that will be the admin of the proxy. - function transferToFinalProxyAdmin(address _proxyAdmin, Output memory _output) internal { + function transferToFinalProxyAdmin(address _proxyAdmin, IProxy _feesDepositorProxy) internal { vm.broadcast(deployer); - IProxy(payable(_output.feesDepositorProxy)).changeAdmin(_proxyAdmin); + _feesDepositorProxy.changeAdmin(_proxyAdmin); } /// @notice Validates the input parameters. @@ -154,11 +134,12 @@ contract DeployFeesDepositor is Script { } /// @notice Logs the deployment results. - /// @param _output The deployment output addresses. - function logResults(Output memory _output) internal view { + /// @param _feesDepositorImpl The deployed FeesDepositor implementation address. + /// @param _feesDepositorProxy The deployed FeesDepositor proxy address. + function logResults(IFeesDepositor _feesDepositorImpl, IProxy _feesDepositorProxy) internal view { console.log("=== FeesDepositor Deployment ==="); - console.log("Implementation:", _output.feesDepositorImpl); - console.log("Proxy:", _output.feesDepositorProxy); + console.log("Implementation:", address(_feesDepositorImpl)); + console.log("Proxy:", address(_feesDepositorProxy)); console.log("================================"); } } diff --git a/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol index 489103f9261..620cdcde189 100644 --- a/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol +++ b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol @@ -43,29 +43,29 @@ contract DeployFeesDepositor_Test is Test { vm.assume(_gasLimit > 0); // Run the deployment script. - DeployFeesDepositor.Output memory output1 = + (IFeesDepositor feesDepositorImpl, IProxy feesDepositorProxy) = deployFeesDepositor.run(_proxyAdmin, _minDepositAmount, _l2Recipient, _messenger, _gasLimit); // Verify the implementation is deployed correctly. FeesDepositor impl = new FeesDepositor(); - assertEq(output1.feesDepositorImpl.code, address(impl).code, "Implementation code mismatch"); + assertEq(address(feesDepositorImpl).code, address(impl).code, "Implementation code mismatch"); // Verify the proxy is deployed correctly. Proxy proxy = new Proxy(_proxyAdmin); - assertEq(output1.feesDepositorProxy.code, address(proxy).code, "Proxy code mismatch"); + assertEq(address(feesDepositorProxy).code, address(proxy).code, "Proxy code mismatch"); // Verify the proxy admin is set correctly. - assertEq(EIP1967Helper.getAdmin(output1.feesDepositorProxy), _proxyAdmin, "Proxy admin mismatch"); + assertEq(EIP1967Helper.getAdmin(address(feesDepositorProxy)), _proxyAdmin, "Proxy admin mismatch"); // Verify the proxy implementation is set correctly. assertEq( - EIP1967Helper.getImplementation(output1.feesDepositorProxy), - output1.feesDepositorImpl, + EIP1967Helper.getImplementation(address(feesDepositorProxy)), + address(feesDepositorImpl), "Proxy implementation mismatch" ); // Verify the FeesDepositor is initialized correctly. - FeesDepositor feesDepositor = FeesDepositor(payable(output1.feesDepositorProxy)); + FeesDepositor feesDepositor = FeesDepositor(payable(address(feesDepositorProxy))); assertEq(feesDepositor.minDepositAmount(), _minDepositAmount, "MinDepositAmount mismatch"); assertEq(feesDepositor.l2Recipient(), _l2Recipient, "L2Recipient mismatch"); assertEq(address(feesDepositor.messenger()), _messenger, "Messenger mismatch"); @@ -103,20 +103,20 @@ contract DeployFeesDepositor_Test is Test { } function test_run_defaultInput_succeeds() public { - DeployFeesDepositor.Output memory output = deployFeesDepositor.run( + (IFeesDepositor feesDepositorImpl, IProxy feesDepositorProxy) = deployFeesDepositor.run( defaultProxyAdmin, defaultMinDepositAmount, defaultL2Recipient, address(defaultMessenger), defaultGasLimit ); // Verify addresses are non-zero. - assertNotEq(output.feesDepositorImpl, address(0), "Implementation address is zero"); - assertNotEq(output.feesDepositorProxy, address(0), "Proxy address is zero"); + assertNotEq(address(feesDepositorImpl), address(0), "Implementation address is zero"); + assertNotEq(address(feesDepositorProxy), address(0), "Proxy address is zero"); // Verify contracts have code. - assertGt(output.feesDepositorImpl.code.length, 0, "Implementation has no code"); - assertGt(output.feesDepositorProxy.code.length, 0, "Proxy has no code"); + assertGt(address(feesDepositorImpl).code.length, 0, "Implementation has no code"); + assertGt(address(feesDepositorProxy).code.length, 0, "Proxy has no code"); // Verify the FeesDepositor is initialized correctly. - FeesDepositor feesDepositor = FeesDepositor(payable(output.feesDepositorProxy)); + IFeesDepositor feesDepositor = IFeesDepositor(payable(address(feesDepositorProxy))); assertEq(feesDepositor.minDepositAmount(), defaultMinDepositAmount, "MinDepositAmount mismatch"); assertEq(feesDepositor.l2Recipient(), defaultL2Recipient, "L2Recipient mismatch"); assertEq(address(feesDepositor.messenger()), address(defaultMessenger), "Messenger mismatch"); From 8c7e06b40b29e978b7dd358d9829bf47f5f65ff3 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Sat, 8 Nov 2025 10:19:36 -0500 Subject: [PATCH 3/9] forge fmt --- .../scripts/deploy/DeployFeesDepositor.s.sol | 4 +--- .../contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol index 67f62c53803..e36653cac8d 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -99,8 +99,7 @@ contract DeployFeesDepositor is Script { ); vm.broadcast(deployer); - IProxy(_feesDepositorProxy) - .upgradeToAndCall({ _implementation: address(_feesDepositorImpl), _data: initData }); + IProxy(_feesDepositorProxy).upgradeToAndCall({ _implementation: address(_feesDepositorImpl), _data: initData }); } /// @notice Transfers the ownership of the proxy to the final proxy. @@ -143,4 +142,3 @@ contract DeployFeesDepositor is Script { console.log("================================"); } } - diff --git a/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol index 620cdcde189..6284d7de33a 100644 --- a/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol +++ b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol @@ -123,4 +123,3 @@ contract DeployFeesDepositor_Test is Test { assertEq(feesDepositor.gasLimit(), defaultGasLimit, "GasLimit mismatch"); } } - From d913db40e88de6b98eb1d71dad16708f03cd9c20 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 10 Nov 2025 09:46:46 -0500 Subject: [PATCH 4/9] Make logResults() pure --- .../contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol index e36653cac8d..7fc0fcc846a 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -135,7 +135,7 @@ contract DeployFeesDepositor is Script { /// @notice Logs the deployment results. /// @param _feesDepositorImpl The deployed FeesDepositor implementation address. /// @param _feesDepositorProxy The deployed FeesDepositor proxy address. - function logResults(IFeesDepositor _feesDepositorImpl, IProxy _feesDepositorProxy) internal view { + function logResults(IFeesDepositor _feesDepositorImpl, IProxy _feesDepositorProxy) internal pure { console.log("=== FeesDepositor Deployment ==="); console.log("Implementation:", address(_feesDepositorImpl)); console.log("Proxy:", address(_feesDepositorProxy)); From 87f719b871793f06cd29d6f3ee4e5026eaf4914a Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 10 Nov 2025 09:48:52 -0500 Subject: [PATCH 5/9] fix return value names --- .../contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol index 7fc0fcc846a..4eb470c94b1 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -33,7 +33,7 @@ contract DeployFeesDepositor is Script { uint32 _gasLimit ) public - returns (IFeesDepositor feesDepositorImpl, IProxy feesDepositorProxy) + returns (IFeesDepositor, IProxy) { deployer = msg.sender; From ece8998d650dbd585849b40b328fb1b69a36df1f Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 10 Nov 2025 10:38:26 -0500 Subject: [PATCH 6/9] remove unused import --- .../contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol index 4eb470c94b1..740ae29de81 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.15; import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; -import { FeesDepositor } from "src/L1/FeesDepositor.sol"; import { IFeesDepositor } from "interfaces/L1/IFeesDepositor.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { IL1CrossDomainMessenger } from "interfaces/L1/IL1CrossDomainMessenger.sol"; From 5ed81cbf246bfa7d3d13a26985d7a40ee129437a Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 10 Nov 2025 14:00:29 -0500 Subject: [PATCH 7/9] Apply suggestions from code review Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com> --- .../scripts/deploy/DeployFeesDepositor.s.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol index 740ae29de81..06561342e0c 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -47,7 +47,7 @@ contract DeployFeesDepositor is Script { // Initialize the proxy. initializeProxy(proxy, impl, _minDepositAmount, _l2Recipient, _messenger, _gasLimit); - // Transfer the ownership of the proxy to the final proxy. + // Transfer the ownership of the proxy to the final proxy admin. transferToFinalProxyAdmin(_proxyAdmin, proxy); // Log the results. @@ -101,7 +101,7 @@ contract DeployFeesDepositor is Script { IProxy(_feesDepositorProxy).upgradeToAndCall({ _implementation: address(_feesDepositorImpl), _data: initData }); } - /// @notice Transfers the ownership of the proxy to the final proxy. + /// @notice Transfers the ownership of the proxy to the final proxy admin. /// @param _proxyAdmin The address that will be the admin of the proxy. function transferToFinalProxyAdmin(address _proxyAdmin, IProxy _feesDepositorProxy) internal { vm.broadcast(deployer); From 9539e1338acd1278e46910024681c6311a0ca575 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 10 Nov 2025 14:01:15 -0500 Subject: [PATCH 8/9] Add missing natspec --- .../contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol index 06561342e0c..9ce2d14e9fe 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployFeesDepositor.s.sol @@ -79,6 +79,8 @@ contract DeployFeesDepositor is Script { } /// @notice Initializes the FeesDepositor proxy contract. + /// @param _feesDepositorProxy The address of the FeesDepositor proxy. + /// @param _feesDepositorImpl The address of the FeesDepositor implementation. /// @param _minDepositAmount The threshold at which fees are deposited. /// @param _l2Recipient The L2 recipient of the fees. /// @param _messenger The L1CrossDomainMessenger contract address. From 3d15a478ffbb1300a9e40fa1a196b5d0c719a96c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 25 Nov 2025 08:35:43 -0500 Subject: [PATCH 9/9] Add natspec to tests --- .../contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol index 6284d7de33a..e8d934427be 100644 --- a/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol +++ b/packages/contracts-bedrock/test/opcm/DeployFeesDepositor.t.sol @@ -13,6 +13,8 @@ import { FeesDepositor } from "src/L1/FeesDepositor.sol"; import { Proxy } from "src/universal/Proxy.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; +/// @title DeployFeesDepositor_Test +/// @notice This test is used to test the DeployFeesDepositor script. contract DeployFeesDepositor_Test is Test { DeployFeesDepositor deployFeesDepositor; @@ -23,10 +25,12 @@ contract DeployFeesDepositor_Test is Test { uint96 defaultMinDepositAmount = 1 ether; uint32 defaultGasLimit = 200_000; + /// @notice Sets up the test suite. function setUp() public { deployFeesDepositor = new DeployFeesDepositor(); } + /// @notice Tests that the DeployFeesDepositor script succeeds with valid fuzzed input values. function testFuzz_run_succeeds( address _proxyAdmin, uint96 _minDepositAmount, @@ -72,6 +76,7 @@ contract DeployFeesDepositor_Test is Test { assertEq(feesDepositor.gasLimit(), _gasLimit, "GasLimit mismatch"); } + /// @notice Tests that the DeployFeesDepositor script reverts when called with zero input values. function test_run_nullInput_reverts() public { // Test zero proxyAdmin vm.expectRevert("DeployFeesDepositor: proxyAdmin cannot be zero address"); @@ -102,6 +107,7 @@ contract DeployFeesDepositor_Test is Test { ); } + /// @notice Tests that the DeployFeesDepositor script succeeds when called with default input values. function test_run_defaultInput_succeeds() public { (IFeesDepositor feesDepositorImpl, IProxy feesDepositorProxy) = deployFeesDepositor.run( defaultProxyAdmin, defaultMinDepositAmount, defaultL2Recipient, address(defaultMessenger), defaultGasLimit