Skip to content

Commit ef651a6

Browse files
f: smaller contract size via proxy
1 parent 7ba3dd1 commit ef651a6

File tree

15 files changed

+257
-136
lines changed

15 files changed

+257
-136
lines changed

packages/horizon/contracts/data-service/utilities/ProvisionManager.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ abstract contract ProvisionManager is Initializable, GraphDirectory, ProvisionMa
111111
_;
112112
}
113113

114+
modifier onlyAuthorizedForProvisionHack(address caller, address serviceProvider) {
115+
require(
116+
_graphStaking().isAuthorized(serviceProvider, address(this), caller),
117+
ProvisionManagerNotAuthorized(serviceProvider, caller)
118+
);
119+
_;
120+
}
121+
114122
/**
115123
* @notice Checks if a provision of a service provider is valid according
116124
* to the parameter ranges established.

packages/subgraph-service/contracts/DisputeManager.sol

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { IGraphToken } from "@graphprotocol/contracts/contracts/token/IGraphToke
55
import { IHorizonStaking } from "@graphprotocol/horizon/contracts/interfaces/IHorizonStaking.sol";
66
import { IDisputeManager } from "./interfaces/IDisputeManager.sol";
77
import { ISubgraphService } from "./interfaces/ISubgraphService.sol";
8+
import { ISubgraphServiceExtension } from "./interfaces/ISubgraphServiceExtension.sol";
89

910
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
1011
import { TokenUtils } from "@graphprotocol/contracts/contracts/utils/TokenUtils.sol";
@@ -480,7 +481,9 @@ contract DisputeManager is
480481
bytes32 _poi,
481482
uint256 _entities
482483
) private returns (bytes32) {
483-
IndexingAgreement.AgreementWrapper memory wrapper = _getSubgraphService().getIndexingAgreement(_agreementId);
484+
IndexingAgreement.AgreementWrapper memory wrapper = _getSubgraphServiceExtension().getIndexingAgreement(
485+
_agreementId
486+
);
484487

485488
// Agreement must have been collected on and be a version 1
486489
require(
@@ -703,6 +706,16 @@ contract DisputeManager is
703706
return subgraphService;
704707
}
705708

709+
/**
710+
* @notice Get the address of the subgraph service extension
711+
* @dev Will revert if the subgraph service is not set
712+
* @return The subgraph service address
713+
*/
714+
function _getSubgraphServiceExtension() private view returns (ISubgraphServiceExtension) {
715+
require(address(subgraphService) != address(0), DisputeManagerSubgraphServiceNotSet());
716+
return ISubgraphServiceExtension(address(subgraphService));
717+
}
718+
706719
/**
707720
* @notice Returns whether the dispute is for a conflicting attestation or not.
708721
* @param _dispute Dispute

packages/subgraph-service/contracts/SubgraphService.sol

Lines changed: 51 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { DataService } from "@graphprotocol/horizon/contracts/data-service/DataS
1616
import { DataServiceFees } from "@graphprotocol/horizon/contracts/data-service/extensions/DataServiceFees.sol";
1717
import { Directory } from "./utilities/Directory.sol";
1818
import { AllocationManager } from "./utilities/AllocationManager.sol";
19-
import { IndexingAgreementManagerStorageV1 } from "./utilities/IndexingAgreementManagerStorageV1.sol";
2019
import { SubgraphServiceV1Storage } from "./SubgraphServiceStorage.sol";
2120

2221
import { TokenUtils } from "@graphprotocol/contracts/contracts/utils/TokenUtils.sol";
@@ -44,8 +43,7 @@ contract SubgraphService is
4443
AllocationManager,
4544
SubgraphServiceV1Storage,
4645
IRewardsIssuer,
47-
ISubgraphService,
48-
IndexingAgreementManagerStorageV1
46+
ISubgraphService
4947
{
5048
using PPMMath for uint256;
5149
using Allocation for mapping(address => Allocation.State);
@@ -75,10 +73,11 @@ contract SubgraphService is
7573
address disputeManager,
7674
address graphTallyCollector,
7775
address curation,
78-
address recurringCollector
76+
address recurringCollector,
77+
address extension
7978
)
8079
DataService(graphController)
81-
Directory(address(this), disputeManager, graphTallyCollector, curation, recurringCollector)
80+
Directory(address(this), disputeManager, graphTallyCollector, curation, recurringCollector, extension)
8281
{
8382
_disableInitializers();
8483
}
@@ -553,6 +552,10 @@ contract SubgraphService is
553552
emit StakeToFeesRatioSet(_stakeToFeesRatio);
554553
}
555554

555+
function _cancelAllocationIndexingAgreement(address _allocationId) internal {
556+
IndexingAgreement._getManager().cancelForAllocation(_allocationId);
557+
}
558+
556559
/**
557560
* @notice Accept an indexing agreement.
558561
* See {ISubgraphService.acceptIndexingAgreement}.
@@ -584,75 +587,7 @@ contract SubgraphService is
584587
onlyValidProvision(signedRCA.rca.serviceProvider)
585588
onlyRegisteredIndexer(signedRCA.rca.serviceProvider)
586589
{
587-
_indexingAgreementManager.accept(_allocations, allocationId, signedRCA);
588-
}
589-
590-
function upgradeIndexingAgreement(
591-
address indexer,
592-
IRecurringCollector.SignedRCAU calldata signedRCAU
593-
)
594-
external
595-
whenNotPaused
596-
onlyAuthorizedForProvision(indexer)
597-
onlyValidProvision(indexer)
598-
onlyRegisteredIndexer(indexer)
599-
{
600-
_indexingAgreementManager.upgrade(indexer, signedRCAU);
601-
}
602-
603-
/**
604-
* @notice Cancel an indexing agreement by indexer / operator.
605-
* See {ISubgraphService.cancelIndexingAgreement}.
606-
*
607-
* @dev Can only be canceled on behalf of a valid indexer.
608-
*
609-
* Requirements:
610-
* - The indexer must be registered
611-
* - The caller must be authorized by the indexer
612-
* - The provision must be valid according to the subgraph service rules
613-
* - The agreement must be active
614-
*
615-
* Emits {IndexingAgreementCanceled} event
616-
*
617-
* @param agreementId The id of the agreement
618-
*/
619-
function cancelIndexingAgreement(
620-
address indexer,
621-
bytes16 agreementId
622-
)
623-
external
624-
whenNotPaused
625-
onlyAuthorizedForProvision(indexer)
626-
onlyValidProvision(indexer)
627-
onlyRegisteredIndexer(indexer)
628-
{
629-
_indexingAgreementManager.cancel(indexer, agreementId);
630-
}
631-
632-
function _cancelAllocationIndexingAgreement(address _allocationId) internal {
633-
_indexingAgreementManager.cancelForAllocation(_allocationId);
634-
}
635-
636-
/**
637-
* @notice Cancel an indexing agreement by payer / signer.
638-
* See {ISubgraphService.cancelIndexingAgreementByPayer}.
639-
*
640-
* Requirements:
641-
* - The caller must be authorized by the payer
642-
* - The agreement must be active
643-
*
644-
* Emits {IndexingAgreementCanceled} event
645-
*
646-
* @param agreementId The id of the agreement
647-
*/
648-
function cancelIndexingAgreementByPayer(bytes16 agreementId) external whenNotPaused {
649-
_indexingAgreementManager.cancelByPayer(agreementId);
650-
}
651-
652-
function getIndexingAgreement(
653-
bytes16 agreementId
654-
) external view returns (IndexingAgreement.AgreementWrapper memory) {
655-
return _indexingAgreementManager.get(agreementId);
590+
IndexingAgreement._getManager().accept(_allocations, allocationId, signedRCA);
656591
}
657592

