Skip to content

Commit e1d173d

Browse files
committed
chore: added script to migrate protocol contracts to Horizon
1 parent 1038cf4 commit e1d173d

22 files changed

+929
-142
lines changed

packages/horizon/contracts/interfaces/internal/IHorizonStakingMain.sol

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -774,12 +774,12 @@ interface IHorizonStakingMain {
774774
* @param beneficiary The address where the tokens will be withdrawn after thawing
775775
* @return The ID of the thaw request
776776
*/
777-
function undelegateWithBeneficiary(
778-
address serviceProvider,
779-
address verifier,
780-
uint256 shares,
781-
address beneficiary
782-
) external returns (bytes32);
777+
// function undelegateWithBeneficiary(
778+
// address serviceProvider,
779+
// address verifier,
780+
// uint256 shares,
781+
// address beneficiary
782+
// ) external returns (bytes32);
783783

784784
/**
785785
* @notice Withdraw undelegated tokens from a provision after thawing.
@@ -815,11 +815,11 @@ interface IHorizonStakingMain {
815815
* @param verifier The verifier address
816816
* @param nThawRequests The number of thaw requests to fulfill. Set to 0 to fulfill all thaw requests.
817817
*/
818-
function withdrawDelegatedWithBeneficiary(
819-
address serviceProvider,
820-
address verifier,
821-
uint256 nThawRequests
822-
) external;
818+
// function withdrawDelegatedWithBeneficiary(
819+
// address serviceProvider,
820+
// address verifier,
821+
// uint256 nThawRequests
822+
// ) external;
823823

824824
/**
825825
* @notice Re-delegate undelegated tokens from a provision after thawing to a `newServiceProvider` and `newVerifier`.

packages/horizon/contracts/staking/HorizonStaking.sol

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -310,15 +310,15 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
310310
/**
311311
* @notice See {IHorizonStakingMain-undelegate}.
312312
*/
313-
function undelegateWithBeneficiary(
314-
address serviceProvider,
315-
address verifier,
316-
uint256 shares,
317-
address beneficiary
318-
) external override notPaused returns (bytes32) {
319-
require(beneficiary != address(0), HorizonStakingInvalidBeneficiaryZeroAddress());
320-
return _undelegate(ThawRequestType.DelegationWithBeneficiary, serviceProvider, verifier, shares, beneficiary);
321-
}
313+
// function undelegateWithBeneficiary(
314+
// address serviceProvider,
315+
// address verifier,
316+
// uint256 shares,
317+
// address beneficiary
318+
// ) external override notPaused returns (bytes32) {
319+
// require(beneficiary != address(0), HorizonStakingInvalidBeneficiaryZeroAddress());
320+
// return _undelegate(ThawRequestType.DelegationWithBeneficiary, serviceProvider, verifier, shares, beneficiary);
321+
// }
322322

323323
/**
324324
* @notice See {IHorizonStakingMain-withdrawDelegated}.
@@ -342,21 +342,21 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
342342
/**
343343
* @notice See {IHorizonStakingMain-withdrawDelegatedWithBeneficiary}.
344344
*/
345-
function withdrawDelegatedWithBeneficiary(
346-
address serviceProvider,
347-
address verifier,
348-
uint256 nThawRequests
349-
) external override notPaused {
350-
_withdrawDelegated(
351-
ThawRequestType.DelegationWithBeneficiary,
352-
serviceProvider,
353-
verifier,
354-
address(0),
355-
address(0),
356-
0,
357-
nThawRequests
358-
);
359-
}
345+
// function withdrawDelegatedWithBeneficiary(
346+
// address serviceProvider,
347+
// address verifier,
348+
// uint256 nThawRequests
349+
// ) external override notPaused {
350+
// _withdrawDelegated(
351+
// ThawRequestType.DelegationWithBeneficiary,
352+
// serviceProvider,
353+
// verifier,
354+
// address(0),
355+
// address(0),
356+
// 0,
357+
// nThawRequests
358+
// );
359+
// }
360360

361361
/**
362362
* @notice See {IHorizonStakingMain-redelegate}.

packages/horizon/hardhat.config.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
import '@nomicfoundation/hardhat-foundry'
22
import '@nomicfoundation/hardhat-toolbox'
33
import '@nomicfoundation/hardhat-ignition-ethers'
4+
import '@tenderly/hardhat-tenderly'
45
import 'hardhat-storage-layout'
56
import 'hardhat-contract-sizer'
67
import 'hardhat-secure-accounts'
8+
import * as dotenv from 'dotenv'
79

810
import type { HardhatUserConfig } from 'hardhat/config'
911

12+
dotenv.config()
13+
14+
const getNetworkAccounts = () => {
15+
const accounts: string[] = []
16+
if (process.env.DEPLOYER_PRIVATE_KEY) accounts.push(process.env.DEPLOYER_PRIVATE_KEY)
17+
if (process.env.GOVERNOR_PRIVATE_KEY) accounts.push(process.env.GOVERNOR_PRIVATE_KEY)
18+
return accounts.length > 0 ? accounts : undefined
19+
}
20+
1021
if (process.env.BUILD_RUN !== 'true') {
1122
require('hardhat-graph-protocol')
1223
}
@@ -17,7 +28,7 @@ const config: HardhatUserConfig = {
1728
settings: {
1829
optimizer: {
1930
enabled: true,
20-
runs: 200,
31+
runs: 1,
2132
},
2233
},
2334
},
@@ -41,6 +52,18 @@ const config: HardhatUserConfig = {
4152
chainId: 421614,
4253
url: 'https://sepolia-rollup.arbitrum.io/rpc',
4354
},
55+
arbitrumVirtualTestnet: {
56+
secureAccounts: {
57+
enabled: false,
58+
},
59+
chainId: 421615,
60+
url: process.env.ARBITRUM_VIRTUAL_TESTNET_URL || '',
61+
accounts: getNetworkAccounts(),
62+
},
63+
},
64+
tenderly: {
65+
project: 'graph-network',
66+
username: 'graphprotocol',
4467
},
4568
graph: {
4669
deployments: {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"$global": {
3+
"isMigrate": true,
4+
"graphProxyAdminAddress": "0x7474a6cc5fAeDEc620Db0fa8E4da6eD58477042C",
5+
"controllerAddress": "0x9DB3ee191681f092607035d9BDA6e59FbEaCa695",
6+
"horizonStakingProxyAddress": "0x865365C425f3A593Ffe698D9c4E6707D14d51e08",
7+
"bridgeEscrowProxyAddress": "0x428Ab6E9EeF41Dc5098a34a6993Cdd5Be5BA24a6",
8+
"epochManagerProxyAddress": "0x88b3C7f37253bAA1A9b95feAd69bD5320585826D",
9+
"graphTokenProxyAddress": "0xf8c05dCF59E8B28BFD5eed176C562bEbcfc7Ac04",
10+
"graphTokenGatewayProxyAddress": "0xB24Ce0f8c18c4DdDa584A7EeC132F49C966813bb",
11+
// Placeholder address for a standalone Horizon deployment, see README.md for more details
12+
"subgraphServiceAddress": "0x0000000000000000000000000000000000000000"
13+
},
14+
"RewardsManager": {
15+
"rewardsManagerProxyAddress": "0x1F49caE7669086c8ba53CC35d1E9f80176d67E79"
16+
},
17+
"Curation": {
18+
"graphCurationProxyAddress": "0xDe761f075200E75485F4358978FB4d1dC8644FD5"
19+
},
20+
"HorizonStaking": {
21+
"maxThawingPeriod": 2419200
22+
},
23+
"GraphPayments": {
24+
"protocolPaymentCut": 10000
25+
},
26+
"PaymentsEscrow": {
27+
"withdrawEscrowThawingPeriod": 10000
28+
},
29+
"TAPCollector": {
30+
"eip712Name": "TAPCollector",
31+
"eip712Version": "1",
32+
"revokeSignerThawingPeriod": 10000
33+
}
34+
}

packages/horizon/ignition/configs/horizon.hardhat.json5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"$global": {
3+
"isMigrate": false,
34
"governor": "0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0",
45
"pauseGuardian": "0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC",
56
"subgraphAvailabilityOracle": "0xd03ea8624C8C5987235048901fB614fDcA89b117",

packages/horizon/ignition/modules/core/GraphPayments.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ export default buildModule('GraphPayments', (m) => {
2727
// Load contract with implementation ABI
2828
const GraphPayments = m.contractAt('GraphPayments', GraphPaymentsArtifact, GraphPaymentsProxy, { id: 'GraphPayments_Instance' })
2929

30-
return { GraphPayments }
30+
return { GraphPayments, GraphPaymentsImplementation }
3131
})

packages/horizon/ignition/modules/core/HorizonProxies.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,28 @@ export default buildModule('HorizonProxies', (m) => {
1616
const { Controller, PeripheryRegistered } = m.useModule(GraphPeripheryModule)
1717
const { GraphProxyAdmin } = m.useModule(GraphProxyAdminModule)
1818

19+
const isMigrate = m.getParameter('isMigrate', false)
20+
1921
// Deploy HorizonStaking proxy without an implementation
20-
const HorizonStakingProxy = m.contract('GraphProxy', GraphProxyArtifact, [ZERO_ADDRESS, GraphProxyAdmin], { after: [PeripheryRegistered], id: 'GraphProxy_HorizonStaking' })
22+
let HorizonStakingProxy, setProxyHorizonStaking
23+
if (isMigrate) {
24+
const horizonStakingProxyAddress = m.getParameter('horizonStakingProxyAddress')
25+
HorizonStakingProxy = m.contractAt('GraphProxy', GraphProxyArtifact, horizonStakingProxyAddress, { id: 'GraphProxy_HorizonStaking' })
26+
setProxyHorizonStaking = HorizonStakingProxy
27+
} else {
28+
HorizonStakingProxy = m.contract('GraphProxy', GraphProxyArtifact, [ZERO_ADDRESS, GraphProxyAdmin], { after: [PeripheryRegistered], id: 'GraphProxy_HorizonStaking' })
29+
setProxyHorizonStaking = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('Staking')), HorizonStakingProxy], { id: 'setContractProxy_HorizonStaking' })
30+
}
2131

2232
// Deploy proxies for payments contracts using OZ TransparentUpgradeableProxy
2333
const { Proxy: GraphPaymentsProxy, ProxyAdmin: GraphPaymentsProxyAdmin } = deployWithOZProxy(m, 'GraphPayments')
2434
const { Proxy: PaymentsEscrowProxy, ProxyAdmin: PaymentsEscrowProxyAdmin } = deployWithOZProxy(m, 'PaymentsEscrow')
2535

2636
// Register the proxies in the controller
27-
const setProxyHorizonStaking = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('Staking')), HorizonStakingProxy], { id: 'setContractProxy_HorizonStaking' })
28-
const setProxyGraphPayments = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphPayments')), GraphPaymentsProxy], { id: 'setContractProxy_GraphPayments' })
29-
const setProxyPaymentsEscrow = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('PaymentsEscrow')), PaymentsEscrowProxy], { id: 'setContractProxy_PaymentsEscrow' })
37+
// if isMigrate then use from: governor
38+
const options = isMigrate ? { from: m.getAccount(1) } : {}
39+
const setProxyGraphPayments = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphPayments')), GraphPaymentsProxy], { ...options, id: 'setContractProxy_GraphPayments' })
40+
const setProxyPaymentsEscrow = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('PaymentsEscrow')), PaymentsEscrowProxy], { ...options, id: 'setContractProxy_PaymentsEscrow' })
3041

3142
// Deploy dummy contract to signal that all periphery contracts are registered
3243
const HorizonRegistered = m.contract('Dummy', DummyArtifact, [], {

packages/horizon/ignition/modules/core/HorizonStaking.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@ export default buildModule('HorizonStaking', (m) => {
2727
)
2828

2929
// Upgrade proxy to implementation contract
30-
const upgradeCall = m.call(GraphProxyAdmin, 'upgrade', [HorizonStakingProxy, HorizonStakingImplementation])
31-
const acceptCall = m.call(GraphProxyAdmin, 'acceptProxy', [HorizonStakingImplementation, HorizonStakingProxy], { after: [upgradeCall] })
30+
const isMigrate = m.getParameter('isMigrate')
31+
const governor = m.getAccount(1)
32+
const options = isMigrate ? { from: governor } : {}
33+
const upgradeCall = m.call(GraphProxyAdmin, 'upgrade', [HorizonStakingProxy, HorizonStakingImplementation], options)
34+
const acceptCall = m.call(GraphProxyAdmin, 'acceptProxy', [HorizonStakingImplementation, HorizonStakingProxy], { ...options, after: [upgradeCall] })
3235

3336
// Load contract with implementation ABI
3437
const HorizonStaking = m.contractAt('HorizonStaking', HorizonStakingArtifact, HorizonStakingProxy, { after: [acceptCall], id: 'HorizonStaking_Instance' })
35-
m.call(HorizonStaking, 'setMaxThawingPeriod', [m.getParameter('maxThawingPeriod')])
38+
m.call(HorizonStaking, 'setMaxThawingPeriod', [m.getParameter('maxThawingPeriod')], options)
3639

3740
return { HorizonStakingProxy, HorizonStakingImplementation, HorizonStaking }
3841
})

packages/horizon/ignition/modules/core/PaymentsEscrow.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ export default buildModule('PaymentsEscrow', (m) => {
2727
// Load contract with implementation ABI
2828
const PaymentsEscrow = m.contractAt('PaymentsEscrow', PaymentsEscrowArtifact, PaymentsEscrowProxy, { id: 'PaymentsEscrow_Instance' })
2929

30-
return { PaymentsEscrow }
30+
return { PaymentsEscrow, PaymentsEscrowImplementation }
3131
})

packages/horizon/ignition/modules/periphery.ts

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,42 @@ export default buildModule('GraphHorizon_Periphery', (m) => {
1818
const { EpochManager } = m.useModule(EpochManagerModule)
1919
const { GraphProxyAdmin } = m.useModule(GraphProxyAdminModule)
2020
const { GraphTokenGateway } = m.useModule(GraphTokenGatewayModule)
21-
const { RewardsManager } = m.useModule(RewardsManagerModule)
2221
const { GraphToken } = m.useModule(GraphTokenModule)
23-
const { Curation } = m.useModule(CurationModule)
24-
25-
// Register contracts in the Controller
26-
const setProxyEpochManager = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('EpochManager')), EpochManager], { id: 'setContractProxy_EpochManager' })
27-
const setProxyRewardsManager = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('RewardsManager')), RewardsManager], { id: 'setContractProxy_RewardsManager' })
28-
const setProxyGraphToken = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphToken')), GraphToken], { id: 'setContractProxy_GraphToken' })
29-
const setProxyGraphTokenGateway = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphTokenGateway')), GraphTokenGateway], { id: 'setContractProxy_GraphTokenGateway' })
30-
// eslint-disable-next-line no-secrets/no-secrets
31-
const setProxyGraphProxyAdmin = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphProxyAdmin')), GraphProxyAdmin], { id: 'setContractProxy_GraphProxyAdmin' })
32-
const setProxyCuration = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('Curation')), Curation], { id: 'setContractProxy_Curation' })
33-
34-
// Deploy dummy contract to signal that all periphery contracts are registered
35-
const PeripheryRegistered = m.contract('Dummy', DummyArtifact, [], {
36-
after: [
37-
setProxyEpochManager,
38-
setProxyRewardsManager,
39-
setProxyGraphToken,
40-
setProxyGraphTokenGateway,
41-
setProxyGraphProxyAdmin,
42-
setProxyCuration,
43-
],
44-
})
22+
23+
const { instance: RewardsManager } = m.useModule(RewardsManagerModule)
24+
const { instance: Curation } = m.useModule(CurationModule)
25+
26+
const isMigrate = m.getParameter('isMigrate', false)
27+
28+
let PeripheryRegistered
29+
if (!isMigrate) {
30+
// Register contracts in the Controller
31+
const setProxyEpochManager = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('EpochManager')), EpochManager], { id: 'setContractProxy_EpochManager' })
32+
const setProxyRewardsManager = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('RewardsManager')), RewardsManager], { id: 'setContractProxy_RewardsManager' })
33+
const setProxyGraphToken = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphToken')), GraphToken], { id: 'setContractProxy_GraphToken' })
34+
const setProxyGraphTokenGateway = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphTokenGateway')), GraphTokenGateway], { id: 'setContractProxy_GraphTokenGateway' })
35+
// eslint-disable-next-line no-secrets/no-secrets
36+
const setProxyGraphProxyAdmin = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphProxyAdmin')), GraphProxyAdmin], { id: 'setContractProxy_GraphProxyAdmin' })
37+
const setProxyCuration = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('Curation')), Curation], { id: 'setContractProxy_Curation' })
38+
39+
// Deploy dummy contract to signal that all periphery contracts are registered
40+
PeripheryRegistered = m.contract('Dummy', DummyArtifact, [], {
41+
after: [
42+
setProxyEpochManager,
43+
setProxyRewardsManager,
44+
setProxyGraphToken,
45+
setProxyGraphTokenGateway,
46+
setProxyGraphProxyAdmin,
47+
setProxyCuration,
48+
],
49+
})
50+
} else {
51+
// TODO: Remove if not needed
52+
const governor = m.getAccount(1)
53+
// eslint-disable-next-line no-secrets/no-secrets
54+
const setProxyGraphProxyAdmin = m.call(Controller, 'setContractProxy', [ethers.keccak256(ethers.toUtf8Bytes('GraphProxyAdmin')), GraphProxyAdmin], { id: 'setContractProxy_GraphProxyAdmin', from: governor })
55+
PeripheryRegistered = m.contract('Dummy', DummyArtifact, [], { after: [setProxyGraphProxyAdmin] })
56+
}
4557

4658
return {
4759
BridgeEscrow,

0 commit comments

Comments
 (0)