Commit 1a22e822 authored by smartcontracts's avatar smartcontracts Committed by GitHub

style(ctb): fix revert messages globally (#3005)

Updates revert messages across all contracts to use the standardized
format "<ContractName>: <lowercase message>".
parent 7a1c7a92
---
'@eth-optimism/contracts-bedrock': patch
---
Standardizes revert strings globally
This diff is collapsed.
This diff is collapsed.
...@@ -42,26 +42,26 @@ L1CrossDomainMessenger_Test:test_L1MessengerPause() (gas: 48061) ...@@ -42,26 +42,26 @@ L1CrossDomainMessenger_Test:test_L1MessengerPause() (gas: 48061)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 201827) L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 201827)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 195116) L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 195116)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77762) L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77762)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 67801) L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 67873)
L1CrossDomainMessenger_Test:test_L1MessengerRelayShouldRevertIfPaused() (gas: 60471) L1CrossDomainMessenger_Test:test_L1MessengerRelayShouldRevertIfPaused() (gas: 60471)
L1CrossDomainMessenger_Test:test_L1MessengerReplayMessageWithValue() (gas: 38127) L1CrossDomainMessenger_Test:test_L1MessengerReplayMessageWithValue() (gas: 38127)
L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 297745) L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 297745)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1490048) L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1490048)
L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40908) L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40908)
L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24249) L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24291)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86168) L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86269)
L1StandardBridge_Test:test_depositERC20() (gas: 578911) L1StandardBridge_Test:test_depositERC20() (gas: 578911)
L1StandardBridge_Test:test_depositERC20To() (gas: 581092) L1StandardBridge_Test:test_depositERC20To() (gas: 581092)
L1StandardBridge_Test:test_depositETH() (gas: 372953) L1StandardBridge_Test:test_depositETH() (gas: 372953)
L1StandardBridge_Test:test_depositETHTo() (gas: 330097) L1StandardBridge_Test:test_depositETHTo() (gas: 330097)
L1StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 681339) L1StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 681356)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490817) L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490817)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64453) L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64453)
L1StandardBridge_Test:test_initialize() (gas: 26401) L1StandardBridge_Test:test_initialize() (gas: 26401)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22341) L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22377)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40882) L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40918)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36294) L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36330)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35578) L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35614)
L1StandardBridge_Test:test_receive() (gas: 519538) L1StandardBridge_Test:test_receive() (gas: 519538)
L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10823) L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10823)
L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 171968) L2CrossDomainMessenger_Test:test_L1MessengerRelayMessageRevertsOnReentrancy() (gas: 171968)
...@@ -69,12 +69,12 @@ L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8455) ...@@ -69,12 +69,12 @@ L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8455)
L2CrossDomainMessenger_Test:test_L2MessengerPause() (gas: 31750) L2CrossDomainMessenger_Test:test_L2MessengerPause() (gas: 31750)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 173004) L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageFirstStuckSecondSucceeds() (gas: 173004)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57311) L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57311)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36115) L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36151)
L2CrossDomainMessenger_Test:test_L2MessengerRelayShouldRevertIfPaused() (gas: 41578) L2CrossDomainMessenger_Test:test_L2MessengerRelayShouldRevertIfPaused() (gas: 41578)
L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 120536) L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 120536)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133720) L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133720)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10554) L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10590)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54732) L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54798)
L2OutputOracleTest:testCannot_ProposeWithUnmatchedBlockhash() (gas: 26786) L2OutputOracleTest:testCannot_ProposeWithUnmatchedBlockhash() (gas: 26786)
L2OutputOracleTest:testCannot_deleteL2Output_ifNotOwner() (gas: 24844) L2OutputOracleTest:testCannot_deleteL2Output_ifNotOwner() (gas: 24844)
L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 91114) L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 91114)
...@@ -98,16 +98,16 @@ L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 19451) ...@@ -98,16 +98,16 @@ L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 19451)
L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 24450) L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 24450)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38899) L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38899)
L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843) L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133459) L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133477)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21656) L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21689)
L2StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 499042) L2StandardBridge_Test:test_finalizeBridgeERC20FailSendBack() (gas: 499057)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93203) L2StandardBridge_Test:test_finalizeDeposit() (gas: 93203)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140492) L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140492)
L2StandardBridge_Test:test_initialize() (gas: 14802) L2StandardBridge_Test:test_initialize() (gas: 14802)
L2StandardBridge_Test:test_receive() (gas: 136864) L2StandardBridge_Test:test_receive() (gas: 136864)
L2StandardBridge_Test:test_withdraw() (gas: 353022) L2StandardBridge_Test:test_withdraw() (gas: 353022)
L2StandardBridge_Test:test_withdrawTo() (gas: 353706) L2StandardBridge_Test:test_withdrawTo() (gas: 353706)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 252006) L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 252032)
L2ToL1MessagePasserTest:test_burn() (gas: 112037) L2ToL1MessagePasserTest:test_burn() (gas: 112037)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 67892) L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 67892)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA() (gas: 74831) L2ToL1MessagePasserTest:test_initiateWithdrawal_fromEOA() (gas: 74831)
...@@ -130,9 +130,9 @@ OptimismMintableERC20_Test:test_mint() (gas: 65754) ...@@ -130,9 +130,9 @@ OptimismMintableERC20_Test:test_mint() (gas: 65754)
OptimismMintableERC20_Test:test_mintRevertsFromNotBridge() (gas: 13243) OptimismMintableERC20_Test:test_mintRevertsFromNotBridge() (gas: 13243)
OptimismMintableERC20_Test:test_remoteToken() (gas: 9740) OptimismMintableERC20_Test:test_remoteToken() (gas: 9740)
OptimismMintableTokenFactory_Test:test_bridge() (gas: 7663) OptimismMintableTokenFactory_Test:test_bridge() (gas: 7663)
OptimismMintableTokenFactory_Test:test_createStandardL2Token() (gas: 1113150) OptimismMintableTokenFactory_Test:test_createStandardL2Token() (gas: 1113127)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenSameTwice() (gas: 2209211) OptimismMintableTokenFactory_Test:test_createStandardL2TokenSameTwice() (gas: 2209165)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenShouldRevertIfRemoteIsZero() (gas: 9399) OptimismMintableTokenFactory_Test:test_createStandardL2TokenShouldRevertIfRemoteIsZero() (gas: 9398)
OptimismPortalUpgradeable_Test:test_cannotInitImpl() (gas: 10686) OptimismPortalUpgradeable_Test:test_cannotInitImpl() (gas: 10686)
OptimismPortalUpgradeable_Test:test_cannotInitProxy() (gas: 15662) OptimismPortalUpgradeable_Test:test_cannotInitProxy() (gas: 15662)
OptimismPortalUpgradeable_Test:test_initValuesOnProxy() (gas: 15990) OptimismPortalUpgradeable_Test:test_initValuesOnProxy() (gas: 15990)
...@@ -189,37 +189,37 @@ ProxyAdmin_Test:test_setImplementationName() (gas: 39002) ...@@ -189,37 +189,37 @@ ProxyAdmin_Test:test_setImplementationName() (gas: 39002)
RLPReader_Test:testReadBool() (gas: 1109) RLPReader_Test:testReadBool() (gas: 1109)
RLPReader_Test:test_readAddress() (gas: 1347) RLPReader_Test:test_readAddress() (gas: 1347)
RLPReader_Test:test_readAddressSmall() (gas: 614) RLPReader_Test:test_readAddressSmall() (gas: 614)
RLPReader_Test:test_readAddressTooLarge() (gas: 3646) RLPReader_Test:test_readAddressTooLarge() (gas: 3679)
RLPReader_Test:test_readAddressTooShort() (gas: 3603) RLPReader_Test:test_readAddressTooShort() (gas: 3636)
RLPReader_Test:test_readBoolInvalidValue() (gas: 3677) RLPReader_Test:test_readBoolInvalidValue() (gas: 3677)
RLPReader_Test:test_readBoolLargeInput() (gas: 3550) RLPReader_Test:test_readBoolLargeInput() (gas: 3583)
RLPReader_Test:test_readBytes32_revertOnList() (gas: 3998) RLPReader_Test:test_readBytes32_revertOnList() (gas: 4031)
RLPReader_Test:test_readBytes32_revertOnTooLong() (gas: 3588) RLPReader_Test:test_readBytes32_revertOnTooLong() (gas: 3621)
RLPReader_Test:test_readBytes_bytestring00() (gas: 1823) RLPReader_Test:test_readBytes_bytestring00() (gas: 1823)
RLPReader_Test:test_readBytes_bytestring01() (gas: 1846) RLPReader_Test:test_readBytes_bytestring01() (gas: 1846)
RLPReader_Test:test_readBytes_bytestring7f() (gas: 1844) RLPReader_Test:test_readBytes_bytestring7f() (gas: 1844)
RLPReader_Test:test_readBytes_invalidListLength() (gas: 3812) RLPReader_Test:test_readBytes_invalidListLength() (gas: 3845)
RLPReader_Test:test_readBytes_invalidStringLength() (gas: 3768) RLPReader_Test:test_readBytes_invalidStringLength() (gas: 3801)
RLPReader_Test:test_readBytes_revertListItem() (gas: 3922) RLPReader_Test:test_readBytes_revertListItem() (gas: 3955)
RLPReader_Test:test_readList_dictTest1() (gas: 23791) RLPReader_Test:test_readList_dictTest1() (gas: 23791)
RLPReader_Test:test_readList_empty() (gas: 4472) RLPReader_Test:test_readList_empty() (gas: 4472)
RLPReader_Test:test_readList_incorrectLengthInArray() (gas: 4210) RLPReader_Test:test_readList_incorrectLengthInArray() (gas: 4243)
RLPReader_Test:test_readList_int32Overflow() (gas: 3955) RLPReader_Test:test_readList_int32Overflow() (gas: 3988)
RLPReader_Test:test_readList_int32Overflow2() (gas: 4021) RLPReader_Test:test_readList_int32Overflow2() (gas: 4015)
RLPReader_Test:test_readList_invalidShortList() (gas: 3855) RLPReader_Test:test_readList_invalidShortList() (gas: 3888)
RLPReader_Test:test_readList_invalidValue() (gas: 3787) RLPReader_Test:test_readList_invalidValue() (gas: 3820)
RLPReader_Test:test_readList_leadingZerosInLongLengthArray1() (gas: 4193) RLPReader_Test:test_readList_leadingZerosInLongLengthArray1() (gas: 4226)
RLPReader_Test:test_readList_leadingZerosInLongLengthArray2() (gas: 4177) RLPReader_Test:test_readList_leadingZerosInLongLengthArray2() (gas: 4210)
RLPReader_Test:test_readList_leadingZerosInLongLengthList1() (gas: 38560) RLPReader_Test:test_readList_leadingZerosInLongLengthList1() (gas: 38560)
RLPReader_Test:test_readList_listOfLists() (gas: 9619) RLPReader_Test:test_readList_listOfLists() (gas: 9619)
RLPReader_Test:test_readList_listOfLists2() (gas: 12479) RLPReader_Test:test_readList_listOfLists2() (gas: 12479)
RLPReader_Test:test_readList_longList1() (gas: 29013) RLPReader_Test:test_readList_longList1() (gas: 29013)
RLPReader_Test:test_readList_longList2() (gas: 202895) RLPReader_Test:test_readList_longList2() (gas: 202895)
RLPReader_Test:test_readList_longStringLength() (gas: 3853) RLPReader_Test:test_readList_longStringLength() (gas: 3886)
RLPReader_Test:test_readList_multiList() (gas: 12025) RLPReader_Test:test_readList_multiList() (gas: 12025)
RLPReader_Test:test_readList_nonOptimalLongLengthArray1() (gas: 4200) RLPReader_Test:test_readList_nonOptimalLongLengthArray1() (gas: 4233)
RLPReader_Test:test_readList_nonOptimalLongLengthArray2() (gas: 4223) RLPReader_Test:test_readList_nonOptimalLongLengthArray2() (gas: 4256)
RLPReader_Test:test_readList_notLongEnough() (gas: 3841) RLPReader_Test:test_readList_notLongEnough() (gas: 3874)
RLPReader_Test:test_readList_shortListMax1() (gas: 40662) RLPReader_Test:test_readList_shortListMax1() (gas: 40662)
RLPReader_Test:test_readList_stringList() (gas: 16796) RLPReader_Test:test_readList_stringList() (gas: 16796)
RLPReader_Test:test_readString_emptyString() (gas: 1719) RLPReader_Test:test_readString_emptyString() (gas: 1719)
...@@ -276,4 +276,4 @@ SequencerFeeVault_Test:test_constructor() (gas: 7656) ...@@ -276,4 +276,4 @@ SequencerFeeVault_Test:test_constructor() (gas: 7656)
SequencerFeeVault_Test:test_minWithdrawalAmount() (gas: 5407) SequencerFeeVault_Test:test_minWithdrawalAmount() (gas: 5407)
SequencerFeeVault_Test:test_receive() (gas: 17338) SequencerFeeVault_Test:test_receive() (gas: 17338)
SequencerFeeVault_Test:test_revertWithdraw() (gas: 9332) SequencerFeeVault_Test:test_revertWithdraw() (gas: 9332)
SequencerFeeVault_Test:test_withdraw() (gas: 147582) SequencerFeeVault_Test:test_withdraw() (gas: 147588)
...@@ -111,7 +111,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver { ...@@ -111,7 +111,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
* @notice Reverts if called by any account other than the proposer. * @notice Reverts if called by any account other than the proposer.
*/ */
modifier onlyProposer() { modifier onlyProposer() {
require(proposer == msg.sender, "OutputOracle: caller is not the proposer"); require(proposer == msg.sender, "L2OutputOracle: function can only be called by proposer");
_; _;
} }
...@@ -139,7 +139,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver { ...@@ -139,7 +139,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
) Semver(0, 0, 1) { ) Semver(0, 0, 1) {
require( require(
_l2BlockTime < block.timestamp, _l2BlockTime < block.timestamp,
"Output Oracle: Initial L2 block time must be less than current time" "L2OutputOracle: initial L2 block time must be less than current time"
); );
SUBMISSION_INTERVAL = _submissionInterval; SUBMISSION_INTERVAL = _submissionInterval;
...@@ -190,13 +190,18 @@ contract L2OutputOracle is OwnableUpgradeable, Semver { ...@@ -190,13 +190,18 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
) external payable onlyProposer { ) external payable onlyProposer {
require( require(
_l2BlockNumber == nextBlockNumber(), _l2BlockNumber == nextBlockNumber(),
"OutputOracle: Block number must be equal to next expected block number." "L2OutputOracle: block number must be equal to next expected block number"
); );
require( require(
computeL2Timestamp(_l2BlockNumber) < block.timestamp, computeL2Timestamp(_l2BlockNumber) < block.timestamp,
"OutputOracle: Cannot propose L2 output in future." "L2OutputOracle: cannot propose L2 output in the future"
);
require(
_outputRoot != bytes32(0),
"L2OutputOracle: L2 output proposal cannot be the zero hash"
); );
require(_outputRoot != bytes32(0), "OutputOracle: Cannot submit empty L2 output.");
if (_l1Blockhash != bytes32(0)) { if (_l1Blockhash != bytes32(0)) {
// This check allows the proposer to propose an output based on a given L1 block, // This check allows the proposer to propose an output based on a given L1 block,
...@@ -209,7 +214,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver { ...@@ -209,7 +214,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
// finalized. // finalized.
require( require(
blockhash(_l1BlockNumber) == _l1Blockhash, blockhash(_l1BlockNumber) == _l1Blockhash,
"OutputOracle: Blockhash does not match the hash at the expected height." "L2OutputOracle: blockhash does not match the hash at the expected height"
); );
} }
...@@ -233,11 +238,12 @@ contract L2OutputOracle is OwnableUpgradeable, Semver { ...@@ -233,11 +238,12 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
require( require(
_proposal.outputRoot == outputToDelete.outputRoot, _proposal.outputRoot == outputToDelete.outputRoot,
"OutputOracle: The output root to delete does not match the latest output proposal." "L2OutputOracle: output root to delete does not match the latest output proposal"
); );
require( require(
_proposal.timestamp == outputToDelete.timestamp, _proposal.timestamp == outputToDelete.timestamp,
"OutputOracle: The timestamp to delete does not match the latest output proposal." "L2OutputOracle: timestamp to delete does not match the latest output proposal"
); );
emit OutputDeleted(outputToDelete.outputRoot, outputToDelete.timestamp, latestBlockNumber); emit OutputDeleted(outputToDelete.outputRoot, outputToDelete.timestamp, latestBlockNumber);
...@@ -272,7 +278,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver { ...@@ -272,7 +278,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) { function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {
require( require(
_l2BlockNumber >= STARTING_BLOCK_NUMBER, _l2BlockNumber >= STARTING_BLOCK_NUMBER,
"OutputOracle: Block number must be greater than or equal to the starting block number." "L2OutputOracle: block number must be greater than or equal to starting block number"
); );
return STARTING_TIMESTAMP + ((_l2BlockNumber - STARTING_BLOCK_NUMBER) * L2_BLOCK_TIME); return STARTING_TIMESTAMP + ((_l2BlockNumber - STARTING_BLOCK_NUMBER) * L2_BLOCK_TIME);
...@@ -283,8 +289,16 @@ contract L2OutputOracle is OwnableUpgradeable, Semver { ...@@ -283,8 +289,16 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
* Can only be called by the current owner. * Can only be called by the current owner.
*/ */
function changeProposer(address _newProposer) public onlyOwner { function changeProposer(address _newProposer) public onlyOwner {
require(_newProposer != address(0), "OutputOracle: new proposer is the zero address"); require(
require(_newProposer != owner(), "OutputOracle: proposer cannot be same as the owner"); _newProposer != address(0),
"L2OutputOracle: new proposer cannot be the zero address"
);
require(
_newProposer != owner(),
"L2OutputOracle: proposer cannot be the same as the owner"
);
emit ProposerChanged(proposer, _newProposer); emit ProposerChanged(proposer, _newProposer);
proposer = _newProposer; proposer = _newProposer;
} }
......
...@@ -143,7 +143,7 @@ abstract contract ResourceMetering is Initializable { ...@@ -143,7 +143,7 @@ abstract contract ResourceMetering is Initializable {
params.prevBoughtGas += _amount; params.prevBoughtGas += _amount;
require( require(
int256(uint256(params.prevBoughtGas)) <= MAX_RESOURCE_LIMIT, int256(uint256(params.prevBoughtGas)) <= MAX_RESOURCE_LIMIT,
"OptimismPortal: cannot buy more gas than available gas limit" "ResourceMetering: cannot buy more gas than available gas limit"
); );
// Determine the amount of ETH to be paid. // Determine the amount of ETH to be paid.
......
...@@ -186,7 +186,11 @@ contract L2StandardBridge is StandardBridge, Semver { ...@@ -186,7 +186,11 @@ contract L2StandardBridge is StandardBridge, Semver {
) internal { ) internal {
address l1Token = OptimismMintableERC20(_l2Token).l1Token(); address l1Token = OptimismMintableERC20(_l2Token).l1Token();
if (_l2Token == PredeployAddresses.LEGACY_ERC20_ETH) { if (_l2Token == PredeployAddresses.LEGACY_ERC20_ETH) {
require(msg.value == _amount, "ETH withdrawals must include sufficient ETH value."); require(
msg.value == _amount,
"L2StandardBridge: ETH withdrawals must include sufficient ETH value"
);
_initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData); _initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);
} else { } else {
_initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData); _initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);
......
...@@ -39,14 +39,11 @@ contract SequencerFeeVault is Semver { ...@@ -39,14 +39,11 @@ contract SequencerFeeVault is Semver {
function withdraw() external { function withdraw() external {
require( require(
address(this).balance >= MIN_WITHDRAWAL_AMOUNT, address(this).balance >= MIN_WITHDRAWAL_AMOUNT,
// solhint-disable-next-line max-line-length "SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount"
"OVM_SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount"
); );
uint256 balance = address(this).balance;
L2StandardBridge(payable(PredeployAddresses.L2_STANDARD_BRIDGE)).withdrawTo{ L2StandardBridge(payable(PredeployAddresses.L2_STANDARD_BRIDGE)).withdrawTo{
value: balance value: address(this).balance
}(PredeployAddresses.LEGACY_ERC20_ETH, l1FeeWallet, balance, 0, bytes("")); }(PredeployAddresses.LEGACY_ERC20_ETH, l1FeeWallet, address(this).balance, 0, bytes(""));
} }
} }
...@@ -146,7 +146,7 @@ contract L1ChugSplashProxy { ...@@ -146,7 +146,7 @@ contract L1ChugSplashProxy {
// should be doing this check anyway though. // should be doing this check anyway though.
require( require(
_getAccountCodeHash(newImplementation) == keccak256(_code), _getAccountCodeHash(newImplementation) == keccak256(_code),
"L1ChugSplashProxy: code was not correctly deployed." "L1ChugSplashProxy: code was not correctly deployed"
); );
_setImplementation(newImplementation); _setImplementation(newImplementation);
......
...@@ -59,7 +59,7 @@ library RLPReader { ...@@ -59,7 +59,7 @@ library RLPReader {
function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) { function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {
(uint256 listOffset, , RLPItemType itemType) = _decodeLength(_in); (uint256 listOffset, , RLPItemType itemType) = _decodeLength(_in);
require(itemType == RLPItemType.LIST_ITEM, "Invalid RLP list value."); require(itemType == RLPItemType.LIST_ITEM, "RLPReader: invalid RLP list value");
// Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by
// writing to the length. Since we can't know the number of RLP items without looping over // writing to the length. Since we can't know the number of RLP items without looping over
...@@ -70,7 +70,10 @@ library RLPReader { ...@@ -70,7 +70,10 @@ library RLPReader {
uint256 itemCount = 0; uint256 itemCount = 0;
uint256 offset = listOffset; uint256 offset = listOffset;
while (offset < _in.length) { while (offset < _in.length) {
require(itemCount < MAX_LIST_LENGTH, "Provided RLP list exceeds max list length."); require(
itemCount < MAX_LIST_LENGTH,
"RLPReader: provided RLP list exceeds max list length"
);
(uint256 itemOffset, uint256 itemLength, ) = _decodeLength( (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(
RLPItem({ length: _in.length - offset, ptr: _in.ptr + offset }) RLPItem({ length: _in.length - offset, ptr: _in.ptr + offset })
...@@ -111,7 +114,7 @@ library RLPReader { ...@@ -111,7 +114,7 @@ library RLPReader {
function readBytes(RLPItem memory _in) internal pure returns (bytes memory) { function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {
(uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);
require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes value."); require(itemType == RLPItemType.DATA_ITEM, "RLPReader: invalid RLP bytes value");
return _copy(_in.ptr, itemOffset, itemLength); return _copy(_in.ptr, itemOffset, itemLength);
} }
...@@ -157,11 +160,11 @@ library RLPReader { ...@@ -157,11 +160,11 @@ library RLPReader {
* @return Decoded bytes32. * @return Decoded bytes32.
*/ */
function readBytes32(RLPItem memory _in) internal pure returns (bytes32) { function readBytes32(RLPItem memory _in) internal pure returns (bytes32) {
require(_in.length <= 33, "Invalid RLP bytes32 value."); require(_in.length <= 33, "RLPReader: invalid RLP bytes32 value");
(uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);
require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes32 value."); require(itemType == RLPItemType.DATA_ITEM, "RLPReader: invalid RLP bytes32 value");
uint256 ptr = _in.ptr + itemOffset; uint256 ptr = _in.ptr + itemOffset;
bytes32 out; bytes32 out;
...@@ -218,7 +221,7 @@ library RLPReader { ...@@ -218,7 +221,7 @@ library RLPReader {
* @return Decoded bool. * @return Decoded bool.
*/ */
function readBool(RLPItem memory _in) internal pure returns (bool) { function readBool(RLPItem memory _in) internal pure returns (bool) {
require(_in.length == 1, "Invalid RLP boolean value."); require(_in.length == 1, "RLPReader: invalid RLP boolean value");
uint256 ptr = _in.ptr; uint256 ptr = _in.ptr;
uint256 out; uint256 out;
...@@ -226,7 +229,7 @@ library RLPReader { ...@@ -226,7 +229,7 @@ library RLPReader {
out := byte(0, mload(ptr)) out := byte(0, mload(ptr))
} }
require(out == 0 || out == 1, "RLPReader: Invalid RLP boolean value, must be 0 or 1"); require(out == 0 || out == 1, "RLPReader: invalid RLP boolean value, must be 0 or 1");
return out != 0; return out != 0;
} }
...@@ -254,7 +257,7 @@ library RLPReader { ...@@ -254,7 +257,7 @@ library RLPReader {
return address(0); return address(0);
} }
require(_in.length == 21, "Invalid RLP address value."); require(_in.length == 21, "RLPReader: invalid RLP address value");
return address(uint160(readUint256(_in))); return address(uint160(readUint256(_in)));
} }
...@@ -303,7 +306,7 @@ library RLPReader { ...@@ -303,7 +306,7 @@ library RLPReader {
RLPItemType RLPItemType
) )
{ {
require(_in.length > 0, "RLP item cannot be null."); require(_in.length > 0, "RLPReader: RLP item cannot be null");
uint256 ptr = _in.ptr; uint256 ptr = _in.ptr;
uint256 prefix; uint256 prefix;
...@@ -321,14 +324,14 @@ library RLPReader { ...@@ -321,14 +324,14 @@ library RLPReader {
// slither-disable-next-line variable-scope // slither-disable-next-line variable-scope
uint256 strLen = prefix - 0x80; uint256 strLen = prefix - 0x80;
require(_in.length > strLen, "Invalid RLP short string."); require(_in.length > strLen, "RLPReader: invalid RLP short string");
return (1, strLen, RLPItemType.DATA_ITEM); return (1, strLen, RLPItemType.DATA_ITEM);
} else if (prefix <= 0xbf) { } else if (prefix <= 0xbf) {
// Long string. // Long string.
uint256 lenOfStrLen = prefix - 0xb7; uint256 lenOfStrLen = prefix - 0xb7;
require(_in.length > lenOfStrLen, "Invalid RLP long string length."); require(_in.length > lenOfStrLen, "RLPReader: invalid RLP long string length");
uint256 strLen; uint256 strLen;
assembly { assembly {
...@@ -336,7 +339,7 @@ library RLPReader { ...@@ -336,7 +339,7 @@ library RLPReader {
strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen))) strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen)))
} }
require(_in.length > lenOfStrLen + strLen, "Invalid RLP long string."); require(_in.length > lenOfStrLen + strLen, "RLPReader: invalid RLP long string");
return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM); return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);
} else if (prefix <= 0xf7) { } else if (prefix <= 0xf7) {
...@@ -344,14 +347,14 @@ library RLPReader { ...@@ -344,14 +347,14 @@ library RLPReader {
// slither-disable-next-line variable-scope // slither-disable-next-line variable-scope
uint256 listLen = prefix - 0xc0; uint256 listLen = prefix - 0xc0;
require(_in.length > listLen, "Invalid RLP short list."); require(_in.length > listLen, "RLPReader: invalid RLP short list");
return (1, listLen, RLPItemType.LIST_ITEM); return (1, listLen, RLPItemType.LIST_ITEM);
} else { } else {
// Long list. // Long list.
uint256 lenOfListLen = prefix - 0xf7; uint256 lenOfListLen = prefix - 0xf7;
require(_in.length > lenOfListLen, "Invalid RLP long list length."); require(_in.length > lenOfListLen, "RLPReader: invalid RLP long list length");
uint256 listLen; uint256 listLen;
assembly { assembly {
...@@ -359,7 +362,7 @@ library RLPReader { ...@@ -359,7 +362,7 @@ library RLPReader {
listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen))) listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen)))
} }
require(_in.length > lenOfListLen + listLen, "Invalid RLP long list."); require(_in.length > lenOfListLen + listLen, "RLPReader: invalid RLP long list");
return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM); return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);
} }
......
...@@ -107,7 +107,7 @@ library MerkleTrie { ...@@ -107,7 +107,7 @@ library MerkleTrie {
bool exists = keyRemainder.length == 0; bool exists = keyRemainder.length == 0;
require(exists || isFinalNode, "Provided proof is invalid."); require(exists || isFinalNode, "MerkleTrie: provided proof is invalid");
bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes(""); bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes("");
...@@ -158,18 +158,21 @@ library MerkleTrie { ...@@ -158,18 +158,21 @@ library MerkleTrie {
if (currentKeyIndex == 0) { if (currentKeyIndex == 0) {
// First proof element is always the root node. // First proof element is always the root node.
require(keccak256(currentNode.encoded) == currentNodeID, "Invalid root hash"); require(
keccak256(currentNode.encoded) == currentNodeID,
"MerkleTrie: invalid root hash"
);
} else if (currentNode.encoded.length >= 32) { } else if (currentNode.encoded.length >= 32) {
// Nodes 32 bytes or larger are hashed inside branch nodes. // Nodes 32 bytes or larger are hashed inside branch nodes.
require( require(
keccak256(currentNode.encoded) == currentNodeID, keccak256(currentNode.encoded) == currentNodeID,
"Invalid large internal hash" "MerkleTrie: invalid large internal hash"
); );
} else { } else {
// Nodes smaller than 31 bytes aren't hashed. // Nodes smaller than 31 bytes aren't hashed.
require( require(
bytes32(currentNode.encoded) == currentNodeID, bytes32(currentNode.encoded) == currentNodeID,
"Invalid internal node hash" "MerkleTrie: invalid internal node hash"
); );
} }
...@@ -223,10 +226,10 @@ library MerkleTrie { ...@@ -223,10 +226,10 @@ library MerkleTrie {
continue; continue;
} }
} else { } else {
revert("Received a node with an unknown prefix"); revert("MerkleTrie: received a node with an unknown prefix");
} }
} else { } else {
revert("Received an unparseable node."); revert("MerkleTrie: received an unparseable node");
} }
} }
......
...@@ -121,7 +121,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -121,7 +121,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
} }
function test_L1MessengerXDomainSenderReverts() external { function test_L1MessengerXDomainSenderReverts() external {
vm.expectRevert("xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); L1Messenger.xDomainMessageSender();
} }
...@@ -170,11 +170,11 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -170,11 +170,11 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
bytes memory message = hex"1111"; bytes memory message = hex"1111";
vm.prank(address(op)); vm.prank(address(op));
vm.expectRevert("Message cannot be replayed."); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage(0, sender, target, 0, 0, message); L1Messenger.relayMessage(0, sender, target, 0, 0, message);
vm.store(address(op), 0, bytes32(abi.encode(sender))); vm.store(address(op), 0, bytes32(abi.encode(sender)));
vm.expectRevert("Message cannot be replayed."); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage(0, sender, target, 0, 0, message); L1Messenger.relayMessage(0, sender, target, 0, 0, message);
} }
...@@ -185,14 +185,14 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -185,14 +185,14 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
bytes memory message = hex"1111"; bytes memory message = hex"1111";
vm.expectRevert( vm.expectRevert(
"CrossDomainMessenger: Value must be zero unless message is from a system address." "CrossDomainMessenger: value must be zero unless message is from a system address"
); );
L1Messenger.relayMessage{ value: 100 }(0, sender, target, 0, 0, message); L1Messenger.relayMessage{ value: 100 }(0, sender, target, 0, 0, message);
} }
// relayMessage: the xDomainMessageSender is reset to the original value // relayMessage: the xDomainMessageSender is reset to the original value
function test_L1MessengerxDomainMessageSenderResets() external { function test_L1MessengerxDomainMessageSenderResets() external {
vm.expectRevert("xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); L1Messenger.xDomainMessageSender();
address sender = PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER; address sender = PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER;
...@@ -203,7 +203,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -203,7 +203,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.prank(address(op)); vm.prank(address(op));
L1Messenger.relayMessage(0, address(0), address(0), 0, 0, hex""); L1Messenger.relayMessage(0, address(0), address(0), 0, 0, hex"");
vm.expectRevert("xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); L1Messenger.xDomainMessageSender();
} }
......
...@@ -100,7 +100,7 @@ contract L1StandardBridge_Test is Bridge_Initializer { ...@@ -100,7 +100,7 @@ contract L1StandardBridge_Test is Bridge_Initializer {
// turn alice into a contract // turn alice into a contract
vm.etch(alice, address(L1Token).code); vm.etch(alice, address(L1Token).code);
vm.expectRevert("Account not EOA"); vm.expectRevert("StandardBridge: function can only be called from an EOA");
vm.prank(alice); vm.prank(alice);
L1Bridge.depositETH{ value: 1 }(300, hex""); L1Bridge.depositETH{ value: 1 }(300, hex"");
} }
...@@ -207,7 +207,7 @@ contract L1StandardBridge_Test is Bridge_Initializer { ...@@ -207,7 +207,7 @@ contract L1StandardBridge_Test is Bridge_Initializer {
// turn alice into a contract // turn alice into a contract
vm.etch(alice, hex"ffff"); vm.etch(alice, hex"ffff");
vm.expectRevert("Account not EOA"); vm.expectRevert("StandardBridge: function can only be called from an EOA");
vm.prank(alice, alice); vm.prank(alice, alice);
L1Bridge.depositERC20( L1Bridge.depositERC20(
address(0), address(0),
...@@ -363,7 +363,7 @@ contract L1StandardBridge_Test is Bridge_Initializer { ...@@ -363,7 +363,7 @@ contract L1StandardBridge_Test is Bridge_Initializer {
abi.encode(address(L1Bridge.otherBridge())) abi.encode(address(L1Bridge.otherBridge()))
); );
vm.prank(address(28)); vm.prank(address(28));
vm.expectRevert("Could not authenticate bridge message."); vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal( L1Bridge.finalizeERC20Withdrawal(
address(L1Token), address(L1Token),
address(L2Token), address(L2Token),
...@@ -381,7 +381,7 @@ contract L1StandardBridge_Test is Bridge_Initializer { ...@@ -381,7 +381,7 @@ contract L1StandardBridge_Test is Bridge_Initializer {
abi.encode(address(address(0))) abi.encode(address(address(0)))
); );
vm.prank(address(L1Bridge.messenger())); vm.prank(address(L1Bridge.messenger()));
vm.expectRevert("Could not authenticate bridge message."); vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal( L1Bridge.finalizeERC20Withdrawal(
address(L1Token), address(L1Token),
address(L2Token), address(L2Token),
......
...@@ -90,7 +90,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -90,7 +90,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
} }
function test_L2MessengerXDomainSenderReverts() external { function test_L2MessengerXDomainSenderReverts() external {
vm.expectRevert("xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender(); L2Messenger.xDomainMessageSender();
} }
...@@ -139,20 +139,20 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -139,20 +139,20 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
bytes memory message = hex"1111"; bytes memory message = hex"1111";
vm.prank(caller); vm.prank(caller);
vm.expectRevert("Message cannot be replayed."); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage(0, sender, target, 0, 0, message); L1Messenger.relayMessage(0, sender, target, 0, 0, message);
} }
// relayMessage: the xDomainMessageSender is reset to the original value // relayMessage: the xDomainMessageSender is reset to the original value
function test_L2MessengerxDomainMessageSenderResets() external { function test_L2MessengerxDomainMessageSenderResets() external {
vm.expectRevert("xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender(); L2Messenger.xDomainMessageSender();
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger));
vm.prank(caller); vm.prank(caller);
L2Messenger.relayMessage(0, address(0), address(0), 0, 0, hex""); L2Messenger.relayMessage(0, address(0), address(0), 0, 0, hex"");
vm.expectRevert("xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender(); L2Messenger.xDomainMessageSender();
} }
......
...@@ -71,7 +71,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -71,7 +71,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
function test_computeL2Timestamp() external { function test_computeL2Timestamp() external {
// reverts if timestamp is too low // reverts if timestamp is too low
vm.expectRevert( vm.expectRevert(
"OutputOracle: Block number must be greater than or equal to the starting block number." "L2OutputOracle: block number must be greater than or equal to starting block number"
); );
oracle.computeL2Timestamp(startingBlockNumber - 1); oracle.computeL2Timestamp(startingBlockNumber - 1);
...@@ -104,10 +104,10 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -104,10 +104,10 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
oracle.changeProposer(newProposer); oracle.changeProposer(newProposer);
vm.startPrank(owner); vm.startPrank(owner);
vm.expectRevert("OutputOracle: new proposer is the zero address"); vm.expectRevert("L2OutputOracle: new proposer cannot be the zero address");
oracle.changeProposer(address(0)); oracle.changeProposer(address(0));
vm.expectRevert("OutputOracle: proposer cannot be same as the owner"); vm.expectRevert("L2OutputOracle: proposer cannot be the same as the owner");
oracle.changeProposer(owner); oracle.changeProposer(owner);
// Double check proposer has not changed. // Double check proposer has not changed.
...@@ -178,7 +178,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -178,7 +178,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(address(128)); vm.prank(address(128));
vm.expectRevert("OutputOracle: caller is not the proposer"); vm.expectRevert("L2OutputOracle: function can only be called by proposer");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);
} }
...@@ -188,7 +188,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -188,7 +188,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = oracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(proposer);
vm.expectRevert("OutputOracle: Cannot submit empty L2 output."); vm.expectRevert("L2OutputOracle: L2 output proposal cannot be the zero hash");
oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0); oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);
} }
...@@ -197,7 +197,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -197,7 +197,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = oracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(proposer);
vm.expectRevert("OutputOracle: Block number must be equal to next expected block number."); vm.expectRevert("L2OutputOracle: block number must be equal to next expected block number");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0); oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);
} }
...@@ -207,7 +207,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -207,7 +207,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber); uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber);
vm.warp(nextTimestamp); vm.warp(nextTimestamp);
vm.prank(proposer); vm.prank(proposer);
vm.expectRevert("OutputOracle: Cannot propose L2 output in future."); vm.expectRevert("L2OutputOracle: cannot propose L2 output in the future");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);
} }
...@@ -217,7 +217,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -217,7 +217,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = oracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(proposer);
vm.expectRevert("OutputOracle: Blockhash does not match the hash at the expected height."); vm.expectRevert("L2OutputOracle: blockhash does not match the hash at the expected height");
oracle.proposeL2Output( oracle.proposeL2Output(
nonZeroHash, nonZeroHash,
nextBlockNumber, nextBlockNumber,
...@@ -241,7 +241,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -241,7 +241,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
vm.prank(proposer); vm.prank(proposer);
// This will fail when foundry no longer returns zerod block hashes // This will fail when foundry no longer returns zerod block hashes
vm.expectRevert("OutputOracle: Blockhash does not match the hash at the expected height."); vm.expectRevert("L2OutputOracle: blockhash does not match the hash at the expected height");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1); oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);
} }
...@@ -307,7 +307,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -307,7 +307,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
vm.prank(owner); vm.prank(owner);
vm.expectRevert( vm.expectRevert(
"OutputOracle: The output root to delete does not match the latest output proposal." "L2OutputOracle: output root to delete does not match the latest output proposal"
); );
oracle.deleteL2Output(proposalToDelete); oracle.deleteL2Output(proposalToDelete);
} }
...@@ -324,7 +324,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer { ...@@ -324,7 +324,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
proposalToDelete.timestamp -= 1; proposalToDelete.timestamp -= 1;
vm.prank(owner); vm.prank(owner);
vm.expectRevert( vm.expectRevert(
"OutputOracle: The timestamp to delete does not match the latest output proposal." "L2OutputOracle: timestamp to delete does not match the latest output proposal"
); );
oracle.deleteL2Output(proposalToDelete); oracle.deleteL2Output(proposalToDelete);
} }
......
...@@ -50,7 +50,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -50,7 +50,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
function test_cannotWithdrawEthWithoutSendingIt() external { function test_cannotWithdrawEthWithoutSendingIt() external {
assertEq(address(messagePasser).balance, 0); assertEq(address(messagePasser).balance, 0);
vm.expectRevert("ETH withdrawals must include sufficient ETH value."); vm.expectRevert("L2StandardBridge: ETH withdrawals must include sufficient ETH value");
vm.prank(alice, alice); vm.prank(alice, alice);
L2Bridge.withdraw( L2Bridge.withdraw(
address(PredeployAddresses.LEGACY_ERC20_ETH), address(PredeployAddresses.LEGACY_ERC20_ETH),
...@@ -86,7 +86,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -86,7 +86,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
// This contract has 100 L2Token // This contract has 100 L2Token
deal(address(L2Token), address(this), 100, true); deal(address(L2Token), address(this), 100, true);
vm.expectRevert("Account not EOA"); vm.expectRevert("StandardBridge: function can only be called from an EOA");
L2Bridge.withdraw( L2Bridge.withdraw(
address(L2Token), address(L2Token),
100, 100,
......
...@@ -18,12 +18,12 @@ contract RLPReader_Test is CommonTest { ...@@ -18,12 +18,12 @@ contract RLPReader_Test is CommonTest {
} }
function test_readBoolInvalidValue() external { function test_readBoolInvalidValue() external {
vm.expectRevert("RLPReader: Invalid RLP boolean value, must be 0 or 1"); vm.expectRevert("RLPReader: invalid RLP boolean value, must be 0 or 1");
RLPReader.readBool(hex"02"); RLPReader.readBool(hex"02");
} }
function test_readBoolLargeInput() external { function test_readBoolLargeInput() external {
vm.expectRevert("Invalid RLP boolean value."); vm.expectRevert("RLPReader: invalid RLP boolean value");
RLPReader.readBool(hex"0101"); RLPReader.readBool(hex"0101");
} }
...@@ -42,12 +42,12 @@ contract RLPReader_Test is CommonTest { ...@@ -42,12 +42,12 @@ contract RLPReader_Test is CommonTest {
} }
function test_readAddressTooLarge() external { function test_readAddressTooLarge() external {
vm.expectRevert("Invalid RLP address value."); vm.expectRevert("RLPReader: invalid RLP address value");
RLPReader.readAddress(hex"94121212121212121212121212121212121212121212121212"); RLPReader.readAddress(hex"94121212121212121212121212121212121212121212121212");
} }
function test_readAddressTooShort() external { function test_readAddressTooShort() external {
vm.expectRevert("Invalid RLP address value."); vm.expectRevert("RLPReader: invalid RLP address value");
RLPReader.readAddress(hex"94121212121212121212121212"); RLPReader.readAddress(hex"94121212121212121212121212");
} }
...@@ -73,27 +73,27 @@ contract RLPReader_Test is CommonTest { ...@@ -73,27 +73,27 @@ contract RLPReader_Test is CommonTest {
} }
function test_readBytes_revertListItem() external { function test_readBytes_revertListItem() external {
vm.expectRevert("Invalid RLP bytes value."); vm.expectRevert("RLPReader: invalid RLP bytes value");
RLPReader.readBytes(hex"c7c0c1c0c3c0c1c0"); RLPReader.readBytes(hex"c7c0c1c0c3c0c1c0");
} }
function test_readBytes_invalidStringLength() external { function test_readBytes_invalidStringLength() external {
vm.expectRevert("Invalid RLP long string length."); vm.expectRevert("RLPReader: invalid RLP long string length");
RLPReader.readBytes(hex"b9"); RLPReader.readBytes(hex"b9");
} }
function test_readBytes_invalidListLength() external { function test_readBytes_invalidListLength() external {
vm.expectRevert("Invalid RLP long list length."); vm.expectRevert("RLPReader: invalid RLP long list length");
RLPReader.readBytes(hex"ff"); RLPReader.readBytes(hex"ff");
} }
function test_readBytes32_revertOnList() external { function test_readBytes32_revertOnList() external {
vm.expectRevert("Invalid RLP bytes32 value."); vm.expectRevert("RLPReader: invalid RLP bytes32 value");
RLPReader.readBytes32(hex"c7c0c1c0c3c0c1c0"); RLPReader.readBytes32(hex"c7c0c1c0c3c0c1c0");
} }
function test_readBytes32_revertOnTooLong() external { function test_readBytes32_revertOnTooLong() external {
vm.expectRevert("Invalid RLP bytes32 value."); vm.expectRevert("RLPReader: invalid RLP bytes32 value");
RLPReader.readBytes32(hex"11110000000000000000000000000000000000000000000000000000000000000000"); RLPReader.readBytes32(hex"11110000000000000000000000000000000000000000000000000000000000000000");
} }
...@@ -273,62 +273,62 @@ contract RLPReader_Test is CommonTest { ...@@ -273,62 +273,62 @@ contract RLPReader_Test is CommonTest {
} }
function test_readList_invalidShortList() external { function test_readList_invalidShortList() external {
vm.expectRevert("Invalid RLP short list."); vm.expectRevert("RLPReader: invalid RLP short list");
RLPReader.readList(hex"efdebd"); RLPReader.readList(hex"efdebd");
} }
function test_readList_longStringLength() external { function test_readList_longStringLength() external {
vm.expectRevert("Invalid RLP short list."); vm.expectRevert("RLPReader: invalid RLP short list");
RLPReader.readList(hex"efb83600"); RLPReader.readList(hex"efb83600");
} }
function test_readList_notLongEnough() external { function test_readList_notLongEnough() external {
vm.expectRevert("Invalid RLP short list."); vm.expectRevert("RLPReader: invalid RLP short list");
RLPReader.readList(hex"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); RLPReader.readList(hex"efdebdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
} }
function test_readList_int32Overflow() external { function test_readList_int32Overflow() external {
vm.expectRevert("Invalid RLP long string."); vm.expectRevert("RLPReader: invalid RLP long string");
RLPReader.readList(hex"bf0f000000000000021111"); RLPReader.readList(hex"bf0f000000000000021111");
} }
function test_readList_int32Overflow2() external { function test_readList_int32Overflow2() external {
vm.expectRevert("Invalid RLP long list."); vm.expectRevert("RLPReader: invalid RLP long list");
RLPReader.readList(hex"ff0f000000000000021111"); RLPReader.readList(hex"ff0f000000000000021111");
} }
function test_readList_incorrectLengthInArray() external { function test_readList_incorrectLengthInArray() external {
vm.expectRevert("Invalid RLP list value."); vm.expectRevert("RLPReader: invalid RLP list value");
RLPReader.readList(hex"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0"); RLPReader.readList(hex"b9002100dc2b275d0f74e8a53e6f4ec61b27f24278820be3f82ea2110e582081b0565df0");
} }
function test_readList_leadingZerosInLongLengthArray1() external { function test_readList_leadingZerosInLongLengthArray1() external {
vm.expectRevert("Invalid RLP list value."); vm.expectRevert("RLPReader: invalid RLP list value");
RLPReader.readList(hex"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"); RLPReader.readList(hex"b90040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f");
} }
function test_readList_leadingZerosInLongLengthArray2() external { function test_readList_leadingZerosInLongLengthArray2() external {
vm.expectRevert("Invalid RLP list value."); vm.expectRevert("RLPReader: invalid RLP list value");
RLPReader.readList(hex"b800"); RLPReader.readList(hex"b800");
} }
function test_readList_leadingZerosInLongLengthList1() external { function test_readList_leadingZerosInLongLengthList1() external {
vm.expectRevert("Provided RLP list exceeds max list length."); vm.expectRevert("RLPReader: provided RLP list exceeds max list length");
RLPReader.readList(hex"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"); RLPReader.readList(hex"fb00000040000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f");
} }
function test_readList_nonOptimalLongLengthArray1() external { function test_readList_nonOptimalLongLengthArray1() external {
vm.expectRevert("Invalid RLP list value."); vm.expectRevert("RLPReader: invalid RLP list value");
RLPReader.readList(hex"b81000112233445566778899aabbccddeeff"); RLPReader.readList(hex"b81000112233445566778899aabbccddeeff");
} }
function test_readList_nonOptimalLongLengthArray2() external { function test_readList_nonOptimalLongLengthArray2() external {
vm.expectRevert("Invalid RLP list value."); vm.expectRevert("RLPReader: invalid RLP list value");
RLPReader.readList(hex"b801ff"); RLPReader.readList(hex"b801ff");
} }
function test_readList_invalidValue() external { function test_readList_invalidValue() external {
vm.expectRevert("Invalid RLP short string."); vm.expectRevert("RLPReader: invalid RLP short string");
RLPReader.readList(hex"91"); RLPReader.readList(hex"91");
} }
} }
...@@ -105,7 +105,7 @@ contract ResourceMetering_Test is CommonTest { ...@@ -105,7 +105,7 @@ contract ResourceMetering_Test is CommonTest {
function test_useMoreThanMaxReverts() external { function test_useMoreThanMaxReverts() external {
uint64 target = uint64(uint256(meter.TARGET_RESOURCE_LIMIT())); uint64 target = uint64(uint256(meter.TARGET_RESOURCE_LIMIT()));
uint64 elasticity = uint64(uint256(meter.ELASTICITY_MULTIPLIER())); uint64 elasticity = uint64(uint256(meter.ELASTICITY_MULTIPLIER()));
vm.expectRevert("OptimismPortal: cannot buy more gas than available gas limit"); vm.expectRevert("ResourceMetering: cannot buy more gas than available gas limit");
meter.use(target * elasticity + 1); meter.use(target * elasticity + 1);
} }
} }
...@@ -61,7 +61,7 @@ contract SequencerFeeVault_Test is Bridge_Initializer { ...@@ -61,7 +61,7 @@ contract SequencerFeeVault_Test is Bridge_Initializer {
assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT()); assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT());
vm.expectRevert( vm.expectRevert(
"OVM_SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount" "SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount"
); );
vault.withdraw(); vault.withdraw();
} }
......
...@@ -169,7 +169,10 @@ abstract contract CrossDomainMessenger is ...@@ -169,7 +169,10 @@ abstract contract CrossDomainMessenger is
* @return Address of the sender of the currently executing message on the other chain. * @return Address of the sender of the currently executing message on the other chain.
*/ */
function xDomainMessageSender() external view returns (address) { function xDomainMessageSender() external view returns (address) {
require(xDomainMsgSender != DEFAULT_XDOMAIN_SENDER, "xDomainMessageSender is not set"); require(
xDomainMsgSender != DEFAULT_XDOMAIN_SENDER,
"CrossDomainMessenger: xDomainMessageSender is not set"
);
return xDomainMsgSender; return xDomainMsgSender;
} }
...@@ -276,25 +279,32 @@ abstract contract CrossDomainMessenger is ...@@ -276,25 +279,32 @@ abstract contract CrossDomainMessenger is
if (_isOtherMessenger()) { if (_isOtherMessenger()) {
// Should never happen. // Should never happen.
require(msg.value == _value, "Mismatched message value."); require(msg.value == _value, "CrossDomainMessenger: mismatched message value");
} else { } else {
require( require(
msg.value == 0, msg.value == 0,
"CrossDomainMessenger: Value must be zero unless message is from a system address." "CrossDomainMessenger: value must be zero unless message is from a system address"
);
require(
receivedMessages[versionedHash],
"CrossDomainMessenger: message cannot be replayed"
); );
require(receivedMessages[versionedHash], "Message cannot be replayed.");
} }
require( require(
blockedSystemAddresses[_target] == false, blockedSystemAddresses[_target] == false,
"Cannot send message to blocked system address." "CrossDomainMessenger: cannot send message to blocked system address"
); );
require(successfulMessages[versionedHash] == false, "Message has already been relayed."); require(
successfulMessages[versionedHash] == false,
"CrossDomainMessenger: message has already been relayed"
);
require( require(
gasleft() >= _minGasLimit + RELAY_GAS_REQUIRED, gasleft() >= _minGasLimit + RELAY_GAS_REQUIRED,
"Insufficient gas to relay message." "CrossDomainMessenger: insufficient gas to relay message"
); );
xDomainMsgSender = _sender; xDomainMsgSender = _sender;
......
...@@ -88,11 +88,6 @@ contract OptimismMintableERC20Factory { ...@@ -88,11 +88,6 @@ contract OptimismMintableERC20Factory {
"OptimismMintableERC20Factory: must provide remote token address" "OptimismMintableERC20Factory: must provide remote token address"
); );
require(
bridge != address(0),
"OptimismMintableERC20Factory: must initialize contract first"
);
OptimismMintableERC20 localToken = new OptimismMintableERC20( OptimismMintableERC20 localToken = new OptimismMintableERC20(
bridge, bridge,
_remoteToken, _remoteToken,
......
...@@ -130,7 +130,10 @@ abstract contract StandardBridge is Initializable { ...@@ -130,7 +130,10 @@ abstract contract StandardBridge is Initializable {
* just trying to prevent users accidentally depositing with smart contract wallets. * just trying to prevent users accidentally depositing with smart contract wallets.
*/ */
modifier onlyEOA() { modifier onlyEOA() {
require(!Address.isContract(msg.sender), "Account not EOA"); require(
!Address.isContract(msg.sender),
"StandardBridge: function can only be called from an EOA"
);
_; _;
} }
...@@ -141,7 +144,7 @@ abstract contract StandardBridge is Initializable { ...@@ -141,7 +144,7 @@ abstract contract StandardBridge is Initializable {
require( require(
msg.sender == address(messenger) && msg.sender == address(messenger) &&
messenger.xDomainMessageSender() == address(otherBridge), messenger.xDomainMessageSender() == address(otherBridge),
"Could not authenticate bridge message." "StandardBridge: function can only be called from the other bridge"
); );
_; _;
} }
...@@ -150,7 +153,7 @@ abstract contract StandardBridge is Initializable { ...@@ -150,7 +153,7 @@ abstract contract StandardBridge is Initializable {
* @notice Ensures that the caller is this contract. * @notice Ensures that the caller is this contract.
*/ */
modifier onlySelf() { modifier onlySelf() {
require(msg.sender == address(this), "Function can only be called by self."); require(msg.sender == address(this), "StandardBridge: function can only be called by self");
_; _;
} }
...@@ -277,12 +280,12 @@ abstract contract StandardBridge is Initializable { ...@@ -277,12 +280,12 @@ abstract contract StandardBridge is Initializable {
uint256 _amount, uint256 _amount,
bytes calldata _extraData bytes calldata _extraData
) public payable onlyOtherBridge { ) public payable onlyOtherBridge {
require(msg.value == _amount, "Amount sent does not match amount required."); require(msg.value == _amount, "StandardBridge: amount sent does not match amount required");
require(_to != address(this), "Cannot send to self."); require(_to != address(this), "StandardBridge: cannot send to self");
emit ETHBridgeFinalized(_from, _to, _amount, _extraData); emit ETHBridgeFinalized(_from, _to, _amount, _extraData);
(bool success, ) = _to.call{ value: _amount }(new bytes(0)); (bool success, ) = _to.call{ value: _amount }(new bytes(0));
require(success, "ETH transfer failed."); require(success, "StandardBridge: ETH transfer failed");
} }
/** /**
...@@ -348,12 +351,12 @@ abstract contract StandardBridge is Initializable { ...@@ -348,12 +351,12 @@ abstract contract StandardBridge is Initializable {
) public onlySelf { ) public onlySelf {
// Make sure external function calls can't be used to trigger calls to // Make sure external function calls can't be used to trigger calls to
// completeOutboundTransfer. We only make external (write) calls to _localToken. // completeOutboundTransfer. We only make external (write) calls to _localToken.
require(_localToken != address(this), "Local token cannot be self"); require(_localToken != address(this), "StandardBridge: local token cannot be self");
if (_isOptimismMintableERC20(_localToken)) { if (_isOptimismMintableERC20(_localToken)) {
require( require(
_isCorrectTokenPair(_localToken, _remoteToken), _isCorrectTokenPair(_localToken, _remoteToken),
"Wrong remote token for Optimism Mintable ERC20 local token" "StandardBridge: wrong remote token for Optimism Mintable ERC20 local token"
); );
OptimismMintableERC20(_localToken).mint(_to, _amount); OptimismMintableERC20(_localToken).mint(_to, _amount);
...@@ -434,12 +437,12 @@ abstract contract StandardBridge is Initializable { ...@@ -434,12 +437,12 @@ abstract contract StandardBridge is Initializable {
) internal { ) internal {
// Make sure external function calls can't be used to trigger calls to // Make sure external function calls can't be used to trigger calls to
// completeOutboundTransfer. We only make external (write) calls to _localToken. // completeOutboundTransfer. We only make external (write) calls to _localToken.
require(_localToken != address(this), "Local token cannot be self"); require(_localToken != address(this), "StandardBridge: local token cannot be self");
if (_isOptimismMintableERC20(_localToken)) { if (_isOptimismMintableERC20(_localToken)) {
require( require(
_isCorrectTokenPair(_localToken, _remoteToken), _isCorrectTokenPair(_localToken, _remoteToken),
"Wrong remote token for Optimism Mintable ERC20 local token" "StandardBridge: wrong remote token for Optimism Mintable ERC20 local token"
); );
OptimismMintableERC20(_localToken).burn(_from, _amount); OptimismMintableERC20(_localToken).burn(_from, _amount);
......
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