658593
/**
@@ -680,7 +615,7 @@ contract SubgraphService is
680615
* @return The amount of fees collected
681616
*/
682617
function _collectIndexingFees(bytes16 _agreementId, bytes memory _data) private returns (uint256) {
683-
(address indexer, uint256 tokensCollected) = _indexingAgreementManager.collect(
618+
(address indexer, uint256 tokensCollected) = IndexingAgreement._getManager().collect(
684619
_allocations,
685620
_agreementId,
686621
_data
@@ -702,4 +637,45 @@ contract SubgraphService is
702637
);
703638
}
704639
}
640+
641+
function modifiersHack(
642+
address caller,
643+
address indexer
644+
)
645+
external
646+
view
647+
whenNotPaused
648+
onlyAuthorizedForProvisionHack(caller, indexer)
649+
onlyValidProvision(indexer)
650+
onlyRegisteredIndexer(indexer)
651+
{}
652+
653+
/**
654+
* @notice Delegates the call to the SubgraphServiceExtension implementation.
655+
* @dev This function does not return to its internal call site, it will return directly to the
656+
* external caller.
657+
*/
658+
// solhint-disable-next-line payable-fallback, no-complex-fallback
659+
fallback() external {
660+
address extImpl = _subgraphServiceExtensionImpl();
661+
require(extImpl != address(0), "only through proxy");
662+
663+
// solhint-disable-next-line no-inline-assembly
664+
assembly {
665+
// copy function selector and any arguments
666+
calldatacopy(0, 0, calldatasize())
667+
// execute function call using the extension implementation
668+
let result := delegatecall(gas(), extImpl, 0, calldatasize(), 0, 0)
669+
// get any return value
670+
returndatacopy(0, 0, returndatasize())
671+
// return any return value or error back to the caller
672+
switch result
673+
case 0 {
674+
revert(0, returndatasize())
675+
}
676+
default {
677+
return(0, returndatasize())
678+
}
679+
}
680+
}
705681
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity 0.8.27;
3+
4+
import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
5+
import { IRecurringCollector } from "@graphprotocol/horizon/contracts/interfaces/IRecurringCollector.sol";
6+
7+
import { IndexingAgreement } from "./libraries/IndexingAgreement.sol";
8+
import { SubgraphService } from "./SubgraphService.sol";
9+
10+
contract SubgraphServiceExtension is PausableUpgradeable {
11+
using IndexingAgreement for IndexingAgreement.Manager;
12+
13+
modifier modifiersHack(address indexer) {
14+
SubgraphService(address(this)).modifiersHack(msg.sender, indexer);
15+
_;
16+
}
17+
18+
function upgradeIndexingAgreement(
19+
address indexer,
20+
IRecurringCollector.SignedRCAU calldata signedRCAU
21+
) external modifiersHack(indexer) {
22+
IndexingAgreement._getManager().upgrade(indexer, signedRCAU);
23+
}
24+
25+
/**
26+
* @notice Cancel an indexing agreement by indexer / operator.
27+
* See {ISubgraphService.cancelIndexingAgreement}.
28+
*
29+
* @dev Can only be canceled on behalf of a valid indexer.
30+
*
31+
* Requirements:
32+
* - The indexer must be registered
33+
* - The caller must be authorized by the indexer
34+
* - The provision must be valid according to the subgraph service rules
35+
* - The agreement must be active
36+
*
37+
* Emits {IndexingAgreementCanceled} event
38+
*
39+
* @param agreementId The id of the agreement
40+
*/
41+
function cancelIndexingAgreement(address indexer, bytes16 agreementId) external modifiersHack(indexer) {
42+
IndexingAgreement._getManager().cancel(indexer, agreementId);
43+
}
44+
45+
/**
46+
* @notice Cancel an indexing agreement by payer / signer.
47+
* See {ISubgraphService.cancelIndexingAgreementByPayer}.
48+
*
49+
* Requirements:
50+
* - The caller must be authorized by the payer
51+
* - The agreement must be active
52+
*
53+
* Emits {IndexingAgreementCanceled} event
54+
*
55+
* @param agreementId The id of the agreement
56+
*/
57+
function cancelIndexingAgreementByPayer(bytes16 agreementId) external whenNotPaused {
58+
IndexingAgreement._getManager().cancelByPayer(agreementId);
59+
}
60+
61+
function getIndexingAgreement(
62+
bytes16 agreementId
63+
) external view returns (IndexingAgreement.AgreementWrapper memory) {
64+
return IndexingAgreement._getManager().get(agreementId);
65+
}
66+
67+
function _cancelAllocationIndexingAgreement(address _allocationId) internal {
68+
IndexingAgreement._getManager().cancelForAllocation(_allocationId);
69+
}
70+
}

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

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ pragma solidity 0.8.27;
33

