Skip to content

Commit

Permalink
[WIP] Horizon Staking (#967)
Browse files Browse the repository at this point in the history
* chore(horizon): add staking contract and others (WIP)

* chore: fix errors until it compiles

* fix: add missing IL2StakingTypes

* chore: wip on splitting for code size

* chore: somehow it fits in 24kB now

* chore: remove global operators and the verifier allowlist

* fix: various fixes and a bit of cleanup

* chore: slippage protection for delegation

* chore: add setter for delegation cuts

* chore: add getter for delegation cuts

* fix: reintroduce early alloc closure

* chore: add support for vesting contracts

* fix: various missing things

* chore: add OZ contracts

* chore: add setOperatorLocked

* chore: use delegation ratio in getTokensAvailable

* fix: allow changing provision params

* fix: remove verifier cut from tokens to slash
  • Loading branch information
pcarranzav authored May 17, 2024
1 parent 2585495 commit a94a455
Show file tree
Hide file tree
Showing 44 changed files with 3,416 additions and 244 deletions.
2 changes: 1 addition & 1 deletion packages/contracts/contracts/base/IMulticall.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;
pragma abicoder v2;

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/base/Multicall.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity ^0.7.6 || 0.8.24;
pragma abicoder v2;

import "./IMulticall.sol";
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/curation/ICuration.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;

/**
* @title Curation Interface
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/epochs/IEpochManager.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;

interface IEpochManager {
// -- Configuration --
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/gateway/ICallhookReceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* be allowlisted by the governor, but also implement this interface that contains
* the function that will actually be called by the L2GraphTokenGateway.
*/
pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;

interface ICallhookReceiver {
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/governance/IController.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.6.12 <0.8.0;
pragma solidity >=0.6.12 <0.9.0;

interface IController {
function getGovernor() external view returns (address);
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/governance/IManaged.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;

import { IController } from "./IController.sol";

Expand Down
20 changes: 2 additions & 18 deletions packages/contracts/contracts/l2/staking/IL2Staking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pragma abicoder v2;

import { IStaking } from "../../staking/IStaking.sol";
import { IL2StakingBase } from "./IL2StakingBase.sol";
import { IL2StakingTypes } from "./IL2StakingTypes.sol";

/**
* @title Interface for the L2 Staking contract
Expand All @@ -15,21 +16,4 @@ import { IL2StakingBase } from "./IL2StakingBase.sol";
* the custom setup of the Staking contract where part of the functionality is implemented
* in a separate contract (StakingExtension) to which calls are delegated through the fallback function.
*/
interface IL2Staking is IStaking, IL2StakingBase {
/// @dev Message codes for the L1 -> L2 bridge callhook
enum L1MessageCodes {
RECEIVE_INDEXER_STAKE_CODE,
RECEIVE_DELEGATION_CODE
}

/// @dev Encoded message struct when receiving indexer stake through the bridge
struct ReceiveIndexerStakeData {
address indexer;
}

/// @dev Encoded message struct when receiving delegation through the bridge
struct ReceiveDelegationData {
address indexer;
address delegator;
}
}
interface IL2Staking is IStaking, IL2StakingBase, IL2StakingTypes {}
2 changes: 1 addition & 1 deletion packages/contracts/contracts/l2/staking/IL2StakingBase.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;

import { ICallhookReceiver } from "../../gateway/ICallhookReceiver.sol";

Expand Down
22 changes: 22 additions & 0 deletions packages/contracts/contracts/l2/staking/IL2StakingTypes.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.6.12 <0.9.0;

interface IL2StakingTypes {
/// @dev Message codes for the L1 -> L2 bridge callhook
enum L1MessageCodes {
RECEIVE_INDEXER_STAKE_CODE,
RECEIVE_DELEGATION_CODE
}

/// @dev Encoded message struct when receiving indexer stake through the bridge
struct ReceiveIndexerStakeData {
address indexer;
}

/// @dev Encoded message struct when receiving delegation through the bridge
struct ReceiveDelegationData {
address indexer;
address delegator;
}
}
23 changes: 15 additions & 8 deletions packages/contracts/contracts/l2/staking/L2Staking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Staking } from "../../staking/Staking.sol";
import { IL2StakingBase } from "./IL2StakingBase.sol";
import { IL2Staking } from "./IL2Staking.sol";
import { Stakes } from "../../staking/libs/Stakes.sol";
import { IL2StakingTypes } from "./IL2StakingTypes.sol";

/**
* @title L2Staking contract
Expand Down Expand Up @@ -63,16 +64,16 @@ contract L2Staking is Staking, IL2StakingBase {
require(_from == counterpartStakingAddress, "ONLY_L1_STAKING_THROUGH_BRIDGE");
(uint8 code, bytes memory functionData) = abi.decode(_data, (uint8, bytes));

if (code == uint8(IL2Staking.L1MessageCodes.RECEIVE_INDEXER_STAKE_CODE)) {
IL2Staking.ReceiveIndexerStakeData memory indexerData = abi.decode(
if (code == uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_INDEXER_STAKE_CODE)) {
IL2StakingTypes.ReceiveIndexerStakeData memory indexerData = abi.decode(
functionData,
(IL2Staking.ReceiveIndexerStakeData)
(IL2StakingTypes.ReceiveIndexerStakeData)
);
_receiveIndexerStake(_amount, indexerData);
} else if (code == uint8(IL2Staking.L1MessageCodes.RECEIVE_DELEGATION_CODE)) {
IL2Staking.ReceiveDelegationData memory delegationData = abi.decode(
} else if (code == uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_DELEGATION_CODE)) {
IL2StakingTypes.ReceiveDelegationData memory delegationData = abi.decode(
functionData,
(IL2Staking.ReceiveDelegationData)
(IL2StakingTypes.ReceiveDelegationData)
);
_receiveDelegation(_amount, delegationData);
} else {
Expand All @@ -87,7 +88,10 @@ contract L2Staking is Staking, IL2StakingBase {
* @param _amount Amount of tokens that were transferred
* @param _indexerData struct containing the indexer's address
*/
function _receiveIndexerStake(uint256 _amount, IL2Staking.ReceiveIndexerStakeData memory _indexerData) internal {
function _receiveIndexerStake(
uint256 _amount,
IL2StakingTypes.ReceiveIndexerStakeData memory _indexerData
) internal {
address _indexer = _indexerData.indexer;
// Deposit tokens into the indexer stake
__stakes[_indexer].deposit(_amount);
Expand All @@ -108,7 +112,10 @@ contract L2Staking is Staking, IL2StakingBase {
* @param _amount Amount of tokens that were transferred
* @param _delegationData struct containing the delegator's address and the indexer's address
*/
function _receiveDelegation(uint256 _amount, IL2Staking.ReceiveDelegationData memory _delegationData) internal {
function _receiveDelegation(
uint256 _amount,
IL2StakingTypes.ReceiveDelegationData memory _delegationData
) internal {
// Get the delegation pool of the indexer
DelegationPool storage pool = __delegationPools[_delegationData.indexer];
Delegation storage delegation = pool.delegators[_delegationData.delegator];
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/rewards/IRewardsManager.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;

interface IRewardsManager {
/**
Expand Down
149 changes: 0 additions & 149 deletions packages/contracts/contracts/staking/IHorizonStaking.sol

This file was deleted.

13 changes: 8 additions & 5 deletions packages/contracts/contracts/staking/L1Staking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import { ITokenGateway } from "../arbitrum/ITokenGateway.sol";
import { Staking } from "./Staking.sol";
import { Stakes } from "./libs/Stakes.sol";
import { IStakingData } from "./IStakingData.sol";
import { IL2Staking } from "../l2/staking/IL2Staking.sol";
import { L1StakingV1Storage } from "./L1StakingStorage.sol";
import { IGraphToken } from "../token/IGraphToken.sol";
import { IL1StakingBase } from "./IL1StakingBase.sol";
import { MathUtils } from "./libs/MathUtils.sol";
import { IL1GraphTokenLockTransferTool } from "./IL1GraphTokenLockTransferTool.sol";
import { IL2StakingTypes } from "../l2/staking/IL2StakingTypes.sol";

/**
* @title L1Staking contract
Expand Down Expand Up @@ -267,11 +267,11 @@ contract L1Staking is Staking, L1StakingV1Storage, IL1StakingBase {
);
}

IL2Staking.ReceiveIndexerStakeData memory functionData;
IL2StakingTypes.ReceiveIndexerStakeData memory functionData;
functionData.indexer = _l2Beneficiary;

bytes memory extraData = abi.encode(
uint8(IL2Staking.L1MessageCodes.RECEIVE_INDEXER_STAKE_CODE),
uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_INDEXER_STAKE_CODE),
abi.encode(functionData)
);

Expand Down Expand Up @@ -324,10 +324,13 @@ contract L1Staking is Staking, L1StakingV1Storage, IL1StakingBase {
delegation.shares = 0;
bytes memory extraData;
{
IL2Staking.ReceiveDelegationData memory functionData;
IL2StakingTypes.ReceiveDelegationData memory functionData;
functionData.indexer = indexerTransferredToL2[_indexer];
functionData.delegator = _l2Beneficiary;
extraData = abi.encode(uint8(IL2Staking.L1MessageCodes.RECEIVE_DELEGATION_CODE), abi.encode(functionData));
extraData = abi.encode(
uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_DELEGATION_CODE),
abi.encode(functionData)
);
}

_sendTokensAndMessageToL2Staking(
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/upgrades/GraphUpgradeable.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity ^0.7.6 || 0.8.24;

import { IGraphProxy } from "./IGraphProxy.sol";

Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/upgrades/IGraphProxy.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.6.12 <0.9.0;

interface IGraphProxy {
function admin() external returns (address);
Expand Down
Loading

0 comments on commit a94a455

Please sign in to comment.