Skip to content

Commit 392047c

Browse files
committed
feat: clean up post horizon on horizon contracts
Signed-off-by: Tomás Migone <tomas@edgeandnode.com>
1 parent 714b32c commit 392047c

File tree

9 files changed

+50
-703
lines changed

9 files changed

+50
-703
lines changed

packages/horizon/contracts/staking/HorizonStaking.sol

Lines changed: 18 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ pragma solidity 0.8.27;
99

1010
import { IGraphToken } from "@graphprotocol/interfaces/contracts/contracts/token/IGraphToken.sol";
1111
import { IHorizonStakingMain } from "@graphprotocol/interfaces/contracts/horizon/internal/IHorizonStakingMain.sol";
12-
import { IHorizonStakingExtension } from "@graphprotocol/interfaces/contracts/horizon/internal/IHorizonStakingExtension.sol";
1312
import { IGraphPayments } from "@graphprotocol/interfaces/contracts/horizon/IGraphPayments.sol";
1413
import { ILinkedList } from "@graphprotocol/interfaces/contracts/horizon/internal/ILinkedList.sol";
1514

@@ -28,9 +27,6 @@ import { HorizonStakingBase } from "./HorizonStakingBase.sol";
2827
* @dev Implements the {IHorizonStakingMain} interface.
2928
* @dev This is the main Staking contract in The Graph protocol after the Horizon upgrade.
3029
* It is designed to be deployed as an upgrade to the L2Staking contract from the legacy contracts package.
31-
* @dev It uses a {HorizonStakingExtension} contract to implement the full {IHorizonStaking} interface through delegatecalls.
32-
* This is due to the contract size limit on Arbitrum (24kB). The extension contract implements functionality to support
33-
* the legacy staking functions. It can be eventually removed without affecting the main staking contract.
3430
* @custom:security-contact Please email security+contracts@thegraph.com if you find any
3531
* bugs. We may have an active bug bounty program.
3632
*/
@@ -407,21 +403,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
407403
uint256 tokensVerifier,
408404
address verifierDestination
409405
) external override notPaused {
410-
// TRANSITION PERIOD: remove after the transition period
411-
// Check if sender is authorized to slash on the deprecated list
412-
if (__DEPRECATED_slashers[msg.sender]) {
413-
// Forward call to staking extension
414-
// solhint-disable-next-line avoid-low-level-calls
415-
(bool success, ) = STAKING_EXTENSION_ADDRESS.delegatecall(
416-
abi.encodeCall(
417-
IHorizonStakingExtension.legacySlash,
418-
(serviceProvider, tokens, tokensVerifier, verifierDestination)
419-
)
420-
);
421-
require(success, HorizonStakingLegacySlashFailed());
422-
return;
423-
}
424-
425406
address verifier = msg.sender;
426407
Provision storage prov = _provisions[serviceProvider][verifier];
427408
DelegationPoolInternal storage pool = _getDelegationPool(serviceProvider, verifier);
@@ -538,12 +519,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
538519
emit DelegationSlashingEnabled();
539520
}
540521

541-
/// @inheritdoc IHorizonStakingMain
542-
function clearThawingPeriod() external override onlyGovernor {
543-
__DEPRECATED_thawingPeriod = 0;
544-
emit ThawingPeriodCleared();
545-
}
546-
547522
/// @inheritdoc IHorizonStakingMain
548523
function setMaxThawingPeriod(uint64 maxThawingPeriod) external override onlyGovernor {
549524
_maxThawingPeriod = maxThawingPeriod;
@@ -569,17 +544,19 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
569544
}
570545

571546
/*
572-
* GETTERS
547+
* PRIVATE FUNCTIONS
573548
*/
574549

575-
/// @inheritdoc IHorizonStakingMain
576-
function getStakingExtension() external view override returns (address) {
577-
return STAKING_EXTENSION_ADDRESS;
578-
}
579-
580-
/*
581-
* PRIVATE FUNCTIONS
550+
/**
551+
* @notice Deposit tokens into the service provider stake.
552+
* Emits a {HorizonStakeDeposited} event.
553+
* @param _serviceProvider The address of the service provider.
554+
* @param _tokens The amount of tokens to deposit.
582555
*/
556+
function _stake(address _serviceProvider, uint256 _tokens) internal {
557+
_serviceProviders[_serviceProvider].tokensStaked = _serviceProviders[_serviceProvider].tokensStaked + _tokens;
558+
emit HorizonStakeDeposited(_serviceProvider, _tokens);
559+
}
583560

