Skip to content

Commit

Permalink
chore: reduce contract sizes to fit 24kb HorizonStaking and SubgraphS…
Browse files Browse the repository at this point in the history
…ervice
  • Loading branch information
Maikol committed Jan 28, 2025
1 parent 4799228 commit 7db331d
Show file tree
Hide file tree
Showing 10 changed files with 5 additions and 249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -433,18 +433,6 @@ interface IHorizonStakingMain {
*/
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.
*/
error HorizonStakingInvalidBeneficiaryZeroAddress();

/**
* @notice Thrown when attempting to redelegate with a serivce provider that is the zero address.
*/
Expand Down Expand Up @@ -754,33 +742,6 @@ interface IHorizonStakingMain {
*/
function undelegate(address serviceProvider, address verifier, uint256 shares) external returns (bytes32);

/**
* @notice Undelegate tokens from a provision and start thawing them.
* The tokens will be withdrawable by the `beneficiary` after the thawing period.
*
* Note that undelegating tokens from a provision is a two step process:
* - First the tokens are thawed using this function.
* - Then after the thawing period, the tokens are removed from the provision using {withdrawDelegated}.
*
* Requirements:
* - `shares` cannot be zero.
* - `beneficiary` cannot be the zero address.
*
* Emits a {TokensUndelegated} and {ThawRequestCreated} event.
*
* @param serviceProvider The service provider address
* @param verifier The verifier address
* @param shares The amount of shares to undelegate
* @param beneficiary The address where the tokens will be withdrawn after thawing
* @return The ID of the thaw request
*/
// function undelegateWithBeneficiary(
// address serviceProvider,
// address verifier,
// uint256 shares,
// address beneficiary
// ) external returns (bytes32);

/**
* @notice Withdraw undelegated 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
Expand All @@ -799,28 +760,6 @@ 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
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ interface IHorizonStakingTypes {
*/
enum ThawRequestType {
Provision,
Delegation,
DelegationWithBeneficiary
Delegation
}

/**
Expand Down
55 changes: 0 additions & 55 deletions packages/horizon/contracts/staking/HorizonStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
/// @dev Minimum amount of delegation.
uint256 private constant MIN_DELEGATION = 1e18;

/// @dev Minimum amount of undelegation with beneficiary.
uint256 private constant MIN_UNDELEGATION_WITH_BENEFICIARY = 10e18;

/**
* @notice Checks that the caller is authorized to operate over a provision.
* @param serviceProvider The address of the service provider.
Expand Down Expand Up @@ -307,19 +304,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
return _undelegate(ThawRequestType.Delegation, serviceProvider, verifier, shares, msg.sender);
}

/**
* @notice See {IHorizonStakingMain-undelegate}.
*/
// function undelegateWithBeneficiary(
// address serviceProvider,
// address verifier,
// uint256 shares,
// address beneficiary
// ) external override notPaused returns (bytes32) {
// require(beneficiary != address(0), HorizonStakingInvalidBeneficiaryZeroAddress());
// return _undelegate(ThawRequestType.DelegationWithBeneficiary, serviceProvider, verifier, shares, beneficiary);
// }

/**
* @notice See {IHorizonStakingMain-withdrawDelegated}.
*/
Expand All @@ -339,25 +323,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
);
}

/**
* @notice See {IHorizonStakingMain-withdrawDelegatedWithBeneficiary}.
*/
// function withdrawDelegatedWithBeneficiary(
// address serviceProvider,
// address verifier,
// uint256 nThawRequests
// ) external override notPaused {
// _withdrawDelegated(
// ThawRequestType.DelegationWithBeneficiary,
// serviceProvider,
// verifier,
// address(0),
// address(0),
// 0,
// nThawRequests
// );
// }

/**
* @notice See {IHorizonStakingMain-redelegate}.
*/
Expand Down Expand Up @@ -935,16 +900,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
// Thawing pool is reset/initialized when the pool is empty: prov.tokensThawing == 0
uint256 tokens = (_shares * (pool.tokens - pool.tokensThawing)) / pool.shares;

