Skip to content

Commit 1d46a82

Browse files
yorhodesnambrot
andauthored
test: lint for functions that are virtual and override (#7086)
Co-authored-by: nambrot <[email protected]>
1 parent 18c32ed commit 1d46a82

38 files changed

+143
-92
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hyperlane-xyz/core": patch
3+
---
4+
5+
Remove majority of virtual override functions

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"postinstall": "husky install"
4141
},
4242
"workspaces": [
43+
"solhint-plugin",
4344
"solidity",
4445
"typescript/*",
4546
"starknet"

solhint-plugin/index.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// https://protofire.github.io/solhint/docs/writing-plugins.html
2+
class NoVirtualOverrideAllowed {
3+
constructor(reporter, config) {
4+
this.ruleId = 'no-virtual-override';
5+
6+
this.reporter = reporter;
7+
this.config = config;
8+
}
9+
10+
FunctionDefinition(ctx) {
11+
const isVirtual = ctx.isVirtual;
12+
const hasOverride = ctx.override !== null;
13+
14+
if (isVirtual && hasOverride) {
15+
this.reporter.error(
16+
ctx,
17+
this.ruleId,
18+
'Functions cannot be "virtual" and "override" at the same time',
19+
);
20+
}
21+
}
22+
}
23+
24+
class NoVirtualInitializerAllowed {
25+
constructor(reporter, config) {
26+
this.ruleId = 'no-virtual-initializer';
27+
28+
this.reporter = reporter;
29+
this.config = config;
30+
}
31+
32+
FunctionDefinition(ctx) {
33+
const isVirtual = ctx.isVirtual;
34+
const hasInitializer = ctx.modifiers.some(
35+
(modifier) => modifier.name === 'initializer',
36+
);
37+
38+
if (isVirtual && hasInitializer) {
39+
this.reporter.error(
40+
ctx,
41+
this.ruleId,
42+
'Functions cannot be "virtual" and "initializer" at the same time',
43+
);
44+
}
45+
}
46+
}
47+
48+
module.exports = [NoVirtualOverrideAllowed, NoVirtualInitializerAllowed];

solhint-plugin/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "solhint-plugin-hyperlane",
3+
"private": true,
4+
"version": "0.0.0",
5+
"description": "",
6+
"license": "Apache-2.0",
7+
"type": "commonjs",
8+
"main": "index.js"
9+
}

solidity/.solhint.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
"reason-string": ["warn", { "maxLength": 64 }],
1313
"prettier/prettier": "error",
1414
"gas-custom-errors": "off",
15-
"named-parameters-mapping": "error"
15+
"named-parameters-mapping": "error",
16+
"hyperlane/no-virtual-override": "error",
17+
"hyperlane/no-virtual-initializer": "error"
1618
},
17-
"plugins": ["prettier"]
19+
"plugins": ["prettier", "hyperlane"]
1820
}

solidity/contracts/avs/HyperlaneServiceManager.sol

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,7 @@ contract HyperlaneServiceManager is ECDSAServiceManagerBase, PackageVersioned {
286286
}
287287

288288
/// @inheritdoc ECDSAServiceManagerBase
289-
function _deregisterOperatorFromAVS(
290-
address operator
291-
) internal virtual override {
289+
function _deregisterOperatorFromAVS(address operator) internal override {
292290
address[] memory challengers = getOperatorChallengers(operator);
293291
_completeUnenrollment(operator, challengers);
294292

solidity/contracts/client/Router.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ abstract contract Router is MailboxClient, IMessageRecipient {
9393
* @param _sender The sender address
9494
* @param _message The message
9595
*/
96+
// solhint-disable-next-line hyperlane/no-virtual-override
9697
function handle(
9798
uint32 _origin,
9899
bytes32 _sender,

solidity/contracts/hooks/DefaultHook.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ contract DefaultHook is AbstractPostDispatchHook, MailboxClient {
2424
function _quoteDispatch(
2525
bytes calldata metadata,
2626
bytes calldata message
27-
) internal view virtual override returns (uint256) {
27+
) internal view override returns (uint256) {
2828
return _hook().quoteDispatch(metadata, message);
2929
}
3030

3131
function _postDispatch(
3232
bytes calldata metadata,
3333
bytes calldata message
34-
) internal virtual override {
34+
) internal override {
3535
_hook().postDispatch{value: msg.value}(metadata, message);
3636
}
3737
}

solidity/contracts/hooks/aggregation/StaticAggregationHookFactory.sol

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,7 @@ import {StaticAggregationHook} from "./StaticAggregationHook.sol";
1818
import {StaticAddressSetFactory} from "../../libs/StaticAddressSetFactory.sol";
1919

2020
contract StaticAggregationHookFactory is StaticAddressSetFactory {
21-
function _deployImplementation()
22-
internal
23-
virtual
24-
override
25-
returns (address)
26-
{
21+
function _deployImplementation() internal override returns (address) {
2722
return address(new StaticAggregationHook());
2823
}
2924
}

solidity/contracts/hooks/igp/InterchainGasPaymaster.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ contract InterchainGasPaymaster is
192192
* @param _gasLimit The amount of destination gas to pay for.
193193
* @return The amount of native tokens required to pay for interchain gas.
194194
*/
195+
// solhint-disable-next-line hyperlane/no-virtual-override
195196
function quoteGasPayment(
196197
uint32 _destinationDomain,
197198
uint256 _gasLimit

0 commit comments

Comments
 (0)