Skip to content

Commit

Permalink
Merge branch 'horizon' into tmigone/ignition-v0.15.9
Browse files Browse the repository at this point in the history
  • Loading branch information
tmigone authored Jan 27, 2025
2 parents 6494bf8 + 17692b7 commit 353902e
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { logDebug, logError } from '../../../logger'
import { Provider, Signer } from 'ethers'
import { AddressBook } from '../../address-book'
import { assertObject } from '../../utils/assertion'
import { Contract } from 'ethers'
import { loadArtifact } from '../../lib/artifact'
import { mergeABIs } from '../../utils/abi'

import type { GraphHorizonContractName, GraphHorizonContracts } from './contracts'

Expand All @@ -23,6 +26,20 @@ export class GraphHorizonAddressBook extends AddressBook<number, GraphHorizonCon
GraphHorizonArtifactsMap,
signerOrProvider,
)

// Handle HorizonStaking specially to include extension functions
if (contracts.HorizonStaking) {
const stakingOverride = new Contract(
this.getEntry('HorizonStaking').address,
mergeABIs(
loadArtifact('HorizonStaking', GraphHorizonArtifactsMap.HorizonStaking).abi,
loadArtifact('HorizonStakingExtension', GraphHorizonArtifactsMap.HorizonStaking).abi,
),
signerOrProvider,
)
contracts.HorizonStaking = stakingOverride
}

this._assertGraphHorizonContracts(contracts)

// Aliases
Expand Down
8 changes: 8 additions & 0 deletions packages/hardhat-graph-protocol/src/sdk/utils/abi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function mergeABIs(abi1: any[], abi2: any[]) {
for (const item of abi2) {
if (abi1.find((v) => v.name === item.name) === undefined) {
abi1.push(item)
}
}
return abi1
}
2 changes: 1 addition & 1 deletion packages/subgraph-service/contracts/SubgraphService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ contract SubgraphService is
/**
* @notice See {ISubgraphService.closeStaleAllocation}
*/
function closeStaleAllocation(address allocationId) external override {
function closeStaleAllocation(address allocationId) external override whenNotPaused {
Allocation.State memory allocation = allocations.get(allocationId);
require(allocation.isStale(maxPOIStaleness), SubgraphServiceCannotForceCloseAllocation(allocationId));
require(!allocation.isAltruistic(), SubgraphServiceAllocationIsAltruistic(allocationId));
Expand Down
4 changes: 3 additions & 1 deletion packages/subgraph-service/test/SubgraphBaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ abstract contract SubgraphBaseTest is Utils, Constants {
delegator: createUser("delegator"),
arbitrator: createUser("arbitrator"),
fisherman: createUser("fisherman"),
rewardsDestination: createUser("rewardsDestination")
rewardsDestination: createUser("rewardsDestination"),
pauseGuardian: createUser("pauseGuardian")
});

deployProtocolContracts();
Expand Down Expand Up @@ -191,6 +192,7 @@ abstract contract SubgraphBaseTest is Utils, Constants {
epochManager.setEpochLength(EPOCH_LENGTH);
subgraphService.setMaxPOIStaleness(maxPOIStaleness);
subgraphService.setCurationCut(curationCut);
subgraphService.setPauseGuardian(users.pauseGuardian, true);
}

function unpauseProtocol() private {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ abstract contract HorizonStakingSharedTest is SubgraphBaseTest {
staking.delegate(_indexer, _verifier, _tokens, _minSharesOut);
}

function _undelegate(address _indexer, address _verifier, uint256 _shares) internal {
staking.undelegate(_indexer, _verifier, _shares);
}

function _setDelegationFeeCut(
address _indexer,
address _verifier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ abstract contract SubgraphServiceSharedTest is HorizonStakingSharedTest {
}

modifier useAllocation(uint256 tokens) {
vm.assume(tokens > minimumProvisionTokens);
vm.assume(tokens >= minimumProvisionTokens);
vm.assume(tokens < 10_000_000_000 ether);
_createProvision(users.indexer, tokens, maxSlashingPercentage, disputePeriod);
_register(users.indexer, abi.encode("url", "geoHash", address(0)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity 0.8.27;

import "forge-std/Test.sol";

import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import { IGraphPayments } from "@graphprotocol/horizon/contracts/interfaces/IGraphPayments.sol";

import { Allocation } from "../../../contracts/libraries/Allocation.sol";
Expand Down Expand Up @@ -91,4 +92,13 @@ contract SubgraphServiceAllocationForceCloseTest is SubgraphServiceTest {
);
subgraphService.closeStaleAllocation(allocationID);
}

function test_SubgraphService_Allocation_ForceClose_RevertIf_Paused() public useIndexer useAllocation(1000 ether) {
resetPrank(users.pauseGuardian);
subgraphService.pause();

resetPrank(permissionlessBob);
vm.expectRevert(abi.encodeWithSelector(PausableUpgradeable.EnforcedPause.selector));
subgraphService.closeStaleAllocation(allocationID);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;

import "forge-std/Test.sol";

import { IGraphPayments } from "@graphprotocol/horizon/contracts/interfaces/IGraphPayments.sol";
import { IHorizonStakingTypes } from "@graphprotocol/horizon/contracts/interfaces/internal/IHorizonStakingTypes.sol";

import { Allocation } from "../../../contracts/libraries/Allocation.sol";
import { ISubgraphService } from "../../../contracts/interfaces/ISubgraphService.sol";
import { SubgraphServiceTest } from "../SubgraphService.t.sol";

contract SubgraphServiceAllocationOverDelegatedTest is SubgraphServiceTest {

/*
* TESTS
*/

function test_SubgraphService_Allocation_OverDelegated_NotOverAllocatedAfterUndelegation(
uint256 delegationTokens,
uint256 undelegationTokens
) public useIndexer {
// Use minimum provision tokens
uint256 indexerTokens = minimumProvisionTokens;
uint256 allocationTokens = indexerTokens * delegationRatio;
// Bound delegation tokens to be over delegated
delegationTokens = bound(delegationTokens, allocationTokens, MAX_TOKENS);
// Assume undelegation tokens to still leave indexer over delegated
vm.assume(undelegationTokens > 1);
vm.assume(undelegationTokens < delegationTokens - allocationTokens);

// Create provision
token.approve(address(staking), indexerTokens);
_createProvision(users.indexer, indexerTokens, maxSlashingPercentage, disputePeriod);
_register(users.indexer, abi.encode("url", "geoHash", address(0)));

// Delegate so that indexer is over allocated
resetPrank(users.delegator);
token.approve(address(staking), delegationTokens);
_delegate(users.indexer, address(subgraphService), delegationTokens, 0);

// Create allocation
resetPrank(users.indexer);
bytes memory data = _createSubgraphAllocationData(
users.indexer,
subgraphDeployment,
allocationIDPrivateKey,
allocationTokens
);
_startService(users.indexer, data);

// Undelegate
resetPrank(users.delegator);
_undelegate(users.indexer, address(subgraphService), undelegationTokens);

// Check that indexer is not over allocated
assertFalse(subgraphService.isOverAllocated(users.indexer));
}
}
1 change: 1 addition & 0 deletions packages/subgraph-service/test/utils/Users.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ struct Users {
address arbitrator;
address fisherman;
address rewardsDestination;
address pauseGuardian;
}

0 comments on commit 353902e

Please sign in to comment.