// Since anyone can undelegate for any beneficiary, we require a minimum amount to prevent
// malicious actors from flooding the thaw request list with tiny amounts and causing a
// denial of service attack by hitting the MAX_THAW_REQUESTS limit
if (_requestType == ThawRequestType.DelegationWithBeneficiary) {
require(
tokens >= MIN_UNDELEGATION_WITH_BENEFICIARY,
HorizonStakingInsufficientUndelegationTokens(tokens, MIN_UNDELEGATION_WITH_BENEFICIARY)
);
}

// Thawing shares are rounded down to protect the pool and avoid taking extra tokens from other participants.
uint256 thawingShares = pool.tokensThawing == 0 ? tokens : ((tokens * pool.sharesThawing) / pool.tokensThawing);
uint64 thawingUntil = uint64(block.timestamp + uint256(_provisions[_serviceProvider][_verifier].thawingPeriod));
Expand Down Expand Up @@ -1208,8 +1163,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
return _deleteProvisionThawRequest;
} else if (_requestType == ThawRequestType.Delegation) {
return _deleteDelegationThawRequest;
} else if (_requestType == ThawRequestType.DelegationWithBeneficiary) {
return _deleteDelegationWithBeneficiaryThawRequest;
} else {
revert HorizonStakingInvalidThawRequestType();
}
Expand All @@ -1231,14 +1184,6 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
delete _thawRequests[ThawRequestType.Delegation][_thawRequestId];
}

/**
* @notice Deletes a thaw request for a delegation with a beneficiary.
* @param _thawRequestId The ID of the thaw request to delete.
*/
function _deleteDelegationWithBeneficiaryThawRequest(bytes32 _thawRequestId) private {
delete _thawRequests[ThawRequestType.DelegationWithBeneficiary][_thawRequestId];
}

/**
* @notice See {IHorizonStakingMain-setOperator}.
* @dev Note that this function handles the special case where the verifier is the subgraph data service,
Expand Down
11 changes: 0 additions & 11 deletions packages/horizon/contracts/staking/HorizonStakingBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,6 @@ abstract contract HorizonStakingBase is
return _getNextProvisionThawRequest;
} else if (_requestType == ThawRequestType.Delegation) {
return _getNextDelegationThawRequest;
} else if (_requestType == ThawRequestType.DelegationWithBeneficiary) {
return _getNextDelegationWithBeneficiaryThawRequest;
} else {
revert HorizonStakingInvalidThawRequestType();
}
Expand All @@ -335,15 +333,6 @@ abstract contract HorizonStakingBase is
return _thawRequests[ThawRequestType.Delegation][_thawRequestId].next;
}

/**
* @notice Retrieves the next thaw request for a delegation with a beneficiary.
* @param _thawRequestId The ID of the current thaw request.
* @return The ID of the next thaw request in the list.
*/
function _getNextDelegationWithBeneficiaryThawRequest(bytes32 _thawRequestId) internal view returns (bytes32) {
return _thawRequests[ThawRequestType.DelegationWithBeneficiary][_thawRequestId].next;
}