44
import { IDataServiceFees } from "@graphprotocol/horizon/contracts/data-service/interfaces/IDataServiceFees.sol";
55
import { IGraphPayments } from "@graphprotocol/horizon/contracts/interfaces/IGraphPayments.sol";
6-
import { IRecurringCollector } from "@graphprotocol/horizon/contracts/interfaces/IRecurringCollector.sol";
76

87
import { Allocation } from "../libraries/Allocation.sol";
98
import { LegacyAllocation } from "../libraries/LegacyAllocation.sol";
10-
import { IndexingAgreement } from "../libraries/IndexingAgreement.sol";
9+
10+
import { IRecurringCollector } from "@graphprotocol/horizon/contracts/interfaces/IRecurringCollector.sol";
1111

1212
/**
1313
* @title Interface for the {SubgraphService} contract
@@ -301,23 +301,4 @@ interface ISubgraphService is IDataServiceFees {
301301
* @notice Accept an indexing agreement.
302302
*/
303303
function acceptIndexingAgreement(address allocationId, IRecurringCollector.SignedRCA calldata signedRCA) external;
304-
305-
/**
306-
* @notice Upgrade an indexing agreement.
307-
*/
308-
function upgradeIndexingAgreement(address indexer, IRecurringCollector.SignedRCAU calldata signedRCAU) external;
309-
310-
/**
311-
* @notice Cancel an indexing agreement by indexer / operator.
312-
*/
313-
function cancelIndexingAgreement(address indexer, bytes16 agreementId) external;
314-
315-
/**
316-
* @notice Cancel an indexing agreement by payer / signer.
317-
*/
318-
function cancelIndexingAgreementByPayer(bytes16 agreementId) external;
319-
320-
function getIndexingAgreement(
321-
bytes16 agreementId
322-
) external view returns (IndexingAgreement.AgreementWrapper memory);
323304
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity 0.8.27;
3+
4+
import { IRecurringCollector } from "@graphprotocol/horizon/contracts/interfaces/IRecurringCollector.sol";
5+
6+
import { IndexingAgreement } from "../libraries/IndexingAgreement.sol";
7+
8+
interface ISubgraphServiceExtension {
9+
/**
10+
* @notice Accept an indexing agreement.
11+
*/
12+
// function acceptIndexingAgreement(address allocationId, IRecurringCollector.SignedRCA calldata signedRCA) external;
13+
14+
/**
15+
* @notice Upgrade an indexing agreement.
16+
*/
17+
function upgradeIndexingAgreement(address indexer, IRecurringCollector.SignedRCAU calldata signedRCAU) external;
18+
19+
/**
20+
* @notice Cancel an indexing agreement by indexer / operator.
21+
*/
22+
function cancelIndexingAgreement(address indexer, bytes16 agreementId) external;
23+
24+
/**
25+
* @notice Cancel an indexing agreement by payer / signer.
26+
*/
27+
function cancelIndexingAgreementByPayer(bytes16 agreementId) external;
28+
29+
function getIndexingAgreement(
30+
bytes16 agreementId
31+
) external view returns (IndexingAgreement.AgreementWrapper memory);
32+
}

