Skip to content

Commit 0b2d0b2

Browse files
authored
use DeployUtils lib for deployments in deploy script (ethereum-optimism#12070)
* use DeployUtils lib for deployments in deploy script * type safety for constructor args and use encode constructor * add comments to helper functions * add commentsd, deploy scripts cleanup * fix assertion * modify interface checker script to always expect a pseudo-constructor, modify failing interfaces * assert contracts with no constructors to have pseudo-constructors with no input * use pseudo-constructor encoding for contracts with no constructor defined
1 parent e2599c6 commit 0b2d0b2

31 files changed

+341
-112
lines changed

packages/contracts-bedrock/scripts/checks/check-interfaces.sh

+23
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,29 @@ for interface_file in $JSON_FILES; do
208208
normalized_interface_abi=$(normalize_abi "$interface_abi")
209209
normalized_contract_abi=$(normalize_abi "$contract_abi")
210210

211+
# Check if the contract ABI has no constructor but the interface is missing __constructor__
212+
contract_has_constructor=$(echo "$normalized_contract_abi" | jq 'any(.[]; .type == "constructor")')
213+
interface_has_default_pseudo_constructor=$(echo "$normalized_interface_abi" | jq 'any(.[]; .type == "constructor" and .inputs == [])')
214+
215+
# If any contract has no constructor and its corresponding interface also does not have one, flag it as a detected issue
216+
if [ "$contract_has_constructor" = false ] && [ "$interface_has_default_pseudo_constructor" = false ]; then
217+
if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then
218+
echo "$contract_name" >> "$REPORTED_INTERFACES_FILE"
219+
if ! is_excluded "$contract_name"; then
220+
echo "Issue found in ABI for interface $contract_name from file $interface_file."
221+
echo "Interface $contract_name must have a function named '__constructor__' as the corresponding contract has no constructor in its ABI."
222+
issues_detected=true
223+
fi
224+
fi
225+
continue
226+
fi
227+
228+
# removes the pseudo constructor json entry from the interface files where the corresponding contract file has no constructor
229+
# this is to ensure it is not flagged as a diff in the next step below
230+
if [ "$contract_has_constructor" = false ] && [ "$interface_has_default_pseudo_constructor" ]; then
231+
normalized_interface_abi=$(echo "$normalized_interface_abi" | jq 'map(select(.type != "constructor"))')
232+
fi
233+
211234
# Use jq to compare the ABIs
212235
if ! diff_result=$(diff -u <(echo "$normalized_interface_abi" | jq 'sort') <(echo "$normalized_contract_abi" | jq 'sort')); then
213236
if ! grep -q "^$contract_name$" "$REPORTED_INTERFACES_FILE"; then

packages/contracts-bedrock/scripts/deploy/Deploy.s.sol

+190-89
Large diffs are not rendered by default.

packages/contracts-bedrock/scripts/fpac/FPACOPS2.s.sol

+21-16
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,14 @@ contract FPACOPS2 is Deploy, StdAssertions {
9191
function deployCannonDisputeGame() internal broadcast {
9292
console.log("Deploying CannonFaultDisputeGame implementation");
9393

94-
save(
95-
"CannonFaultDisputeGame",
96-
address(
97-
_deploy(
98-
"FaultDisputeGame",
99-
abi.encode(
94+
DeployUtils.create2AndSave({
95+
_save: this,
96+
_name: "FaultDisputeGame",
97+
_nick: "CannonFaultDisputeGame",
98+
_args: DeployUtils.encodeConstructor(
99+
abi.encodeCall(
100+
IFaultDisputeGame.__constructor__,
101+
(
100102
GameTypes.CANNON,
101103
loadMipsAbsolutePrestate(),
102104
cfg.faultGameMaxDepth(),
@@ -109,20 +111,22 @@ contract FPACOPS2 is Deploy, StdAssertions {
109111
cfg.l2ChainID()
110112
)
111113
)
112-
)
113-
);
114+
),
115+
_salt: _implSalt()
116+
});
114117
}
115118

116119
/// @notice Deploys the PermissionedDisputeGame.
117120
function deployPermissionedDisputeGame() internal broadcast {
118121
console.log("Deploying PermissionedDisputeGame implementation");
119122

120-
save(
121-
"PermissionedDisputeGame",
122-
address(
123-
_deploy(
124-
"PermissionedDisputeGame",
125-
abi.encode(
123+
DeployUtils.create2AndSave({
124+
_save: this,
125+
_name: "PermissionedDisputeGame",
126+
_args: DeployUtils.encodeConstructor(
127+
abi.encodeCall(
128+
IPermissionedDisputeGame.__constructor__,
129+
(
126130
GameTypes.PERMISSIONED_CANNON,
127131
loadMipsAbsolutePrestate(),
128132
cfg.faultGameMaxDepth(),
@@ -137,8 +141,9 @@ contract FPACOPS2 is Deploy, StdAssertions {
137141
cfg.l2OutputOracleChallenger()
138142
)
139143
)
140-
)
141-
);
144+
),
145+
_salt: _implSalt()
146+
});
142147
}
143148

144149
/// @notice Initializes the DelayedWETH proxy.

packages/contracts-bedrock/scripts/libraries/DeployUtils.sol

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Artifacts } from "scripts/Artifacts.s.sol";
88

99
// Libraries
1010
import { LibString } from "@solady/utils/LibString.sol";
11+
import { Bytes } from "src/libraries/Bytes.sol";
1112

1213
// Contracts
1314
import { Proxy } from "src/universal/Proxy.sol";
@@ -198,6 +199,15 @@ library DeployUtils {
198199
return address(uint160(uint256(keccak256(abi.encode(_sender, _identifier)))));
199200
}
200201

202+
/// @notice Strips the first 4 bytes of `_data` and returns the remaining bytes
203+
/// If `_data` is not greater than 4 bytes, it returns empty bytes type.
204+
/// @param _data constructor arguments prefixed with a psuedo-constructor function signature
205+
/// @return encodedData_ constructor arguments without the psuedo-constructor function signature prefix
206+
function encodeConstructor(bytes memory _data) internal pure returns (bytes memory encodedData_) {
207+
require(_data.length >= 4, "encodeConstructor takes in _data of length >= 4");
208+
encodedData_ = Bytes.slice(_data, 4);
209+
}
210+
201211
/// @notice Asserts that the given address is a valid contract address.
202212
/// @param _who Address to check.
203213
function assertValidContractAddress(address _who) internal view {

packages/contracts-bedrock/src/L1/interfaces/IL1CrossDomainMessenger.sol

+2
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ interface IL1CrossDomainMessenger is ICrossDomainMessenger {
1818
function superchainConfig() external view returns (address);
1919
function systemConfig() external view returns (address);
2020
function version() external view returns (string memory);
21+
22+
function __constructor__() external;
2123
}

packages/contracts-bedrock/src/L1/interfaces/IL1ERC721Bridge.sol

+2
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ interface IL1ERC721Bridge is IERC721Bridge {
3737
function paused() external view returns (bool);
3838
function superchainConfig() external view returns (ISuperchainConfig);
3939
function version() external view returns (string memory);
40+
41+
function __constructor__() external;
4042
}

packages/contracts-bedrock/src/L1/interfaces/IL1StandardBridge.sol

+2
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,6 @@ interface IL1StandardBridge is IStandardBridge {
7272
function superchainConfig() external view returns (ISuperchainConfig);
7373
function systemConfig() external view returns (ISystemConfig);
7474
function version() external view returns (string memory);
75+
76+
function __constructor__() external;
7577
}

packages/contracts-bedrock/src/L1/interfaces/IOptimismPortal.sol

+2
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,6 @@ interface IOptimismPortal {
8282
function superchainConfig() external view returns (ISuperchainConfig);
8383
function systemConfig() external view returns (ISystemConfig);
8484
function version() external pure returns (string memory);
85+
86+
function __constructor__() external;
8587
}

packages/contracts-bedrock/src/L1/interfaces/IResourceMetering.sol

+2
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ interface IResourceMetering {
2222
event Initialized(uint8 version);
2323

2424
function params() external view returns (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum); // nosemgrep
25+
26+
function __constructor__() external;
2527
}

packages/contracts-bedrock/src/L1/interfaces/ISystemConfigInterop.sol

+2
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,6 @@ interface ISystemConfigInterop {
7979
)
8080
external;
8181
function version() external pure returns (string memory);
82+
83+
function __constructor__() external;
8284
}

packages/contracts-bedrock/src/L2/interfaces/IBaseFeeVault.sol

+16-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,27 @@ pragma solidity ^0.8.0;
33

44
import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol";
55

6-
interface IBaseFeeVault is IFeeVault {
6+
interface IBaseFeeVault {
7+
event Withdrawal(uint256 value, address to, address from);
8+
event Withdrawal(uint256 value, address to, address from, IFeeVault.WithdrawalNetwork withdrawalNetwork);
9+
10+
receive() external payable;
11+
12+
function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256);
13+
function RECIPIENT() external view returns (address);
14+
function WITHDRAWAL_NETWORK() external view returns (IFeeVault.WithdrawalNetwork);
15+
function minWithdrawalAmount() external view returns (uint256 amount_);
16+
function recipient() external view returns (address recipient_);
17+
function totalProcessed() external view returns (uint256);
18+
function withdraw() external;
19+
function withdrawalNetwork() external view returns (IFeeVault.WithdrawalNetwork network_);
20+
721
function version() external view returns (string memory);
822

923
function __constructor__(
1024
address _recipient,
1125
uint256 _minWithdrawalAmount,
12-
WithdrawalNetwork _withdrawalNetwork
26+
IFeeVault.WithdrawalNetwork _withdrawalNetwork
1327
)
1428
external;
1529
}

packages/contracts-bedrock/src/L2/interfaces/IETHLiquidity.sol

+2
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ interface IETHLiquidity {
1111
function burn() external payable;
1212
function mint(uint256 _amount) external;
1313
function version() external view returns (string memory);
14+
15+
function __constructor__() external;
1416
}

packages/contracts-bedrock/src/L2/interfaces/IGasPriceOracle.sol

+2
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ interface IGasPriceOracle {
2020
function setEcotone() external;
2121
function setFjord() external;
2222
function version() external view returns (string memory);
23+
24+
function __constructor__() external;
2325
}

packages/contracts-bedrock/src/L2/interfaces/IL1Block.sol

+2
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ interface IL1Block {
3636
function setL1BlockValuesEcotone() external;
3737
function timestamp() external view returns (uint64);
3838
function version() external pure returns (string memory);
39+
40+
function __constructor__() external;
3941
}

packages/contracts-bedrock/src/L2/interfaces/IL1BlockIsthmus.sol

+2
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@ interface IL1BlockIsthmus {
5555
function setL1BlockValuesIsthmus() external;
5656
function timestamp() external view returns (uint64);
5757
function version() external pure returns (string memory);
58+
59+
function __constructor__() external;
5860
}

packages/contracts-bedrock/src/L2/interfaces/IL1FeeVault.sol

+16-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,27 @@ pragma solidity ^0.8.0;
33

44
import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol";
55

6-
interface IL1FeeVault is IFeeVault {
6+
interface IL1FeeVault {
7+
event Withdrawal(uint256 value, address to, address from);
8+
event Withdrawal(uint256 value, address to, address from, IFeeVault.WithdrawalNetwork withdrawalNetwork);
9+
10+
receive() external payable;
11+
12+
function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256);
13+
function RECIPIENT() external view returns (address);
14+
function WITHDRAWAL_NETWORK() external view returns (IFeeVault.WithdrawalNetwork);
15+
function minWithdrawalAmount() external view returns (uint256 amount_);
16+
function recipient() external view returns (address recipient_);
17+
function totalProcessed() external view returns (uint256);
18+
function withdraw() external;
19+
function withdrawalNetwork() external view returns (IFeeVault.WithdrawalNetwork network_);
20+
721
function version() external view returns (string memory);
822

923
function __constructor__(
1024
address _recipient,
1125
uint256 _minWithdrawalAmount,
12-
WithdrawalNetwork _withdrawalNetwork
26+
IFeeVault.WithdrawalNetwork _withdrawalNetwork
1327
)
1428
external;
1529
}

packages/contracts-bedrock/src/L2/interfaces/IL2StandardBridgeInterop.sol

+2
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,6 @@ interface IL2StandardBridgeInterop is IStandardBridge {
9595

9696
function convert(address _from, address _to, uint256 _amount) external;
9797
function version() external pure returns (string memory);
98+
99+
function __constructor__() external;
98100
}

packages/contracts-bedrock/src/L2/interfaces/IL2ToL1MessagePasser.sol

+2
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ interface IL2ToL1MessagePasser {
2121
function messageNonce() external view returns (uint256);
2222
function sentMessages(bytes32) external view returns (bool);
2323
function version() external view returns (string memory);
24+
25+
function __constructor__() external;
2426
}

packages/contracts-bedrock/src/L2/interfaces/ISequencerFeeVault.sol

+16-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,28 @@ pragma solidity ^0.8.0;
33

44
import { IFeeVault } from "src/universal/interfaces/IFeeVault.sol";
55

6-
interface ISequencerFeeVault is IFeeVault {
6+
interface ISequencerFeeVault {
7+
event Withdrawal(uint256 value, address to, address from);
8+
event Withdrawal(uint256 value, address to, address from, IFeeVault.WithdrawalNetwork withdrawalNetwork);
9+
10+
receive() external payable;
11+
12+
function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256);
13+
function RECIPIENT() external view returns (address);
14+
function WITHDRAWAL_NETWORK() external view returns (IFeeVault.WithdrawalNetwork);
15+
function minWithdrawalAmount() external view returns (uint256 amount_);
16+
function recipient() external view returns (address recipient_);
17+
function totalProcessed() external view returns (uint256);
18+
function withdraw() external;
19+
function withdrawalNetwork() external view returns (IFeeVault.WithdrawalNetwork network_);
20+
721
function version() external view returns (string memory);
822
function l1FeeWallet() external view returns (address);
923

1024
function __constructor__(
1125
address _recipient,
1226
uint256 _minWithdrawalAmount,
13-
WithdrawalNetwork _withdrawalNetwork
27+
IFeeVault.WithdrawalNetwork _withdrawalNetwork
1428
)
1529
external;
1630
}

packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol

+3-1
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ interface ISuperchainERC20Errors {
5353

5454
/// @title ISuperchainERC20
5555
/// @notice Combines Solady's ERC20 interface with the SuperchainERC20Extensions interface.
56-
interface ISuperchainERC20 is IERC20Solady, ISuperchainERC20Extensions, ISuperchainERC20Errors { }
56+
interface ISuperchainERC20 is IERC20Solady, ISuperchainERC20Extensions, ISuperchainERC20Errors {
57+
function __constructor__() external;
58+
}

packages/contracts-bedrock/src/L2/interfaces/ISuperchainWETH.sol

+2
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ interface ISuperchainWETH {
3030
function transferFrom(address src, address dst, uint256 wad) external returns (bool);
3131
function version() external view returns (string memory);
3232
function withdraw(uint256 wad) external;
33+
34+
function __constructor__() external;
3335
}

packages/contracts-bedrock/src/dispute/interfaces/IDelayedWETH.sol

+2
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ interface IDelayedWETH is IWETH {
2727
function withdraw(address _guy, uint256 _wad) external;
2828
function withdrawals(address _owner, address _guy) external view returns (uint256, uint256);
2929
function version() external view returns (string memory);
30+
31+
function __constructor__(uint256 _delay) external;
3032
}

packages/contracts-bedrock/src/legacy/interfaces/IAddressManager.sol

+2
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ interface IAddressManager is IOwnable {
1010

1111
function getAddress(string memory _name) external view returns (address);
1212
function setAddress(string memory _name, address _address) external;
13+
14+
function __constructor__() external;
1315
}

packages/contracts-bedrock/src/legacy/interfaces/IDeployerWhitelist.sol

+2
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ interface IDeployerWhitelist {
1717
function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external;
1818
function version() external view returns (string memory);
1919
function whitelist(address) external view returns (bool);
20+
21+
function __constructor__() external;
2022
}

packages/contracts-bedrock/src/legacy/interfaces/IL1BlockNumber.sol

+2
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ interface IL1BlockNumber is ISemver {
1111
receive() external payable;
1212

1313
function getL1BlockNumber() external view returns (uint256);
14+
15+
function __constructor__() external;
1416
}

packages/contracts-bedrock/src/legacy/interfaces/ILegacyMessagePasser.sol

+2
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol";
88
interface ILegacyMessagePasser is ISemver {
99
function passMessageToL1(bytes memory _message) external;
1010
function sentMessages(bytes32) external view returns (bool);
11+
12+
function __constructor__() external;
1113
}

packages/contracts-bedrock/src/universal/interfaces/ICrossDomainMessenger.sol

+2
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ interface ICrossDomainMessenger {
3535
function sendMessage(address _target, bytes memory _message, uint32 _minGasLimit) external payable;
3636
function successfulMessages(bytes32) external view returns (bool);
3737
function xDomainMessageSender() external view returns (address);
38+
39+
function __constructor__() external;
3840
}

packages/contracts-bedrock/src/universal/interfaces/IERC721Bridge.sol

+2
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,6 @@ interface IERC721Bridge {
4444
function messenger() external view returns (ICrossDomainMessenger);
4545
function otherBridge() external view returns (IERC721Bridge);
4646
function paused() external view returns (bool);
47+
48+
function __constructor__() external;
4749
}

packages/contracts-bedrock/src/universal/interfaces/IFeeVault.sol

+2
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ interface IFeeVault {
2020
function totalProcessed() external view returns (uint256);
2121
function withdraw() external;
2222
function withdrawalNetwork() external view returns (WithdrawalNetwork network_);
23+
24+
function __constructor__() external;
2325
}

packages/contracts-bedrock/src/universal/interfaces/IOwnable.sol

+2
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ interface IOwnable {
99
function owner() external view returns (address);
1010
function renounceOwnership() external;
1111
function transferOwnership(address newOwner) external; // nosemgrep
12+
13+
function __constructor__() external;
1214
}

packages/contracts-bedrock/src/universal/interfaces/IStandardBridge.sol

+2
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,6 @@ interface IStandardBridge {
6161
function messenger() external view returns (ICrossDomainMessenger);
6262
function otherBridge() external view returns (IStandardBridge);
6363
function paused() external view returns (bool);
64+
65+
function __constructor__() external;
6466
}

0 commit comments

Comments
 (0)