Skip to content
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

Various contract scripts improvements #1853

Draft
wants to merge 10 commits into
base: dev
Choose a base branch
from
16 changes: 16 additions & 0 deletions contracts/config/courts.v2.devnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,21 @@
240,
600
]
},
{
"name": "Automated Curation",
"id": 6,
"parent": 2,
"hiddenVotes": false,
"minStake": "2000000000000000000",
"alpha": "3100",
"feeForJuror": "100000000000",
"jurorsForCourtJump": "31",
"timesPerPeriod": [
120,
240,
240,
600
]
}
]
18 changes: 17 additions & 1 deletion contracts/config/courts.v2.mainnet-neo.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@
"alpha": "5000",
"jurorsForCourtJump": "15",
"timesPerPeriod": [
108000,
21600,
216000,
216000,
216000
Expand All @@ -478,5 +478,21 @@
583200,
388800
]
},
{
"name": "Automated Curation",
"id": 31,
"parent": 10,
"hiddenVotes": false,
"minStake": "2600000000000000000000",
"alpha": "290",
"feeForJuror": "170000000000000",
"jurorsForCourtJump": "3",
"timesPerPeriod": [
140400,
291600,
291600,
194400
]
}
]
8 changes: 8 additions & 0 deletions contracts/config/policies.v2.devnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,13 @@
"requiredSkills": "Jurors in the Oracle Court should possess:\n- **Analytical Skills**: Ability to objectively assess a wide range of real-world event data, statistics, and sources, with precision and critical thinking.\n- **Understanding of Prediction Markets**: Familiarity with how prediction markets function.",
"court": 5,
"uri": "/ipfs/QmT8DAjUbzzEo2e9oPpJSDH2QzswfNeWAsxoDH3zsGrtkH"
},
{
"name": "Automated Curation",
"purpose": "The Automated Curation Court is designed to handle micro-tasks and cases requiring fast and near-instant resolution. These include, but are not limited to, content moderation, gaming disputes, automated data curation, and similar use cases. AI agents capable of rapid decision-making are better suited for this court's short resolution time.",
"rules": "",
"requiredSkills": "AI agents participating as jurors of this court must be capable of:\n- Data Processing Efficiency: Handling high volumes of disputes in near real-time without compromising accuracy.\n- Kleros Rules Compliance: analyzing all evidence presented and ruling in accordance with Kleros General Court Policy, this Automated Curation Court Policy, and the case’s Primary Document.\n- Temporal Awareness: Identifying the moment of relevant events in a dispute, which may be crucial for applying the General Court’s Policy. This includes understanding the state of the world at the time the dispute was created, recognizing the exact time a piece of evidence was submitted, understanding the applicable court policies and arbitrable application primary documents that existed at the time of the dispute’s creation, and assessing whether a piece of evidence was submitted after the end of the evidence period of the initial round of the dispute.",
"court": 6,
"uri": "/ipfs/QmNm6w4itnvMoWQXcz3CAQmjSF4nP5w6uTwGAQ1Z5YoUKJ"
}
]
28 changes: 18 additions & 10 deletions contracts/config/policies.v2.mainnet-neo.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,36 +181,36 @@
"uri": "/ipfs/QmcaMbPgKAAvc67URzbq1yegnCANPRSNSmLQ7GwsyYNTCe"
},
{
"name": "Humanity Court",
"name": "Humanity",
"purpose": "In this court jurors will judge disputes related to establishing Sybil resistant lists of unique human identities, particularly for the Proof of Humanity protocol.\n\n",
"rules": "",
"requiredSkills": "Jurors should be capable of reasonably evaluating whether a proposed submission consisting of photo and video evidence corresponds to a unique human being, eventually making use of supplementary information that might be provided as evidence by relevant parties.",
"court": 24,
"uri": "/ipfs/QmXAVumYfMmezMQSbhYn33iCFxwqLguRztz7HcJaLnX1Z4"
"uri": "/ipfs/QmfH68LJWRQ7UEJqFGDKDpR6hmxmmJrbz2EHJMgqtCgFo6"
},
{
"name": "Development Court",
"name": "Development",
"purpose": "In this court, jurors will solve disputes involving the respect of specifications given by the client.",
"rules": "### Example\nDeveloper does not respect indentation, does not name variables explicitly or has not made a clear file structure. In such cases, jurors should refuse the proposal made by the developer.",
"requiredSkills": "This court requires a good level of familiarity with programming. Jurors who are not intermediate developers are advised to stake into this court only if they have some basics of low-level programming languages, ​​algorithmic and knowledge of good practices of development.",
"court": 25,
"uri": "/ipfs/QmfH2k1PmX4YufdZoAKwoGtdbjNZaxaTPdXB2uAs3rQsjh"
"uri": "/ipfs/QmdiQGftN4Mxtocvf1ENxeEvVzU62AGR3knzfhMDb85iTh"
},
{
"name": "Solidity Court",
"name": "Solidity",
"purpose": "",
"rules": "If the disputed code is of significant size (> 500 code lines), parties in the dispute should point out specific parts of the content which are being disputed. Otherwise, jurors should refuse to arbitrate.",
"requiredSkills": "This court requires a good level of solidity. Jurors who are not solidity intermediate developers are advised to stake into this court only if they also know how to make relatively simple contracts, know the main solidity hacks and can compute the complexity of simple functions.",
"court": 26,
"uri": "/ipfs/QmPRckaaNLj9ycZH6otChTwbkDsBnhkNrXnarF5vD6rXKy"
"uri": "/ipfs/QmbKfy5vF5jZ5GFqFKgUxnYsbAjJdtsDfp2UJLwxzDokmb"
},
{
"name": "Javascript Court",
"name": "Javascript",
"purpose": "",
"rules": "If the disputed code is of significant size (> 700 code lines), parties in the dispute should point out specific parts of the content which are being disputed. Otherwise, jurors should refuse to arbitrate.",
"requiredSkills": "This court requires a good level of javascript. Jurors who are not javascript intermediate developers are advised to stake into this court only if they know the main frameworks/libraries (ExpressJs, React, EthersJs…) and be comfortable with testing, APIs or languages to interact with databases.",
"court": 27,
"uri": "/ipfs/QmS9JzVezbAioSXXcuQsMw31pNjg5jeaV8vtbpwY5cMG8b"
"uri": "/ipfs/Qmaf4NzAvyVa4biu7MwaGTTwCe46XVSdBa3t3Uu2soFToz"
},
{
"name": "Corte de Curación en Español",
Expand All @@ -229,11 +229,19 @@
"uri": "/ipfs/Qmczrn2DgdKGnacdvKRYwCk7JkeyTCokdqQycWdetYrxGC"
},
{
"name": "Oracle Court",
"name": "Oracle",
"purpose": "The Oracle Court is designed to resolve disputes related to reporting real-world events, including but not limited to those originating from prediction markets.",
"rules": "The following rules are subsidiary and will apply only if no contrary provisions are outlined in the primary document or other rules or sources relevant to resolving the specific question. In such cases, jurors should adhere to these standard guidelines for resolution.\n### Refuse to Arbitrate\n\nThe following questions must resolve as \"Refuse to Arbitrate\":\n\n**1. Invalid answers:** Questions in which none of the answers are valid.\n\n*Refuse to Arbitrate: A Prediction Market question: \"Which movie will win the Best Picture award at the 2024 Oscars Academy Awards?\" with outcomes \"Barbie\" and \"Poor Things\" (the actual winner was \"Oppenheimer\").*\n\n**2. Multiple outcomes:** Questions in which multiple outcomes are valid, unless the question allows multiple correct answers. In a multiple choice question in which only one correct answer is allowed, the fact that multiple outcomes could be valid at the same time does not make the question invalid if only one of those outcomes occurs.\n\n*Valid:​ A Prediction Market multiple choice question that allows more than one answer: \"What team will reach the semi-finals of Copa America 2021?\" with answers \"Brazil,\" \"Argentina,\" \"Uruguay,\" and \"Colombia\" (all of them except Uruguay reached the semi-finals).*\n\n*Refuse to Arbitrate: A Prediction Market multiple choice question in which only one correct answer is allowed: \"Who will be the Time person of the year 1937?\" with answers \"Chiang Kai-shek\" and \"Soong Mei-ling\" (they got the prize jointly).*\n\n**3. Prohibited questions:** Questions that directly incentivize immoral violent actions (such as murder, rape or unjust imprisonment) which could likely be performed by any participant.\n\n*Refuse to Arbitrate: A Prediction Market question: Will Donald Trump be alive on 01/12/2024? (Anyone could bet on \"No\" and kill him for a guaranteed profit. Anyone could bet on \"Yes\" to effectively put a bounty on his head).*\n\n*Refuse to Arbitrate: A Prediction Market question: Will Hera be a victim of swatting in 2024? (Anyone could falsely call the emergency services on him in order to win the bet)*\n\nThis must not prevent questions:\n\n* Whose topics are violent events not caused by human beings.\n\n*Valid:​ A Prediction Market question: How many people will die from COVID19 in 2024? (Viruses don't use prediction markets).*\n\n* Whose main source of uncertainty is not related to a potential violent action.\n\n*Valid:​ A Prediction Market question: Will Trump win the 2020 US presidential election? (The main source of uncertainty is the vote of US citizens, not a potential murder of a presidential candidate).*\n\n* Which could give an incentive only to specific participants to commit an immoral violent action, but are in practice unlikely.\n\n*Valid:​ A Prediction Market question: Will the US be engaged in a military conflict with a UN member state in 2024? (It's unlikely for the US to declare war in order to win a bet on this market).*\n\n*Valid:​ Will Derek Chauvin go to jail for the murder of George Flyod? (It's unlikely that the jurors would collude to make a wrong verdict in order to win this market).*\n\n### Default assumptions\n\nUnless stated otherwise, the following assumptions must be made:\n\n**4. Entities:** Entities are assumed to reference the most obvious entity with that name, taking the context of the question into account.\n\n*Example: A Prediction Market question: \"Will Michael Jordan receive the 2021 Turing award?\" refers to the computer scientist Michael I. Jordan whereas \"How many points will Michael Jordan score in the FIBA Americas Championship?\" refers to Michael J. Jordan, the basketball player.*\n\n**5. Units:** In case units are omitted, they are assumed to be the units which are the most often used in this particular situation.\n\n*Example: A Prediction Market question: \"Will a NFT be sold for more than one million in 2021?\" will be interpreted as \"Will a NFT be sold for more than 1,000,000 USD in 2021?\".*\n\n**6. Rounding rule:** If no specific rounding method is given, values are to be rounded to the nearest proposed value, unit or range. Unless otherwise stated, roundings are done middle toward 0. If no proposed rule, value, or unit is provided, the value shall default to the most commonly used standard in the specific context.\n\n*Example: In a Prediction Market question with outcomes -100, 0 and 100. 77->100, 50->0, -50 -> 0.*\n\n*Example: In a Prediction Market question with outcomes A: 0-2, B: 3-5 and C: 6+. 1->A, 8->C, 5.5->B.*\n\n*Example: In the Prediction Market question \"What percentage of the popular vote will Joe Biden receive in the 2020 United States Presidential Election?\". If Biden received 51.305859559% of the vote, the correct answer is 51% (rounding to the nearest whole percent).*\n\n*Example: In the Prediction Market question \"What percentage of the popular vote will Joe Biden receive in the 2020 United States Presidential Election? (2 decimals)\". If Biden received 51.305859559% of the vote, the correct answer is 51.31%.*\n\n### Resolving unclear questions\n\nIn general, if the question does not break a rule of the Refuse to Arbitrate section, reasonable efforts should be made to determine its outcome even if the question is not 100% technically perfect, and the following rules must be applied:\n\n**7. Objective interpretation:** Questions must be interpreted according to their context, as any average reasonable person would.\n\n*Example: \"Will there be more than ten thousand deaths caused by Coronavirus in the United States in 2024?\" should be interpreted as referring to COVID-19, and not other types of Coronavirus.*\n\n**8. Sources of truth:** If the question doesn't mention a specific source, the most credible outcome must be reported. In order to determine the credibility of an outcome, the quantity of sources and their credibility are to be taken into account. Credibility of sources and of outcomes must be assessed according to facts, not unproven beliefs.\n\n*Example: \"Will extraterrestrial lifeforms visit planet earth?\" will resolve to No, unless a number of credible sources announce it, despite some people reporting having experienced such encounters.*\n\n*Example: \"How many people will die of COVID-19 in 2024?\" should be answered according to numbers reported by renowned health organisations and not according to some public figures claiming COVID-19 to be a hoax.*\n\n**9. Equal interpretations:** If a question can have different interpretations, but all those interpretations lead to the same outcome, this outcome must be reported. If no interpretation is clearly more reasonable than the others, jurors must vote Refuse to Arbitrate.\n\n*Example: A Prediction Market question: \"Which party will win the October 2012 Czeck elections?\" Should be reported as \"Czech Social Democratic Party\". Even if there were both senatorial and regional elections at the same date and the election the question refers to is ambiguous, the \"Czech Social Democratic Party\" won both of them.*\n\n*Example: In a Prediction Market question: \"Which party will win the October 2015 Czech elections?\" jurors should vote Refuse to Arbitrate because \"Christian and Democratic Union – Czechoslovak People's Party\" won the senatorial election but \"ANO 2011\" won the regional ones.*\n\n**10. Precision in numerical values:** When the answer to a question is a numerical value and the exact value is uncertain, the first reported value that is reasonable based on common approximations must be accepted.\n\n*Example: If in a Prediction Market question, \"What will be the global potato production in tons for the year 2024?\", the first answer is 374,000,000, this answer should be accepted if the estimates provided range between 374 million and 375 million tons.*",
"requiredSkills": "Jurors in the Oracle Court should possess:\n- **Analytical Skills**: Ability to objectively assess a wide range of real-world event data, statistics, and sources, with precision and critical thinking.\n- **Understanding of Prediction Markets**: Familiarity with how prediction markets function.",
"court": 30,
"uri": "/ipfs/QmVFKNM1F3YnH2DVFh1Xd6epL9Asum2xBm9kGUQeXypAN5"
"uri": "/ipfs/QmZqV3TJNZtYTZ74fcVTNT5uEwrsv2aDkGGVB5XUS32VD9"
},
{
"name": "Automated Curation",
"purpose": "The Automated Curation Court is designed to handle micro-tasks and cases requiring fast and near-instant resolution. These include, but are not limited to, content moderation, gaming disputes, automated data curation, and similar use cases. AI agents capable of rapid decision-making are better suited for this court's short resolution time.",
"rules": "",
"requiredSkills": "AI agents participating as jurors of this court must be capable of:\n- Data Processing Efficiency: Handling high volumes of disputes in near real-time without compromising accuracy.\n- Kleros Rules Compliance: analyzing all evidence presented and ruling in accordance with Kleros General Court Policy, this Automated Curation Court Policy, and the case’s Primary Document.\n- Temporal Awareness: Identifying the moment of relevant events in a dispute, which may be crucial for applying the General Court’s Policy. This includes understanding the state of the world at the time the dispute was created, recognizing the exact time a piece of evidence was submitted, understanding the applicable court policies and arbitrable application primary documents that existed at the time of the dispute’s creation, and assessing whether a piece of evidence was submitted after the end of the evidence period of the initial round of the dispute.",
"court": 31,
"uri": "/ipfs/QmV4TYUwUFgpMMKfWgDQjBtC5Dn5cRGraDnVatccSb6LMx"
}
]
2 changes: 2 additions & 0 deletions contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import "hardhat-tracer";
require("./scripts/simulations/tasks");
require("./scripts/populatePolicyRegistry");
require("./scripts/populateCourts");
require("./scripts/changeGovernor");
require("./scripts/getDisputeTemplate");