packages/subgraph-service/contracts/libraries/IndexingAgreement.sol

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ library IndexingAgreement {
7474
uint256 tokensPerEntityPerSecond;
7575
}
7676

77+
bytes32 private constant INDEXING_AGREEMENT_MANAGER_STORAGE_V1_SLOT = keccak256("v1.manager.indexing-agreement");
78+
7779
/**
7880
* @notice Emitted when an indexer collects indexing fees from a V1 agreement
7981
* @param indexer The address of the indexer
@@ -377,6 +379,15 @@ library IndexingAgreement {
377379
return wrapper;
378380
}
379381

382+
function _getManager() internal pure returns (Manager storage manager) {
383+
bytes32 slot = INDEXING_AGREEMENT_MANAGER_STORAGE_V1_SLOT;
384+
385+
// solhint-disable-next-line no-inline-assembly
386+
assembly {
387+
manager.slot := slot
388+
}
389+
}
390+
380391
function _setTermsV1(Manager storage _manager, bytes16 _agreementId, bytes memory _data) private {
381392
IndexingAgreementTermsV1 memory newTerms = Decoder.decodeIndexingAgreementTermsV1(_data);
382393
_manager.termsV1[_agreementId].tokensPerSecond = newTerms.tokensPerSecond;

0 commit comments

Comments
 (0)