/**
* @notice Retrieves the thaw request list for the given request type.
* @dev Uses the `ThawRequestType` to determine which mapping to access.
Expand Down
2 changes: 1 addition & 1 deletion packages/horizon/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ test = 'test'
cache_path = 'cache_forge'
fs_permissions = [{ access = "read", path = "./"}]
optimizer = true
optimizer_runs = 200
optimizer_runs = 50
Original file line number Diff line number Diff line change
Expand Up @@ -908,17 +908,6 @@ abstract contract HorizonStakingSharedTest is GraphBaseTest {
__undelegate(IHorizonStakingTypes.ThawRequestType.Delegation, serviceProvider, verifier, shares, false, caller);
}

function _undelegateWithBeneficiary(address serviceProvider, address verifier, uint256 shares, address beneficiary) internal {
__undelegate(
IHorizonStakingTypes.ThawRequestType.DelegationWithBeneficiary,
serviceProvider,
verifier,
shares,
false,
beneficiary
);
}

function _undelegate(address serviceProvider, uint256 shares) internal {
(, address caller, ) = vm.readCallers();
__undelegate(
Expand Down Expand Up @@ -992,8 +981,6 @@ abstract contract HorizonStakingSharedTest is GraphBaseTest {
staking.undelegate(serviceProvider, shares);
} else if (thawRequestType == IHorizonStakingTypes.ThawRequestType.Delegation) {
staking.undelegate(serviceProvider, verifier, shares);
} else if (thawRequestType == IHorizonStakingTypes.ThawRequestType.DelegationWithBeneficiary) {
staking.undelegateWithBeneficiary(serviceProvider, verifier, shares, beneficiary);
} else {
revert("Invalid thaw request type");
}
Expand Down Expand Up @@ -1053,24 +1040,6 @@ abstract contract HorizonStakingSharedTest is GraphBaseTest {
__withdrawDelegated(params);
}

function _withdrawDelegatedWithBeneficiary(
address serviceProvider,
address verifier,
uint256 nThawRequests
) internal {
Params_WithdrawDelegated memory params = Params_WithdrawDelegated({
thawRequestType: IHorizonStakingTypes.ThawRequestType.DelegationWithBeneficiary,
serviceProvider: serviceProvider,
verifier: verifier,
newServiceProvider: address(0),
newVerifier: address(0),
minSharesForNewProvider: 0,
nThawRequests: nThawRequests,
legacy: false
});
__withdrawDelegated(params);
}

function _redelegate(
address serviceProvider,
address verifier,
Expand Down Expand Up @@ -1197,8 +1166,6 @@ abstract contract HorizonStakingSharedTest is GraphBaseTest {
);
} else if (params.thawRequestType == IHorizonStakingTypes.ThawRequestType.Delegation) {
staking.withdrawDelegated(params.serviceProvider, params.verifier, params.nThawRequests);
} else if (params.thawRequestType == IHorizonStakingTypes.ThawRequestType.DelegationWithBeneficiary) {
staking.withdrawDelegatedWithBeneficiary(params.serviceProvider, params.verifier, params.nThawRequests);
} else {
revert("Invalid thaw request type");
}
Expand Down
23 changes: 0 additions & 23 deletions packages/horizon/test/staking/delegation/undelegate.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,6 @@ contract HorizonStakingUndelegateTest is HorizonStakingTest {
_undelegate(users.indexer, subgraphDataServiceAddress, delegation.shares);
}

function testUndelegate_WithBeneficiary(
uint256 amount,
uint256 delegationAmount,
address beneficiary
) public useIndexer useProvision(amount, 0, 0) useDelegation(delegationAmount) {
vm.assume(beneficiary != address(0));
vm.assume(delegationAmount >= MIN_UNDELEGATION_WITH_BENEFICIARY);
resetPrank(users.delegator);
DelegationInternal memory delegation = _getStorage_Delegation(users.indexer, subgraphDataServiceAddress, users.delegator, false);
_undelegateWithBeneficiary(users.indexer, subgraphDataServiceAddress, delegation.shares, beneficiary);
}

function testUndelegate_RevertWhen_InsuficientTokens(
uint256 amount,
uint256 delegationAmount,
Expand Down Expand Up @@ -255,15 +243,4 @@ contract HorizonStakingUndelegateTest is HorizonStakingTest {
resetPrank(users.delegator);
_undelegate(users.indexer, subgraphDataServiceAddress, delegation.shares - delegation.shares / 2);
}

function testUndelegate_RevertIf_BeneficiaryIsZero(
uint256 amount,
uint256 delegationAmount
) public useIndexer useProvision(amount, 0, 0) useDelegation(delegationAmount) {
resetPrank(users.delegator);
DelegationInternal memory delegation = _getStorage_Delegation(users.indexer, subgraphDataServiceAddress, users.delegator, false);
bytes memory expectedError = abi.encodeWithSelector(IHorizonStakingMain.HorizonStakingInvalidBeneficiaryZeroAddress.selector);
vm.expectRevert(expectedError);
staking.undelegateWithBeneficiary(users.indexer, subgraphDataServiceAddress, delegation.shares, address(0));
}
}
59 changes: 0 additions & 59 deletions packages/horizon/test/staking/delegation/withdraw.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -155,63 +155,4 @@ contract HorizonStakingWithdrawDelegationTest is HorizonStakingTest {
resetPrank(users.delegator);
_withdrawDelegated(users.indexer, subgraphDataServiceAddress, 0);
}

function testWithdrawDelegation_WithBeneficiary(
uint256 delegationAmount,
address beneficiary
)
public
useIndexer
useProvision(10_000_000 ether, 0, MAX_THAWING_PERIOD)
useDelegation(delegationAmount)
{
vm.assume(beneficiary != address(0));
vm.assume(beneficiary != address(staking));
vm.assume(delegationAmount >= MIN_UNDELEGATION_WITH_BENEFICIARY);
// Skip beneficiary if balance will overflow
vm.assume(token.balanceOf(beneficiary) < type(uint256).max - delegationAmount);

// Delegator undelegates to beneficiary
resetPrank(users.delegator);
DelegationInternal memory delegation = _getStorage_Delegation(users.indexer, subgraphDataServiceAddress, users.delegator, false);
_undelegateWithBeneficiary(users.indexer, subgraphDataServiceAddress, delegation.shares, beneficiary);

// Thawing period ends
LinkedList.List memory thawingRequests = staking.getThawRequestList(IHorizonStakingTypes.ThawRequestType.Delegation, users.indexer, subgraphDataServiceAddress, beneficiary);
ThawRequest memory thawRequest = staking.getThawRequest(IHorizonStakingTypes.ThawRequestType.Delegation, thawingRequests.tail);
skip(thawRequest.thawingUntil + 1);

// Beneficiary withdraws delegated tokens
resetPrank(beneficiary);
_withdrawDelegatedWithBeneficiary(users.indexer, subgraphDataServiceAddress, 1);
}

function testWithdrawDelegation_RevertWhen_PreviousOwnerAttemptsToWithdraw(
uint256 delegationAmount,
address beneficiary
)
public
useIndexer
useProvision(10_000_000 ether, 0, MAX_THAWING_PERIOD)
useDelegation(delegationAmount)
{
vm.assume(beneficiary != address(0));
vm.assume(beneficiary != users.delegator);
vm.assume(delegationAmount >= MIN_UNDELEGATION_WITH_BENEFICIARY);

// Delegator undelegates to beneficiary
resetPrank(users.delegator);
DelegationInternal memory delegation = _getStorage_Delegation(users.indexer, subgraphDataServiceAddress, users.delegator, false);
_undelegateWithBeneficiary(users.indexer, subgraphDataServiceAddress, delegation.shares, beneficiary);

// Thawing period ends
LinkedList.List memory thawingRequests = staking.getThawRequestList(IHorizonStakingTypes.ThawRequestType.Delegation, users.indexer, subgraphDataServiceAddress, users.delegator);
ThawRequest memory thawRequest = staking.getThawRequest(IHorizonStakingTypes.ThawRequestType.Delegation, thawingRequests.tail);
skip(thawRequest.thawingUntil + 1);

// Delegator attempts to withdraw delegated tokens, should revert since beneficiary is the thaw request owner
bytes memory expectedError = abi.encodeWithSelector(IHorizonStakingMain.HorizonStakingNothingThawing.selector);
vm.expectRevert(expectedError);
staking.withdrawDelegated(users.indexer, subgraphDataServiceAddress, 1);
}
}
1 change: 0 additions & 1 deletion packages/horizon/test/utils/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ abstract contract Constants {
uint64 internal constant MAX_THAWING_PERIOD = 28 days;
uint32 internal constant THAWING_PERIOD_IN_BLOCKS = 300;
uint256 internal constant MIN_DELEGATION = 1e18;
uint256 internal constant MIN_UNDELEGATION_WITH_BENEFICIARY = 10e18;
// Epoch manager
uint256 internal constant EPOCH_LENGTH = 1;
// Rewards manager
Expand Down
Loading

0 comments on commit 7db331d

Please sign in to comment.