Skip to content

Commit e2ea28c

Browse files
authored
fix: Horizon migration script fixes (#1100)
1 parent fbdb3f1 commit e2ea28c

File tree

13 files changed

+174
-37
lines changed

13 files changed

+174
-37
lines changed

packages/hardhat-graph-protocol/src/sdk/address-book.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,13 @@ export abstract class AddressBook<
104104
* @returns the address book entry for the contract
105105
* Returns an empty address book entry if the contract is not found
106106
*/
107-
getEntry(name: ContractName): AddressBookEntry {
108-
try {
109-
const entry = this.addressBook[this.chainId][name]
110-
this._assertAddressBookEntry(entry)
111-
return entry
112-
} catch (_) {
113-
// TODO: should we throw instead?
114-
return { address: '0x0000000000000000000000000000000000000000' }
107+
getEntry(name: ContractName): { address: string } {
108+
const entry = this.addressBook[this.chainId][name]
109+
// Handle both object and string formats
110+
if (typeof entry === 'string') {
111+
return { address: entry }
115112
}
113+
return entry
116114
}
117115

118116
/**
@@ -215,13 +213,20 @@ export abstract class AddressBook<
215213
}
216214

217215
// Asserts the provided object is a valid address book entry
218-
_assertAddressBookEntry(json: unknown): asserts json is AddressBookEntry {
219-
assertObject(json)
220-
221-
if (typeof json.address !== 'string') throw new AssertionError({ message: 'Invalid address' })
222-
if (json.proxy && typeof json.proxy !== 'boolean')
223-
throw new AssertionError({ message: 'Invalid proxy' })
224-
if (json.implementation && typeof json.implementation !== 'object')
225-
throw new AssertionError({ message: 'Invalid implementation' })
216+
_assertAddressBookEntry(
217+
entry: unknown,
218+
): asserts entry is { address: string } {
219+
if (typeof entry === 'string') {
220+
// If it's a string, treat it as an address
221+
return
222+
}
223+
224+
assertObject(entry)
225+
if (!('address' in entry)) {
226+
throw new Error('Address book entry must have an address field')
227+
}
228+
if (typeof entry.address !== 'string') {
229+
throw new Error('Address book entry address must be a string')
230+
}
226231
}
227232
}

packages/hardhat-graph-protocol/src/sdk/hardhat.base.config.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ import type { EtherscanConfig } from '@nomicfoundation/hardhat-verify/types'
55

66
// This next import ensures secure accounts config is correctly typed
77
// eslint-disable-next-line @typescript-eslint/no-unused-vars
8-
import type { SecureAccountsOptions } from 'hardhat-secure-accounts/src/type-extensions'
8+
import 'hardhat-secure-accounts'
99

1010
// Environment variables
1111
const ARBISCAN_API_KEY = vars.get('ARBISCAN_API_KEY', undefined)
1212

1313
// RPCs
1414
const VIRTUAL_ARBITRUM_SEPOLIA_RPC = vars.has('VIRTUAL_ARBITRUM_SEPOLIA_RPC') ? vars.get('VIRTUAL_ARBITRUM_SEPOLIA_RPC') : undefined
1515
const ARBITRUM_SEPOLIA_RPC = vars.get('ARBITRUM_SEPOLIA_RPC', 'https://sepolia-rollup.arbitrum.io/rpc')
16+
const VIRTUAL_ARBITRUM_ONE_RPC = vars.has('VIRTUAL_ARBITRUM_ONE_RPC') ? vars.get('VIRTUAL_ARBITRUM_ONE_RPC') : undefined
17+
18+
// Tenderly API Key
19+
const TENDERLY_API_KEY = vars.has('TENDERLY_API_KEY') ? vars.get('TENDERLY_API_KEY') : undefined
1620

1721
// Accounts
1822
const DEPLOYER_PRIVATE_KEY = vars.get('DEPLOYER_PRIVATE_KEY', undefined)
@@ -47,13 +51,33 @@ export const projectPathsUserConfig: ProjectPathsUserConfig = {
4751
export const etherscanUserConfig: Partial<EtherscanConfig> = {
4852
apiKey: {
4953
arbitrumSepolia: ARBISCAN_API_KEY,
54+
...(TENDERLY_API_KEY && {
55+
virtualArbitrumSepolia: TENDERLY_API_KEY,
56+
virtualArbitrumOne: TENDERLY_API_KEY,
57+
}),
5058
},
5159
customChains: [
5260
{
5361
network: 'arbitrumSepolia',
5462
chainId: 421614,
5563
urls: { apiURL: 'https://api-sepolia.arbiscan.io/api', browserURL: 'https://sepolia.arbiscan.io/' },
5664
},
65+
{
66+
network: 'virtualArbitrumSepolia',
67+
chainId: 421615,
68+
urls: {
69+
apiURL: VIRTUAL_ARBITRUM_SEPOLIA_RPC + '/verify/etherscan',
70+
browserURL: VIRTUAL_ARBITRUM_SEPOLIA_RPC || 'https://sepolia.arbiscan.io/',
71+
},
72+
},
73+
{
74+
network: 'virtualArbitrumOne',
75+
chainId: 42162,
76+
urls: {
77+
apiURL: VIRTUAL_ARBITRUM_ONE_RPC + '/verify/etherscan',
78+
browserURL: VIRTUAL_ARBITRUM_SEPOLIA_RPC || 'https://arbiscan.io/',
79+
},
80+
},
5781
],
5882
}
5983

@@ -85,6 +109,13 @@ export const networksUserConfig: NetworksUserConfig = {
85109
accounts: getTestnetAccounts(),
86110
},
87111
}),
112+
...(VIRTUAL_ARBITRUM_ONE_RPC && {
113+
virtualArbitrumOne: {
114+
chainId: 42162,
115+
url: VIRTUAL_ARBITRUM_ONE_RPC,
116+
accounts: getTestnetAccounts(),
117+
},
118+
}),
88119
}
89120

90121
export const hardhatBaseConfig: HardhatUserConfig & { etherscan: Partial<EtherscanConfig> } = {
@@ -97,7 +128,6 @@ export const hardhatBaseConfig: HardhatUserConfig & { etherscan: Partial<Ethersc
97128
graph: {
98129
deployments: {
99130
horizon: require.resolve('@graphprotocol/horizon/addresses.json'),
100-
subgraphService: require.resolve('@graphprotocol/subgraph-service/addresses.json'),
101131
},
102132
},
103133
etherscan: etherscanUserConfig,

packages/horizon/hardhat.config.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1+
import { HardhatUserConfig } from 'hardhat/config'
12
import { hardhatBaseConfig } from 'hardhat-graph-protocol/sdk'
23

34
// Hardhat plugins
45
import '@nomicfoundation/hardhat-foundry'
56
import '@nomicfoundation/hardhat-toolbox'
67
import '@nomicfoundation/hardhat-ignition-ethers'
8+
import "@tenderly/hardhat-tenderly"
79
import 'hardhat-storage-layout'
810
import 'hardhat-contract-sizer'
9-
import 'hardhat-secure-accounts'
1011

1112
if (process.env.BUILD_RUN !== 'true') {
1213
require('hardhat-graph-protocol')
1314
}
1415

15-
export default hardhatBaseConfig
16+
const config: HardhatUserConfig = {
17+
...hardhatBaseConfig,
18+
tenderly: {
19+
project: "graph-network",
20+
username: "graphprotocol",
21+
}
22+
}
23+
24+
export default config

packages/horizon/ignition/configs/horizon-migrate.default.json5

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
"curationAddress": "0xDe761f075200E75485F4358978FB4d1dC8644FD5",
1515

1616
// Must be set for step 4 of the migration
17-
"subgraphServiceAddress": "0x0000000000000000000000000000000000000000"
17+
"subgraphServiceAddress": "0x0000000000000000000000000000000000000000",
18+
19+
// Parameters
20+
"maxThawingPeriod": 2419200
1821
},
1922
"GraphPayments": {
2023
"protocolPaymentCut": 10000
@@ -33,7 +36,6 @@
3336
"paymentsEscrowAddress": "0x0000000000000000000000000000000000000000"
3437
},
3538
"HorizonStakingGovernor": {
36-
"maxThawingPeriod": 2419200,
3739
// Must be set for step 4 of the migration
3840
"horizonStakingImplementationAddress": "0x0000000000000000000000000000000000000000"
3941
},
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"$global": {
3+
// Accounts
4+
"governor": "0x72ee30d43Fb5A90B3FE983156C5d2fBE6F6d07B3",
5+
6+
// Addresses for contracts deployed in the original Graph Protocol
7+
"graphProxyAdminAddress": "0x2983936aC20202a6555993448E0d5654AC8Ca5fd",
8+
"controllerAddress": "0x0a8491544221dd212964fbb96487467291b2C97e",
9+
"horizonStakingAddress": "0x00669A4CF01450B64E8A2A20E9b1FCB71E61eF03",
10+
"epochManagerAddress": "0x5A843145c43d328B9bB7a4401d94918f131bB281",
11+
"graphTokenAddress": "0x9623063377AD1B27544C965cCd7342f7EA7e88C7",
12+
"graphTokenGatewayAddress": "0x65E1a5e8946e7E87d9774f5288f41c30a99fD302",
13+
"rewardsManagerAddress": "0x971B9d3d0Ae3ECa029CAB5eA1fB0F72c85e6a525",
14+
"curationAddress": "0x22d78fb4bc72e191C765807f8891B5e1785C8014",
15+
16+
// Must be set for step 4 of the migration
17+
"subgraphServiceAddress": "0x0000000000000000000000000000000000000000",
18+
19+
// Parameters
20+
"maxThawingPeriod": 2419200
21+
},
22+
"GraphPayments": {
23+
"protocolPaymentCut": 10000
24+
},
25+
"PaymentsEscrow": {
26+
"withdrawEscrowThawingPeriod": 10000
27+
},
28+
"TAPCollector": {
29+
"eip712Name": "TAPCollector",
30+
"eip712Version": "1",
31+
"revokeSignerThawingPeriod": 10000
32+
},
33+
"HorizonProxiesGovernor": {
34+
// These addresses must be set for step 2 of the migration
35+
"graphPaymentsAddress": "0x0000000000000000000000000000000000000000",
36+
"paymentsEscrowAddress": "0x0000000000000000000000000000000000000000"
37+
},
38+
"HorizonStakingGovernor": {
39+
// Must be set for step 4 of the migration
40+
"horizonStakingImplementationAddress": "0x0000000000000000000000000000000000000000"
41+
},
42+
"L2CurationGovernor": {
43+
// Must be set for step 4 of the migration
44+
"curationImplementationAddress": "0x0000000000000000000000000000000000000000"
45+
},
46+
"RewardsManagerGovernor": {
47+
// Must be set for step 4 of the migration
48+
"rewardsManagerImplementationAddress": "0x0000000000000000000000000000000000000000"
49+
}
50+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { acceptUpgradeGraphProxy, upgradeGraphProxy } from '../proxy/GraphProxy'
1+
import { upgradeGraphProxy } from '../proxy/GraphProxy'
22
import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'
33
import { deployImplementation } from '../proxy/implementation'
44

@@ -89,7 +89,7 @@ export const MigrateHorizonStakingGovernorModule = buildModule('HorizonStakingGo
8989
const GraphProxyAdmin = m.contractAt('GraphProxyAdmin', GraphProxyAdminArtifact, graphProxyAdminAddress)
9090

9191
// Upgrade proxy to implementation contract
92-
const HorizonStaking = acceptUpgradeGraphProxy(m, GraphProxyAdmin, HorizonStakingProxy, HorizonStakingImplementation, {
92+
const HorizonStaking = upgradeGraphProxy(m, GraphProxyAdmin, HorizonStakingProxy, HorizonStakingImplementation, {
9393
name: 'HorizonStaking',
9494
artifact: HorizonStakingArtifact,
9595
})

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ export default buildModule('GraphHorizon_Core', (m) => {
1515
})
1616

1717
export const MigrateHorizonCoreModule = buildModule('GraphHorizon_Core', (m) => {
18-
const { HorizonStakingProxy: HorizonStaking } = m.useModule(MigrateHorizonStakingDeployerModule)
18+
const { HorizonStakingProxy: HorizonStaking, HorizonStakingImplementation } = m.useModule(MigrateHorizonStakingDeployerModule)
1919
const { GraphPayments } = m.useModule(MigrateGraphPaymentsModule)
2020
const { PaymentsEscrow } = m.useModule(MigratePaymentsEscrowModule)
2121
const { TAPCollector } = m.useModule(MigrateTAPCollectorModule)
2222

23-
return { HorizonStaking, GraphPayments, PaymentsEscrow, TAPCollector }
23+
return { HorizonStaking, HorizonStakingImplementation, GraphPayments, PaymentsEscrow, TAPCollector }
2424
})

packages/horizon/ignition/modules/migrate/migrate-3.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { MigratePeripheryModule } from '../periphery/periphery'
66
export default buildModule('GraphHorizon_Migrate_3', (m) => {
77
const {
88
L2Curation,
9+
L2CurationImplementation,
910
RewardsManager,
11+
RewardsManagerImplementation,
1012
Controller,
1113
GraphProxyAdmin,
1214
EpochManager,
@@ -16,15 +18,19 @@ export default buildModule('GraphHorizon_Migrate_3', (m) => {
1618

1719
const {
1820
HorizonStaking,
21+
HorizonStakingImplementation,
1922
GraphPayments,
2023
PaymentsEscrow,
2124
TAPCollector,
2225
} = m.useModule(MigrateHorizonCoreModule)
2326

2427
return {
2528
L2Curation,
29+
L2CurationImplementation,
2630
RewardsManager,
31+
RewardsManagerImplementation,
2732
HorizonStaking,
33+
HorizonStakingImplementation,
2834
GraphPayments,
2935
PaymentsEscrow,
3036
TAPCollector,

packages/horizon/ignition/modules/periphery/Curation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { acceptUpgradeGraphProxy, deployWithGraphProxy } from '../proxy/GraphProxy'
1+
import { upgradeGraphProxy, deployWithGraphProxy } from '../proxy/GraphProxy'
22
import { buildModule, IgnitionModuleBuilder } from '@nomicfoundation/ignition-core'
33
import { deployImplementation } from '../proxy/implementation'
44

@@ -59,7 +59,7 @@ export const MigrateCurationGovernorModule = buildModule('L2CurationGovernor', (
5959
artifact: CurationArtifact,
6060
}
6161

62-
const L2Curation = acceptUpgradeGraphProxy(m, GraphProxyAdmin, L2CurationProxy, L2CurationImplementation, implementationMetadata)
62+
const L2Curation = upgradeGraphProxy(m, GraphProxyAdmin, L2CurationProxy, L2CurationImplementation, implementationMetadata)
6363
m.call(L2Curation, 'setSubgraphService', [subgraphServiceAddress])
6464

6565
return { L2Curation }

packages/horizon/ignition/modules/periphery/RewardsManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { acceptUpgradeGraphProxy, deployWithGraphProxy } from '../proxy/GraphProxy'
1+
import { upgradeGraphProxy, deployWithGraphProxy } from '../proxy/GraphProxy'
22
import { buildModule, IgnitionModuleBuilder } from '@nomicfoundation/ignition-core'
33
import { deployImplementation } from '../proxy/implementation'
44

@@ -59,7 +59,7 @@ export const MigrateRewardsManagerGovernorModule = buildModule('RewardsManagerGo
5959
artifact: RewardsManagerArtifact,
6060
}
6161

62-
const RewardsManager = acceptUpgradeGraphProxy(m, GraphProxyAdmin, RewardsManagerProxy, RewardsManagerImplementation, implementationMetadata)
62+
const RewardsManager = upgradeGraphProxy(m, GraphProxyAdmin, RewardsManagerProxy, RewardsManagerImplementation, implementationMetadata)
6363
m.call(RewardsManager, 'setSubgraphService', [subgraphServiceAddress])
6464

6565
return { RewardsManager }

0 commit comments

Comments
 (0)