Skip to content

Commit 639df67

Browse files
committed
fix: resolve solhint warnings in RecurringCollector and fix subgraph-service coverage
- Revert strict inequality conversions (> x-1, < x+1) back to (>=, <=) and suppress gas-strict-inequalities with solhint comments instead - Suppress gas-small-strings, function-max-lines solhint warnings - Add --ir-minimum to subgraph-service forge coverage to fix stack too deep - Change getCollectionInfo param from memory to calldata - Add @author natspec tag
1 parent 4450e9c commit 639df67

File tree

5 files changed

+32
-15
lines changed

5 files changed

+32
-15
lines changed

packages/horizon/contracts/payments/collectors/RecurringCollector.sol

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { PPMMath } from "../../libraries/PPMMath.sol";
1515

1616
/**
1717
* @title RecurringCollector contract
18+
* @author Edge & Node
1819
* @dev Implements the {IRecurringCollector} interface.
1920
* @notice A payments collector contract that can be used to collect payments using a RCA (Recurring Collection Agreement).
2021
* @custom:security-contact Please email security+contracts@thegraph.com if you find any
@@ -26,6 +27,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
2627
/// @notice The minimum number of seconds that must be between two collections
2728
uint32 public constant MIN_SECONDS_COLLECTION_WINDOW = 600;
2829

30+
/* solhint-disable gas-small-strings */
2931
/// @notice The EIP712 typehash for the RecurringCollectionAgreement struct
3032
bytes32 public constant EIP712_RCA_TYPEHASH =
3133
keccak256(
@@ -37,6 +39,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
3739
keccak256(
3840
"RecurringCollectionAgreementUpdate(bytes16 agreementId,uint64 deadline,uint64 endsAt,uint256 maxInitialTokens,uint256 maxOngoingTokensPerSecond,uint32 minSecondsPerCollection,uint32 maxSecondsPerCollection,uint32 nonce,bytes metadata)"
3941
);
42+
/* solhint-enable gas-small-strings */
4043

4144
/// @notice Tracks agreements
4245
mapping(bytes16 agreementId => AgreementData data) public agreements;
@@ -75,7 +78,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
7578
* See {IRecurringCollector.accept}.
7679
* @dev Caller must be the data service the RCA was issued to.
7780
*/
78-
function accept(SignedRCA calldata signedRCA) external returns (bytes16) {
81+
function accept(SignedRCA calldata signedRCA) external returns (bytes16) { // solhint-disable-line function-max-lines
7982
bytes16 agreementId = _generateAgreementId(
8083
signedRCA.rca.payer,
8184
signedRCA.rca.dataService,
@@ -89,10 +92,12 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
8992
msg.sender == signedRCA.rca.dataService,
9093
RecurringCollectorUnauthorizedCaller(msg.sender, signedRCA.rca.dataService)
9194
);
95+
/* solhint-disable gas-strict-inequalities */
9296
require(
9397
signedRCA.rca.deadline >= block.timestamp,
9498
RecurringCollectorAgreementDeadlineElapsed(block.timestamp, signedRCA.rca.deadline)
9599
);
100+
/* solhint-enable gas-strict-inequalities */
96101

97102
// check that the voucher is signed by the payer (or proxy)
98103
_requireAuthorizedRCASigner(signedRCA);
@@ -187,11 +192,13 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
187192
* @dev Note: Updated pricing terms apply immediately and will affect the next collection
188193
* for the entire period since lastCollectionAt.
189194
*/
190-
function update(SignedRCAU calldata signedRCAU) external {
195+
function update(SignedRCAU calldata signedRCAU) external { // solhint-disable-line function-max-lines
196+
/* solhint-disable gas-strict-inequalities */
191197
require(
192198
signedRCAU.rcau.deadline >= block.timestamp,
193199
RecurringCollectorAgreementDeadlineElapsed(block.timestamp, signedRCAU.rcau.deadline)
194200
);
201+
/* solhint-enable gas-strict-inequalities */
195202

196203
AgreementData storage agreement = _getAgreementStorage(signedRCAU.rcau.agreementId);
197204
require(
@@ -268,7 +275,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
268275

269276
/// @inheritdoc IRecurringCollector
270277
function getCollectionInfo(
271-
AgreementData memory agreement
278+
AgreementData calldata agreement
272279
) external view returns (bool isCollectable, uint256 collectionSeconds, AgreementNotCollectableReason reason) {
273280
return _getCollectionInfo(agreement);
274281
}
@@ -303,7 +310,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
303310
* @param _params The decoded parameters for the collection
304311
* @return The amount of tokens collected
305312
*/
306-
function _collect(
313+
function _collect( // solhint-disable-line function-max-lines
307314
IGraphPayments.PaymentTypes _paymentType,
308315
CollectParams memory _params
309316
) private returns (uint256) {
@@ -336,10 +343,12 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
336343
tokensToCollect = _requireValidCollect(agreement, _params.agreementId, _params.tokens, collectionSeconds);
337344

338345
uint256 slippage = _params.tokens - tokensToCollect;
346+
/* solhint-disable gas-strict-inequalities */
339347
require(
340348
slippage <= _params.maxSlippage,
341349
RecurringCollectorExcessiveSlippage(_params.tokens, tokensToCollect, _params.maxSlippage)
342350
);
351+
/* solhint-enable gas-strict-inequalities */
343352
}
344353
agreement.lastCollectionAt = uint64(block.timestamp);
345354

@@ -395,6 +404,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
395404
// Collection window needs to be at least MIN_SECONDS_COLLECTION_WINDOW
396405
require(
397406
_maxSecondsPerCollection > _minSecondsPerCollection &&
407+
// solhint-disable-next-line gas-strict-inequalities
398408
(_maxSecondsPerCollection - _minSecondsPerCollection >= MIN_SECONDS_COLLECTION_WINDOW),
399409
RecurringCollectorAgreementInvalidCollectionWindow(
400410
MIN_SECONDS_COLLECTION_WINDOW,
@@ -405,6 +415,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
405415

406416
// Agreement needs to last at least one min collection window
407417
require(
418+
// solhint-disable-next-line gas-strict-inequalities
408419
_endsAt - block.timestamp >= _minSecondsPerCollection + MIN_SECONDS_COLLECTION_WINDOW,
409420
RecurringCollectorAgreementInvalidDuration(
410421
_minSecondsPerCollection + MIN_SECONDS_COLLECTION_WINDOW,
@@ -431,6 +442,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
431442
block.timestamp > _agreement.endsAt;
432443
if (!canceledOrElapsed) {
433444
require(
445+
// solhint-disable-next-line gas-strict-inequalities
434446
_collectionSeconds >= _agreement.minSecondsPerCollection,
435447
RecurringCollectorCollectionTooSoon(
436448
_agreementId,
@@ -440,6 +452,7 @@ contract RecurringCollector is EIP712, GraphDirectory, Authorizable, IRecurringC
440452
);
441453
}
442454
require(
455+
// solhint-disable-next-line gas-strict-inequalities
443456
_collectionSeconds <= _agreement.maxSecondsPerCollection,
444457
RecurringCollectorCollectionTooLate(
445458
_agreementId,

packages/interfaces/contracts/horizon/IRecurringCollector.sol

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { IAuthorizable } from "./IAuthorizable.sol";
77

88
/**
99
* @title Interface for the {RecurringCollector} contract
10+
* @author Edge & Node
1011
* @dev Implements the {IPaymentCollector} interface as defined by the Graph
1112
* Horizon payments protocol.
1213
* @notice Implements a payments collector contract that can be used to collect
@@ -63,6 +64,7 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
6364
* @param metadata Arbitrary metadata to extend functionality if a data service requires it
6465
*
6566
*/
67+
// solhint-disable-next-line gas-struct-packing
6668
struct RecurringCollectionAgreement {
6769
uint64 deadline;
6870
uint64 endsAt;
@@ -101,6 +103,7 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
101103
* @param nonce The nonce for preventing replay attacks (must be current nonce + 1)
102104
* @param metadata Arbitrary metadata to extend functionality if a data service requires it
103105
*/
106+
// solhint-disable-next-line gas-struct-packing
104107
struct RecurringCollectionAgreementUpdate {
105108
bytes16 agreementId;
106109
uint64 deadline;
@@ -395,48 +398,48 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
395398
error RecurringCollectorExcessiveSlippage(uint256 requested, uint256 actual, uint256 maxSlippage);
396399

397400
/**
398-
* @dev Accept an indexing agreement.
401+
* @notice Accept an indexing agreement.
399402
* @param signedRCA The signed Recurring Collection Agreement which is to be accepted.
400403
* @return agreementId The deterministically generated agreement ID
401404
*/
402405
function accept(SignedRCA calldata signedRCA) external returns (bytes16 agreementId);
403406

404407
/**
405-
* @dev Cancel an indexing agreement.
408+
* @notice Cancel an indexing agreement.
406409
* @param agreementId The agreement's ID.
407410
* @param by The party that is canceling the agreement.
408411
*/
409412
function cancel(bytes16 agreementId, CancelAgreementBy by) external;
410413

411414
/**
412-
* @dev Update an indexing agreement.
415+
* @notice Update an indexing agreement.
413416
* @param signedRCAU The signed Recurring Collection Agreement Update which is to be applied.
414417
*/
415418
function update(SignedRCAU calldata signedRCAU) external;
416419

417420
/**
418-
* @dev Computes the hash of a RecurringCollectionAgreement (RCA).
421+
* @notice Computes the hash of a RecurringCollectionAgreement (RCA).
419422
* @param rca The RCA for which to compute the hash.
420423
* @return The hash of the RCA.
421424
*/
422425
function hashRCA(RecurringCollectionAgreement calldata rca) external view returns (bytes32);
423426

424427
/**
425-
* @dev Computes the hash of a RecurringCollectionAgreementUpdate (RCAU).
428+
* @notice Computes the hash of a RecurringCollectionAgreementUpdate (RCAU).
426429
* @param rcau The RCAU for which to compute the hash.
427430
* @return The hash of the RCAU.
428431
*/
429432
function hashRCAU(RecurringCollectionAgreementUpdate calldata rcau) external view returns (bytes32);
430433

431434
/**
432-
* @dev Recovers the signer address of a signed RecurringCollectionAgreement (RCA).
435+
* @notice Recovers the signer address of a signed RecurringCollectionAgreement (RCA).
433436
* @param signedRCA The SignedRCA containing the RCA and its signature.
434437
* @return The address of the signer.
435438
*/
436439
function recoverRCASigner(SignedRCA calldata signedRCA) external view returns (address);
437440

438441
/**
439-
* @dev Recovers the signer address of a signed RecurringCollectionAgreementUpdate (RCAU).
442+
* @notice Recovers the signer address of a signed RecurringCollectionAgreementUpdate (RCAU).
440443
* @param signedRCAU The SignedRCAU containing the RCAU and its signature.
441444
* @return The address of the signer.
442445
*/
@@ -458,7 +461,7 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
458461
* @return reason The reason why the agreement is not collectable (None if collectable)
459462
*/
460463
function getCollectionInfo(
461-
AgreementData memory agreement
464+
AgreementData calldata agreement
462465
) external view returns (bool isCollectable, uint256 collectionSeconds, AgreementNotCollectableReason reason);
463466

464467
/**

packages/interfaces/contracts/subgraph-service/IDisputeManager.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ interface IDisputeManager {
122122
);
123123

124124
/**
125-
* @dev Emitted when an indexing fee dispute is created for `agreementId` and `indexer`
125+
* @notice Emitted when an indexing fee dispute is created for `agreementId` and `indexer`
126126
* by `fisherman`.
127-
* The event emits the amount of `tokens` deposited by the fisherman.
127+
* @dev The event emits the amount of `tokens` deposited by the fisherman.
128128
* @param disputeId The dispute id
129129
* @param indexer The indexer address
130130
* @param fisherman The fisherman address

packages/interfaces/contracts/subgraph-service/ISubgraphService.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ interface ISubgraphService is IDataServiceFees {
7575
* @param indexingFeesCut The indexing fees cut
7676
*/
7777
event IndexingFeesCutSet(uint256 indexingFeesCut);
78+
// solhint-disable-previous-line gas-indexed-events
7879

7980
/**
8081
* @notice Thrown when trying to set a curation cut that is not a valid PPM value

packages/subgraph-service/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"test:deployment": "SECURE_ACCOUNTS_DISABLE_PROVIDER=true hardhat test test/deployment/*.ts",
3434
"test:integration": "./scripts/integration",
3535
"test:coverage": "pnpm build && pnpm test:coverage:self",
36-
"test:coverage:self": "forge coverage",
36+
"test:coverage:self": "forge coverage --ir-minimum",
3737
"prepublishOnly": "pnpm run build"
3838
},
3939
"devDependencies": {

0 commit comments

Comments
 (0)