584561
/**
585562
* @notice Deposit tokens on the service provider stake, on behalf of the service provider.
@@ -599,12 +576,7 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
599576

600577
/**
601578
* @notice Move idle stake back to the owner's account.
602-
* Stake is removed from the protocol:
603-
* - During the transition period it's locked for a period of time before it can be withdrawn
604-
* by calling {withdraw}.
605-
* - After the transition period it's immediately withdrawn.
606-
* Note that after the transition period if there are tokens still locked they will have to be
607-
* withdrawn by calling {withdraw}.
579+
* Stake is immediately removed from the protocol.
608580
* @param _tokens Amount of tokens to unstake
609581
*/
610582
function _unstake(uint256 _tokens) private {
@@ -616,54 +588,25 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
616588
ServiceProviderInternal storage sp = _serviceProviders[serviceProvider];
617589
uint256 stakedTokens = sp.tokensStaked;
618590

619-
// This is also only during the transition period: we need
620-
// to ensure tokens stay locked after closing legacy allocations.
621-
// After sufficient time (56 days?) we should remove the closeAllocation function
622-
// and set the thawing period to 0.
623-
uint256 lockingPeriod = __DEPRECATED_thawingPeriod;
624-
if (lockingPeriod == 0) {
625-
sp.tokensStaked = stakedTokens - _tokens;
626-
_graphToken().pushTokens(serviceProvider, _tokens);
627-
emit HorizonStakeWithdrawn(serviceProvider, _tokens);
628-
} else {
629-
// Before locking more tokens, withdraw any unlocked ones if possible
630-
if (sp.__DEPRECATED_tokensLocked != 0 && block.number >= sp.__DEPRECATED_tokensLockedUntil) {
631-
_withdraw(serviceProvider);
632-
}
633-
// TRANSITION PERIOD: remove after the transition period
634-
// Take into account period averaging for multiple unstake requests
635-
if (sp.__DEPRECATED_tokensLocked > 0) {
636-
lockingPeriod = MathUtils.weightedAverageRoundingUp(
637-
MathUtils.diffOrZero(sp.__DEPRECATED_tokensLockedUntil, block.number), // Remaining thawing period
638-
sp.__DEPRECATED_tokensLocked, // Weighted by remaining unstaked tokens
639-
lockingPeriod, // Thawing period
640-
_tokens // Weighted by new tokens to unstake
641-
);
642-
}
643-
644-
// Update balances
645-
sp.__DEPRECATED_tokensLocked = sp.__DEPRECATED_tokensLocked + _tokens;
646-
sp.__DEPRECATED_tokensLockedUntil = block.number + lockingPeriod;
647-
emit HorizonStakeLocked(serviceProvider, sp.__DEPRECATED_tokensLocked, sp.__DEPRECATED_tokensLockedUntil);
648-
}
591+
sp.tokensStaked = stakedTokens - _tokens;
592+
_graphToken().pushTokens(serviceProvider, _tokens);
593+
emit HorizonStakeWithdrawn(serviceProvider, _tokens);
649594
}
650595

