Skip to content

Commit

Permalink
Merge pull request #1073 from graphprotocol/mde/trust-staking-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tmigone authored Dec 17, 2024
2 parents 0c0d090 + 399b7a9 commit 032e4a4
Show file tree
Hide file tree
Showing 26 changed files with 1,325 additions and 336 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ interface IHorizonStakingBase {
*/
event StakeDeposited(address indexed serviceProvider, uint256 tokens);

/**
* @notice Thrown when using an invalid thaw request type.
*/
error HorizonStakingInvalidThawRequestType();

/**
* @notice Gets the details of a service provider.
* @param serviceProvider The address of the service provider.
Expand Down Expand Up @@ -134,34 +139,46 @@ interface IHorizonStakingBase {

/**
* @notice Gets a thaw request.
* @param thawRequestType The type of thaw request.
* @param thawRequestId The id of the thaw request.
* @return The thaw request details.
*/
function getThawRequest(bytes32 thawRequestId) external view returns (IHorizonStakingTypes.ThawRequest memory);
function getThawRequest(
IHorizonStakingTypes.ThawRequestType thawRequestType,
bytes32 thawRequestId
) external view returns (IHorizonStakingTypes.ThawRequest memory);

/**
* @notice Gets the metadata of a thaw request list.
* Service provider and delegators each have their own thaw request list per provision.
* Metadata includes the head and tail of the list, plus the total number of thaw requests.
* @param thawRequestType The type of thaw request.
* @param serviceProvider The address of the service provider.
* @param verifier The address of the verifier.
* @param owner The owner of the thaw requests. Use either the service provider or delegator address.
* @return The thaw requests list metadata.
*/
function getThawRequestList(
IHorizonStakingTypes.ThawRequestType thawRequestType,
address serviceProvider,
address verifier,
address owner
) external view returns (LinkedList.List memory);

/**
* @notice Gets the amount of thawed tokens for a given provision.
* @param thawRequestType The type of thaw request.
* @param serviceProvider The address of the service provider.
* @param verifier The address of the verifier.
* @param owner The owner of the thaw requests. Use either the service provider or delegator address.
* @return The amount of thawed tokens.
*/
function getThawedTokens(address serviceProvider, address verifier, address owner) external view returns (uint256);
function getThawedTokens(
IHorizonStakingTypes.ThawRequestType thawRequestType,
address serviceProvider,
address verifier,
address owner
) external view returns (uint256);

/**
* @notice Gets the maximum allowed thawing period for a provision.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ interface IHorizonStakingExtension is IRewardsIssuer {
uint256 delegationRewards
);

/**
* @dev Emitted when `indexer` was slashed for a total of `tokens` amount.
* Tracks `reward` amount of tokens given to `beneficiary`.
*/
event StakeSlashed(address indexed indexer, uint256 tokens, uint256 reward, address beneficiary);

/**
* @notice Close an allocation and free the staked tokens.
* To be eligible for rewards a proof of indexing must be presented.
Expand Down Expand Up @@ -148,4 +154,14 @@ interface IHorizonStakingExtension is IRewardsIssuer {
*/
// solhint-disable-next-line func-name-mixedcase
function __DEPRECATED_getThawingPeriod() external view returns (uint64);

/**
* @notice Slash the indexer stake. Delegated tokens are not subject to slashing.
* @dev Can only be called by the slasher role.
* @param indexer Address of indexer to slash
* @param tokens Amount of tokens to slash from the indexer stake
* @param reward Amount of reward tokens to send to a beneficiary
* @param beneficiary Address of a beneficiary to receive a reward for the slashing
*/
function legacySlash(address indexer, uint256 tokens, uint256 reward, address beneficiary) external;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pragma solidity 0.8.27;

import { IGraphPayments } from "../../interfaces/IGraphPayments.sol";
import { IHorizonStakingTypes } from "./IHorizonStakingTypes.sol";

/**
* @title Inferface for the {HorizonStaking} contract.
Expand Down Expand Up @@ -205,6 +206,15 @@ interface IHorizonStakingMain {
uint256 tokens
);

/**
* @notice Emitted when `delegator` withdrew delegated `tokens` from `indexer` using `withdrawDelegated`.
* @dev This event is for the legacy `withdrawDelegated` function.
* @param indexer The address of the indexer
* @param delegator The address of the delegator
* @param tokens The amount of tokens withdrawn
*/
event StakeDelegatedWithdrawn(address indexed indexer, address indexed delegator, uint256 tokens);

/**
* @notice Emitted when tokens are added to a delegation pool's reserve.
* @param serviceProvider The address of the service provider
Expand Down Expand Up @@ -271,13 +281,15 @@ interface IHorizonStakingMain {
* @param owner The address of the owner of the thaw requests
* @param thawRequestsFulfilled The number of thaw requests fulfilled
* @param tokens The total amount of tokens being released
* @param requestType The type of thaw request
*/
event ThawRequestsFulfilled(
address indexed serviceProvider,
address indexed verifier,
address indexed owner,
uint256 thawRequestsFulfilled,
uint256 tokens
uint256 tokens,
IHorizonStakingTypes.ThawRequestType requestType
);

// -- Events: governance --
Expand All @@ -303,9 +315,8 @@ interface IHorizonStakingMain {

/**
* @notice Emitted when the delegation slashing global flag is set.
* @param enabled Whether delegation slashing is enabled or disabled.
*/
event DelegationSlashingEnabled(bool enabled);
event DelegationSlashingEnabled();

// -- Errors: tokens

Expand Down Expand Up @@ -415,6 +426,20 @@ interface IHorizonStakingMain {
*/
error HorizonStakingInvalidDelegationPool(address serviceProvider, address verifier);

/**
* @notice Thrown when the minimum token amount required for delegation is not met.
* @param tokens The actual token amount
* @param minTokens The minimum required token amount
*/
error HorizonStakingInsufficientDelegationTokens(uint256 tokens, uint256 minTokens);

/**
* @notice Thrown when the minimum token amount required for undelegation with beneficiary is not met.
* @param tokens The actual token amount
* @param minTokens The minimum required token amount
*/
error HorizonStakingInsufficientUndelegationTokens(uint256 tokens, uint256 minTokens);

/**
* @notice Thrown when attempting to undelegate with a beneficiary that is the zero address.
*/
Expand Down Expand Up @@ -515,6 +540,8 @@ interface IHorizonStakingMain {
* - During the transition period it's locked for a period of time before it can be withdrawn
* by calling {withdraw}.
* - After the transition period it's immediately withdrawn.
* Note that after the transition period if there are tokens still locked they will have to be
* withdrawn by calling {withdraw}.
* @dev Requirements:
* - `_tokens` cannot be zero.
* - `_serviceProvider` must have enough idle stake to cover the staking amount and any
Expand Down Expand Up @@ -747,7 +774,7 @@ interface IHorizonStakingMain {
* @param beneficiary The address where the tokens will be withdrawn after thawing
* @return The ID of the thaw request
*/
function undelegate(
function undelegateWithBeneficiary(
address serviceProvider,
address verifier,
uint256 shares,
Expand All @@ -772,6 +799,28 @@ interface IHorizonStakingMain {
*/
function withdrawDelegated(address serviceProvider, address verifier, uint256 nThawRequests) external;

/**
* @notice Withdraw undelegated with beneficiary tokens from a provision after thawing.
* @dev The parameter `nThawRequests` can be set to a non zero value to fulfill a specific number of thaw
* requests in the event that fulfilling all of them results in a gas limit error.
* @dev If the delegation pool was completely slashed before withdrawing, calling this function will fulfill
* the thaw requests with an amount equal to zero.
*
* Requirements:
* - Must have previously initiated a thaw request using {undelegateWithBeneficiary}.
*
* Emits {ThawRequestFulfilled}, {ThawRequestsFulfilled} and {DelegatedTokensWithdrawn} events.
*
* @param serviceProvider The service provider address
* @param verifier The verifier address
* @param nThawRequests The number of thaw requests to fulfill. Set to 0 to fulfill all thaw requests.
*/
function withdrawDelegatedWithBeneficiary(
address serviceProvider,
address verifier,
uint256 nThawRequests
) external;

/**
* @notice Re-delegate undelegated tokens from a provision after thawing to a `newServiceProvider` and `newVerifier`.
* @dev The parameter `nThawRequests` can be set to a non zero value to fulfill a specific number of thaw
Expand Down Expand Up @@ -838,13 +887,14 @@ interface IHorizonStakingMain {
/**
* @notice Withdraw undelegated tokens from the subgraph data service provision after thawing.
* This function is for backwards compatibility with the legacy staking contract.
* It only allows withdrawing from the subgraph data service and DOES NOT have slippage protection in
* case the caller opts for re-delegating.
* It only allows withdrawing tokens undelegated before horizon upgrade.
* @dev See {delegate}.
* @param serviceProvider The service provider address
* @param newServiceProvider The address of a new service provider, if the delegator wants to re-delegate
*/
function withdrawDelegated(address serviceProvider, address newServiceProvider) external;
function withdrawDelegated(
address serviceProvider,
address // newServiceProvider, deprecated
) external returns (uint256);

/**
* @notice Slash a service provider. This can only be called by a verifier to which
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ interface IHorizonStakingTypes {
uint256 __DEPRECATED_tokensLockedUntil;
}

/**
* @dev Enum to specify the type of thaw request.
* @param Provision Represents a thaw request for a provision.
* @param Delegation Represents a thaw request for a delegation.
*/
enum ThawRequestType {
Provision,
Delegation,
DelegationWithBeneficiary
}

/**
* @notice Details of a stake thawing operation.
* @dev ThawRequests are stored in linked lists by service provider/delegator,
Expand All @@ -146,4 +157,42 @@ interface IHorizonStakingTypes {
// Used to invalidate unfulfilled thaw requests
uint256 thawingNonce;
}

/**
* @notice Parameters to fulfill thaw requests.
* @dev This struct is used to avoid stack too deep error in the `fulfillThawRequests` function.
* @param requestType The type of thaw request (Provision or Delegation)
* @param serviceProvider The address of the service provider
* @param verifier The address of the verifier
* @param owner The address of the owner of the thaw request
* @param tokensThawing The current amount of tokens already thawing
* @param sharesThawing The current amount of shares already thawing
* @param nThawRequests The number of thaw requests to fulfill. If set to 0, all thaw requests are fulfilled.
* @param thawingNonce The current valid thawing nonce. Any thaw request with a different nonce is invalid and should be ignored.
*/
struct FulfillThawRequestsParams {
ThawRequestType requestType;
address serviceProvider;
address verifier;
address owner;
uint256 tokensThawing;
uint256 sharesThawing;
uint256 nThawRequests;
uint256 thawingNonce;
}

/**
* @notice Results of the traversal of thaw requests.
* @dev This struct is used to avoid stack too deep error in the `fulfillThawRequests` function.
* @param requestsFulfilled The number of thaw requests fulfilled
* @param tokensThawed The total amount of tokens thawed
* @param tokensThawing The total amount of tokens thawing
* @param sharesThawing The total amount of shares thawing
*/
struct TraverseThawRequestsResults {
uint256 requestsFulfilled;
uint256 tokensThawed;
uint256 tokensThawing;
uint256 sharesThawing;
}
}
Loading

0 comments on commit 032e4a4

Please sign in to comment.