dotenv.config();

Expand Down
2 changes: 1 addition & 1 deletion contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"populate:policiesUris": "scripts/setPoliciesURIs.sh config/policies.v2.{devnet,testnet,mainnet-neo}.json",
"populate:policies:devnet": "hardhat populate:policy-registry --from v2_devnet --network arbitrumSepoliaDevnet",
"populate:policies:testnet": "hardhat populate:policy-registry --from v2_testnet --network arbitrumSepolia",
"populate:policies:mainnetNeo": "hardhat populate:policy-registry --core-type neo --from v2_mainnet_neo --network arbitrum",
"populate:policies:mainnetNeo": "hardhat populate:policy-registry --from v2_mainnet_neo --network arbitrum",
"release:patch": "scripts/publish.sh patch",
"release:minor": "scripts/publish.sh minor",
"release:major": "scripts/publish.sh major",
Expand Down
72 changes: 72 additions & 0 deletions contracts/scripts/changeGovernor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { task } from "hardhat/config";
import { prompt, print } from "gluegun";
import { Cores, getContracts } from "./utils/contracts";

const { bold } = print.colors;

task("change-governor", "Changes the governor for all the contracts")
.addPositionalParam("newGovernor", "The address of the new governor")
.addOptionalParam("coreType", "The type of core to use between base, neo, university (default: base)", Cores.BASE)
.setAction(async (taskArgs, hre) => {
const newGovernor = taskArgs.newGovernor;
print.highlight(`💣 Changing governor to ${bold(newGovernor)}`);

const { confirm } = await prompt.ask({
type: "confirm",
name: "confirm",
message: "Are you sure you want to proceed?",
});
if (!confirm) {
console.log("Operation cancelled by user.");
return;
}

const coreType = Cores[taskArgs.coreType.toUpperCase() as keyof typeof Cores];
if (coreType === undefined) {
console.error("Invalid core type, must be one of base, neo, university");
return;
}
console.log("Using core type %s", coreType);

const {
core,
disputeKitClassic,
disputeResolver,
disputeTemplateRegistry,
policyRegistry,
chainlinkRng,
randomizerRng,
snapshotProxy,
} = await getContracts(hre, coreType);

const updateGovernor = async (contractName: string, contractInstance: any) => {
print.info(`Changing governor for ${contractName}`);

const spinner = print.spin(`Executing transaction for ${contractName}...`);
try {
const tx = await contractInstance.changeGovernor(newGovernor);
await tx.wait();
spinner.succeed(`Governor changed for ${contractName}, tx hash: ${tx.hash}`);
} catch (error) {
if (error instanceof Error) {
spinner.fail(`Failed to change governor for ${contractName}: ${error.message}`);
} else {
spinner.fail(`Failed to change governor for ${contractName}: ${String(error)}`);
}
}
};
Comment on lines +42 to +57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance error handling and transaction validation.

The current implementation could be improved with better error handling and transaction receipt validation.

     const updateGovernor = async (contractName: string, contractInstance: any) => {
+      if (!contractInstance?.changeGovernor) {
+        throw new Error(`Contract ${contractName} does not implement changeGovernor`);
+      }
       print.info(`Changing governor for ${contractName}`);
 
       const spinner = print.spin(`Executing transaction for ${contractName}...`);
       try {
         const tx = await contractInstance.changeGovernor(newGovernor);
-        await tx.wait();
+        const receipt = await tx.wait();
+        if (receipt.status === 0) {
+          throw new Error('Transaction reverted');
+        }
         spinner.succeed(`Governor changed for ${contractName}, tx hash: ${tx.hash}`);
       } catch (error) {
+        const errorMessage = error instanceof Error ? error.message : String(error);
+        console.error(`Transaction details for ${contractName}:`, error);
-        if (error instanceof Error) {
-          spinner.fail(`Failed to change governor for ${contractName}: ${error.message}`);
-        } else {
-          spinner.fail(`Failed to change governor for ${contractName}: ${String(error)}`);
-        }
+        spinner.fail(`Failed to change governor for ${contractName}: ${errorMessage}`);
+        throw error; // Re-throw to stop execution
       }
     };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const updateGovernor = async (contractName: string, contractInstance: any) => {
print.info(`Changing governor for ${contractName}`);
const spinner = print.spin(`Executing transaction for ${contractName}...`);
try {
const tx = await contractInstance.changeGovernor(newGovernor);
await tx.wait();
spinner.succeed(`Governor changed for ${contractName}, tx hash: ${tx.hash}`);
} catch (error) {
if (error instanceof Error) {
spinner.fail(`Failed to change governor for ${contractName}: ${error.message}`);
} else {
spinner.fail(`Failed to change governor for ${contractName}: ${String(error)}`);
}
}
};
const updateGovernor = async (contractName: string, contractInstance: any) => {
if (!contractInstance?.changeGovernor) {
throw new Error(`Contract ${contractName} does not implement changeGovernor`);
}
print.info(`Changing governor for ${contractName}`);
const spinner = print.spin(`Executing transaction for ${contractName}...`);
try {
const tx = await contractInstance.changeGovernor(newGovernor);
const receipt = await tx.wait();
if (receipt.status === 0) {
throw new Error('Transaction reverted');
}
spinner.succeed(`Governor changed for ${contractName}, tx hash: ${tx.hash}`);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error(`Transaction details for ${contractName}:`, error);
spinner.fail(`Failed to change governor for ${contractName}: ${errorMessage}`);
throw error; // Re-throw to stop execution
}
};


// TODO: upgrade and add changeGovernor!
// await updateGovernor("SortitionModule", sortition)

await updateGovernor("KlerosCore", core);
await updateGovernor("DisputeKitClassic", disputeKitClassic);
await updateGovernor("DisputeResolver", disputeResolver);
await updateGovernor("DisputeTemplateRegistry", disputeTemplateRegistry);
await updateGovernor("PolicyRegistry", policyRegistry);
await updateGovernor("KlerosCoreSnapshotProxy", snapshotProxy);
if (chainlinkRng) await updateGovernor("ChainlinkRNG", chainlinkRng);
if (randomizerRng) await updateGovernor("RandomizerRNG", randomizerRng);

print.success("Governor changed successfully");
});
Loading
Loading