651596
/**
652597
* @notice Withdraw service provider tokens once the thawing period (initiated by {unstake}) has passed.
653598
* All thawed tokens are withdrawn.
654-
* @dev TRANSITION PERIOD: This is only needed during the transition period while we still have
655-
* a global lock. After that, unstake() will automatically withdraw.
599+
* This function is for backwards compatibility with the legacy staking contract.
600+
* It only allows withdrawing tokens unstaked before horizon upgrade.
601+
* @dev This function can't be removed in case there are still pre-horizon unstakes.
602+
* Note that it's assumed unstakes have already passed their thawing period.
656603
* @param _serviceProvider Address of service provider to withdraw funds from
657604
*/
658605
function _withdraw(address _serviceProvider) private {
659606
// Get tokens available for withdraw and update balance
660607
ServiceProviderInternal storage sp = _serviceProviders[_serviceProvider];
661608
uint256 tokensToWithdraw = sp.__DEPRECATED_tokensLocked;
662609
require(tokensToWithdraw != 0, HorizonStakingInvalidZeroTokens());
663-
require(
664-
block.number >= sp.__DEPRECATED_tokensLockedUntil,
665-
HorizonStakingStillThawing(sp.__DEPRECATED_tokensLockedUntil)
666-
);
667610

668611
// Reset locked tokens
669612
sp.__DEPRECATED_tokensLocked = 0;
@@ -683,8 +626,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
683626
* service, where the data service is the verifier.
684627
* This function can be called by the service provider or by an operator authorized by the provider
685628
* for this specific verifier.
686-
* @dev TRANSITION PERIOD: During the transition period, only the subgraph data service can be used as a verifier. This
687-
* prevents an escape hatch for legacy allocation stake.
688629
* @param _serviceProvider The service provider address
689630
* @param _tokens The amount of tokens that will be locked and slashable
690631
* @param _verifier The verifier address for which the tokens are provisioned (who will be able to slash the tokens)
@@ -699,11 +640,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
699640
uint64 _thawingPeriod
700641
) private {
701642
require(_tokens > 0, HorizonStakingInvalidZeroTokens());
702-
// TRANSITION PERIOD: Remove this after the transition period - it prevents an early escape hatch for legacy allocations
703-
require(
704-
_verifier == SUBGRAPH_DATA_SERVICE_ADDRESS || __DEPRECATED_thawingPeriod == 0,
705-
HorizonStakingInvalidVerifier(_verifier)
706-
);
707643
require(PPMMath.isValidPPM(_maxVerifierCut), HorizonStakingInvalidMaxVerifierCut(_maxVerifierCut));
708644
require(
709645
_thawingPeriod <= _maxThawingPeriod,

packages/horizon/contracts/staking/HorizonStakingBase.sol

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ import { HorizonStakingV1Storage } from "./HorizonStakingStorage.sol";
2323
* @author Edge & Node
2424
* @notice This contract is the base staking contract implementing storage getters for both internal
2525
* and external use.
26-
* @dev Implementation of the {IHorizonStakingBase} interface.
27-
* @dev It's meant to be inherited by the {HorizonStaking} and {HorizonStakingExtension}
28-
* contracts so some internal functions are also included here.
26+
* @dev Implementation of the {IHorizonStakingBase} interface, meant to be inherited by {HorizonStaking}.
2927
* @custom:security-contact Please email security+contracts@thegraph.com if you find any
3028
* bugs. We may have an active bug bounty program.
3129
*/
@@ -218,31 +216,18 @@ abstract contract HorizonStakingBase is
218216
return _delegationSlashingEnabled;
219217
}
220218

221-
/**
222-
* @notice Deposit tokens into the service provider stake.
223-
* @dev TRANSITION PERIOD: After transition period move to IHorizonStakingMain. Temporarily it
224-
* needs to be here since it's used by both {HorizonStaking} and {HorizonStakingExtension}.
225-
*
226-
* Emits a {HorizonStakeDeposited} event.
227-
* @param _serviceProvider The address of the service provider.
228-
* @param _tokens The amount of tokens to deposit.
229-
*/
230-
function _stake(address _serviceProvider, uint256 _tokens) internal {
231-
_serviceProviders[_serviceProvider].tokensStaked = _serviceProviders[_serviceProvider].tokensStaked + _tokens;
232-
emit HorizonStakeDeposited(_serviceProvider, _tokens);
233-
}
234-
235219
/**
236220
* @notice Gets the service provider's idle stake which is the stake that is not being
237221
* used for any provision. Note that this only includes service provider's self stake.
238-
* @dev Note that the calculation considers tokens that were locked in the legacy staking contract.
239-
* @dev TRANSITION PERIOD: update the calculation after the transition period.
222+
* @dev Note that the calculation:
223+
* - assumes tokens that were allocated to a subgraph deployment pre-horizon were all unallocated.
224+
* - considers tokens that were locked in the legacy staking contract and never withdrawn.
225+
*
240226
* @param _serviceProvider The address of the service provider.
241227
* @return The amount of tokens that are idle.
242228
*/
243229
function _getIdleStake(address _serviceProvider) internal view returns (uint256) {
244230
uint256 tokensUsed = _serviceProviders[_serviceProvider].tokensProvisioned +
245-
_serviceProviders[_serviceProvider].__DEPRECATED_tokensAllocated +
246231
_serviceProviders[_serviceProvider].__DEPRECATED_tokensLocked;
247232
uint256 tokensStaked = _serviceProviders[_serviceProvider].tokensStaked;
248233
return tokensStaked > tokensUsed ? tokensStaked - tokensUsed : 0;

0 commit comments

Comments
 (0)