-
Notifications
You must be signed in to change notification settings - Fork 49
Staking refactor including bug fixes #2021
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 17 commits
a255c1d
c38ecba
70c173b
d27e204
8ca5d46
1611b4b
98c60ec
8fd11dc
1604509
fb35a86
3d4832a
57d5261
9d87373
0cf0ec4
4c8db66
8a5fbbd
799dad1
a050ca6
51d7739
0eb3292
d99def1
cb7d9b4
56b7b34
6c28f88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { HardhatRuntimeEnvironment } from "hardhat/types"; | ||
import { DeployFunction } from "hardhat-deploy/types"; | ||
import { getContractAddress } from "./utils/getContractAddress"; | ||
import { deployUpgradable } from "./utils/deployUpgradable"; | ||
import { HomeChains, isSkipped, isDevnet, PNK, ETH } from "./utils"; | ||
import { getContractOrDeploy, getContractOrDeployUpgradable } from "./utils/getContractOrDeploy"; | ||
import { deployERC20AndFaucet, deployERC721 } from "./utils/deployTokens"; | ||
import { ChainlinkRNG, DisputeKitClassic, KlerosCoreNeo, StakeControllerNeo, VaultNeo } from "../typechain-types"; | ||
|
||
const deployArbitrationV2Neo: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { | ||
const { ethers, deployments, getNamedAccounts, getChainId } = hre; | ||
const { deploy } = deployments; | ||
const { ZeroAddress } = hre.ethers; | ||
const RNG_LOOKAHEAD = 20; | ||
|
||
// fallback to hardhat node signers on local network | ||
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address; | ||
const chainId = Number(await getChainId()); | ||
console.log("deploying to %s with deployer %s", HomeChains[chainId], deployer); | ||
|
||
const pnk = await deployERC20AndFaucet(hre, deployer, "PNK"); | ||
const weth = await deployERC20AndFaucet(hre, deployer, "WETH"); | ||
const nft = await deployERC721(hre, deployer, "Kleros V2 Neo Early User", "KlerosV2NeoEarlyUser"); | ||
|
||
await getContractOrDeploy(hre, "TransactionBatcher", { from: deployer, args: [], log: true }); | ||
|
||
await deployUpgradable(deployments, "PolicyRegistry", { from: deployer, args: [deployer], log: true }); | ||
|
||
await deployUpgradable(deployments, "EvidenceModule", { from: deployer, args: [deployer], log: true }); | ||
|
||
const disputeKit = await deployUpgradable(deployments, "DisputeKitClassicV2Neo", { | ||
from: deployer, | ||
contract: "DisputeKitClassic", | ||
args: [deployer, ZeroAddress], | ||
log: true, | ||
}); | ||
|
||
// TODO....... | ||
|
||
const disputeTemplateRegistry = await getContractOrDeployUpgradable(hre, "DisputeTemplateRegistry", { | ||
from: deployer, | ||
args: [deployer], | ||
log: true, | ||
}); | ||
|
||
const resolver = await deploy("DisputeResolverV2Neo", { | ||
from: deployer, | ||
contract: "DisputeResolver", | ||
args: [core.target, disputeTemplateRegistry.target], | ||
log: true, | ||
}); | ||
|
||
console.log(`core.changeArbitrableWhitelist(${resolver.address}, true)`); | ||
await core.changeArbitrableWhitelist(resolver.address, true); | ||
|
||
await deploy("KlerosCoreNeoSnapshotProxy", { | ||
from: deployer, | ||
contract: "KlerosCoreSnapshotProxy", | ||
args: [deployer, core.target], | ||
log: true, | ||
}); | ||
|
||
console.log("✅ V2 Neo Architecture deployment completed successfully!"); | ||
console.log(`📦 VaultNeo: ${pnkVaultNeo.address}`); | ||
console.log(`🎫 stPNKNeo: ${stPNK.address}`); | ||
console.log(`🎯 SortitionSumTreeNeo: ${sortitionModuleV2Neo.address}`); | ||
console.log(`🎮 StakeControllerNeo: ${stakeControllerNeo.target}`); | ||
console.log(`⚖️ KlerosCoreNeo: ${klerosCoreV2Neo.target}`); | ||
console.log(`🎨 JurorNFT: ${nft.target}`); | ||
console.log(`🔐 DisputeResolver: ${resolver.address}`); | ||
}; | ||
|
||
deployArbitrationV2Neo.tags = ["ArbitrationV2Neo"]; | ||
deployArbitrationV2Neo.dependencies = ["ChainlinkRNG"]; | ||
deployArbitrationV2Neo.skip = async ({ network }) => { | ||
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]); | ||
}; | ||
|
||
export default deployArbitrationV2Neo; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import { HardhatRuntimeEnvironment } from "hardhat/types"; | ||
import { DeployFunction } from "hardhat-deploy/types"; | ||
import { getContractAddress } from "./utils/getContractAddress"; | ||
import { deployUpgradable } from "./utils/deployUpgradable"; | ||
import { HomeChains, isSkipped, isDevnet, PNK, ETH } from "./utils"; | ||
import { getContractOrDeploy, getContractOrDeployUpgradable } from "./utils/getContractOrDeploy"; | ||
import { deployERC20AndFaucet } from "./utils/deployTokens"; | ||
import { ChainlinkRNG, DisputeKitClassic, KlerosCore, StakeController, Vault } from "../typechain-types"; | ||
import { changeCurrencyRate } from "./utils/klerosCoreHelper"; | ||
|
||
const deployArbitrationV2: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { | ||
const { ethers, deployments, getNamedAccounts, getChainId } = hre; | ||
const { deploy } = deployments; | ||
const { ZeroAddress } = hre.ethers; | ||
const RNG_LOOKAHEAD = 20; | ||
|
||
// fallback to hardhat node signers on local network | ||
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address; | ||
const chainId = Number(await getChainId()); | ||
console.log("deploying to %s with deployer %s", HomeChains[chainId], deployer); | ||
|
||
const pnk = await deployERC20AndFaucet(hre, deployer, "PNK"); | ||
const dai = await deployERC20AndFaucet(hre, deployer, "DAI"); | ||
const weth = await deployERC20AndFaucet(hre, deployer, "WETH"); | ||
|
||
await getContractOrDeploy(hre, "TransactionBatcher", { from: deployer, args: [], log: true }); | ||
|
||
await getContractOrDeployUpgradable(hre, "PolicyRegistry", { from: deployer, args: [deployer], log: true }); | ||
|
||
await getContractOrDeployUpgradable(hre, "EvidenceModule", { from: deployer, args: [deployer], log: true }); | ||
|
||
const disputeKit = await deployUpgradable(deployments, "DisputeKitClassicV2", { | ||
from: deployer, | ||
contract: "DisputeKitClassic", | ||
args: [ | ||
deployer, | ||
ZeroAddress, // Placeholder for KlerosCore address, configured later | ||
], | ||
log: true, | ||
}); | ||
|
||
// Calculate future addresses for circular dependencies | ||
const nonce = await ethers.provider.getTransactionCount(deployer); | ||
|
||
const vaultAddress = getContractAddress(deployer, nonce + 1); // deployed on the 2nd tx (nonce+1): Vault Impl tx, Vault Proxy tx | ||
console.log("calculated future Vault address for nonce %d: %s", nonce + 1, vaultAddress); | ||
|
||
const stakeControllerAddress = getContractAddress(deployer, nonce + 5); // deployed on the 6th tx (nonce+5): Vault Impl tx, Vault Proxy tx, SortitionModule Impl tx, SortitionModule Proxy tx,, StakeController Impl tx, StakeController Proxy tx | ||
console.log("calculated future StakeController address for nonce %d: %s", nonce + 5, stakeControllerAddress); | ||
|
||
const klerosCoreAddress = getContractAddress(deployer, nonce + 7); // deployed on the 8th tx (nonce+7): Vault Impl tx, Vault Proxy tx, SortitionModule Impl tx, SortitionModule Proxy tx, StakeController Impl tx, StakeController Proxy tx, KlerosCore Impl tx, KlerosCore Proxy tx | ||
console.log("calculated future KlerosCore address for nonce %d: %s", nonce + 7, klerosCoreAddress); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nonce-based address prediction is brittle
If any deployment is skipped (already deployed), or Move the circular-dependency resolution inside 🤖 Prompt for AI Agents
|
||
const vault = await deployUpgradable(deployments, "Vault", { | ||
from: deployer, | ||
args: [deployer, pnk.target, stakeControllerAddress, klerosCoreAddress], | ||
log: true, | ||
}); // nonce (implementation), nonce + 1 (proxy) | ||
|
||
// Deploy SortitionSumTree | ||
const sortitionModuleV2 = await deployUpgradable(deployments, "SortitionSumTree", { | ||
from: deployer, | ||
args: [deployer, stakeControllerAddress], | ||
log: true, | ||
}); // nonce + 2 (implementation), nonce + 3 (proxy) | ||
|
||
// Deploy StakeController (only if not already deployed) | ||
const devnet = isDevnet(hre.network); | ||
const minStakingTime = devnet ? 180 : 1800; | ||
const maxDrawingTime = devnet ? 600 : 1800; | ||
const rng = (await ethers.getContract("ChainlinkRNG")) as ChainlinkRNG; | ||
const stakeController = await deployUpgradable(deployments, "StakeController", { | ||
from: deployer, | ||
args: [ | ||
deployer, | ||
klerosCoreAddress, | ||
vault.address, | ||
sortitionModuleV2.address, | ||
rng.target, | ||
minStakingTime, | ||
maxDrawingTime, | ||
RNG_LOOKAHEAD, | ||
], | ||
log: true, | ||
}); // nonce + 4 (implementation), nonce + 5 (proxy) | ||
|
||
const minStake = PNK(200); | ||
const alpha = 10000; | ||
const feeForJuror = ETH(0.1); | ||
const jurorsForCourtJump = 256; | ||
|
||
// Deploy KlerosCore (only if not already deployed) | ||
const klerosCoreV2 = await deployUpgradable(deployments, "KlerosCore", { | ||
from: deployer, | ||
args: [ | ||
deployer, | ||
deployer, | ||
ZeroAddress, // JurorProsecutionModule, not implemented yet | ||
disputeKit.address, | ||
false, | ||
[minStake, alpha, feeForJuror, jurorsForCourtJump], | ||
[0, 0, 0, 10], // evidencePeriod, commitPeriod, votePeriod, appealPeriod | ||
ethers.toBeHex(5), // Extra data for sortition module will return the default value of K | ||
stakeController.address, | ||
vault.address, | ||
], | ||
log: true, | ||
}); | ||
|
||
// Configure cross-dependencies | ||
console.log("Configuring cross-dependencies..."); | ||
|
||
// disputeKit.changeCore() only if necessary | ||
const disputeKitContract = (await ethers.getContract("DisputeKitClassicV2")) as DisputeKitClassic; | ||
const currentCore = await disputeKitContract.core(); | ||
if (currentCore !== klerosCoreV2.address) { | ||
console.log(`disputeKit.changeCore(${klerosCoreV2.address})`); | ||
await disputeKitContract.changeCore(klerosCoreV2.address); | ||
} | ||
|
||
// rng.changeSortitionModule() only if necessary | ||
// Note: the RNG's `sortitionModule` variable is misleading, it's only for access control and should be renamed to `consumer`. | ||
const rngSortitionModule = await rng.sortitionModule(); | ||
if (rngSortitionModule !== stakeController.address) { | ||
console.log(`rng.changeSortitionModule(${stakeController.address})`); | ||
await rng.changeSortitionModule(stakeController.address); | ||
} | ||
|
||
const core = (await hre.ethers.getContract("KlerosCore")) as KlerosCore; | ||
try { | ||
await changeCurrencyRate(core, await pnk.getAddress(), true, 12225583, 12); | ||
await changeCurrencyRate(core, await dai.getAddress(), true, 60327783, 11); | ||
await changeCurrencyRate(core, await weth.getAddress(), true, 1, 1); | ||
} catch (e) { | ||
console.error("failed to change currency rates:", e); | ||
} | ||
|
||
await deploy("KlerosCoreSnapshotProxy", { | ||
from: deployer, | ||
contract: "KlerosCoreSnapshotProxy", | ||
args: [deployer, core.target], | ||
log: true, | ||
}); | ||
|
||
console.log("✅ V2 Architecture deployment completed successfully!"); | ||
console.log(`📦 Vault: ${vault.address}`); | ||
console.log(`🎯 SortitionSumTree: ${sortitionModuleV2.address}`); | ||
console.log(`🎮 StakeController: ${stakeController.address}`); | ||
console.log(`⚖️ KlerosCore: ${klerosCoreV2.address}`); | ||
}; | ||
|
||
deployArbitrationV2.tags = ["ArbitrationV2"]; | ||
deployArbitrationV2.dependencies = ["ChainlinkRNG"]; | ||
deployArbitrationV2.skip = async ({ network }) => { | ||
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]); | ||
}; | ||
|
||
export default deployArbitrationV2; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,8 +1,8 @@ | ||||||
import { KlerosCore, KlerosCoreNeo, KlerosCoreRuler, KlerosCoreUniversity } from "../../typechain-types"; | ||||||
import { KlerosCore, KlerosCoreNeo, KlerosCoreRuler, KlerosCoreUniversity, KlerosCore } from "../../typechain-types"; | ||||||
import { BigNumberish, toBigInt } from "ethers"; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix duplicate import causing syntax error. The import statement contains a duplicate Apply this diff to remove the duplicate: -import { KlerosCore, KlerosCoreNeo, KlerosCoreRuler, KlerosCoreUniversity, KlerosCore } from "../../typechain-types";
+import { KlerosCore, KlerosCoreNeo, KlerosCoreRuler, KlerosCoreUniversity } from "../../typechain-types"; 🧰 Tools🪛 Biome (1.9.4)[error] 1-1: Declarations inside of a a second declaration of
(parse) 🤖 Prompt for AI Agents
|
||||||
|
||||||
export const changeCurrencyRate = async ( | ||||||
core: KlerosCore | KlerosCoreNeo | KlerosCoreRuler | KlerosCoreUniversity, | ||||||
core: KlerosCore | KlerosCoreNeo | KlerosCoreRuler | KlerosCoreUniversity | KlerosCore, | ||||||
erc20: string, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix duplicate type in parameter annotation. The Apply this diff to remove the duplicate: - core: KlerosCore | KlerosCoreNeo | KlerosCoreRuler | KlerosCoreUniversity | KlerosCore,
+ core: KlerosCore | KlerosCoreNeo | KlerosCoreRuler | KlerosCoreUniversity, 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||
accepted: boolean, | ||||||
rateInEth: BigNumberish, | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script will crash – multiple variables are referenced before declaration.
core
,pnkVaultNeo
,stPNK
,sortitionModuleV2Neo
,stakeControllerNeo
, andklerosCoreV2Neo
are logged or passed as args but are never defined.core
is also used when deployingDisputeResolverV2Neo
.Minimal fix sketch:
Without these definitions the deployment script will throw on the first reference and break CI.
🤖 Prompt for AI Agents