From 2bffa61931f99b8d772f180511638d40f885f278 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Sat, 15 Mar 2025 00:49:17 +0000 Subject: [PATCH 01/26] chore: shutter script experiment --- contracts/package.json | 2 + contracts/scripts/shutter.ts | 127 +++++++++++++++++++++++++++++++++++ yarn.lock | 74 ++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 contracts/scripts/shutter.ts diff --git a/contracts/package.json b/contracts/package.json index 0b4d3dd75..101f5ec34 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -157,6 +157,8 @@ "@chainlink/contracts": "^1.3.0", "@kleros/vea-contracts": "^0.6.0", "@openzeppelin/contracts": "^5.2.0", + "@shutter-network/shutter-sdk": "^0.0.1", + "isomorphic-fetch": "^3.0.0", "viem": "^2.24.1" } } diff --git a/contracts/scripts/shutter.ts b/contracts/scripts/shutter.ts new file mode 100644 index 000000000..e5ad5bd77 --- /dev/null +++ b/contracts/scripts/shutter.ts @@ -0,0 +1,127 @@ +import { encryptData } from "@shutter-network/shutter-sdk"; +import { Hex, stringToHex } from "viem"; +import crypto from "crypto"; +import "isomorphic-fetch"; + +interface ShutterApiMessageData { + eon: number; + identity: string; + identity_prefix: string; + eon_key: string; + tx_hash: string; +} + +interface ShutterApiResponse { + message: ShutterApiMessageData; + error?: string; +} + +/** + * Fetches encryption data from the Shutter API + * @param decryptionTimestamp Unix timestamp when decryption should be possible + * @returns Promise with the eon key and identity + */ +async function fetchShutterData(decryptionTimestamp: number): Promise { + try { + console.log(`Sending request to Shutter API with decryption timestamp: ${decryptionTimestamp}`); + + const response = await fetch("https://shutter-api.shutter.network/api/register_identity", { + method: "POST", + headers: { + accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify({ decryptionTimestamp }), + }); + + // Log the response status + console.log(`API response status: ${response.status}`); + + // Get the response text + const responseText = await response.text(); + + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}: ${responseText}`); + } + + // Parse the JSON response + let jsonResponse: ShutterApiResponse; + try { + jsonResponse = JSON.parse(responseText); + } catch (error) { + throw new Error(`Failed to parse API response as JSON: ${responseText}`); + } + + // Check if we have the message data + if (!jsonResponse.message) { + throw new Error(`API response missing message data: ${JSON.stringify(jsonResponse)}`); + } + + return jsonResponse.message; + } catch (error) { + console.error("Error fetching data from Shutter API:", error); + throw error; + } +} + +/** + * Ensures a string is a valid hex string with 0x prefix + * @param hexString The hex string to validate + * @returns The validated hex string with 0x prefix + */ +function ensureHexString(hexString: string | undefined): `0x${string}` { + if (!hexString) { + throw new Error("Hex string is undefined or null"); + } + + // Add 0x prefix if it doesn't exist + const prefixedHex = hexString.startsWith("0x") ? hexString : `0x${hexString}`; + return prefixedHex as `0x${string}`; +} + +/** + * Generates a random sigma value (32 bytes) + * @returns Random sigma as a hex string with 0x prefix + */ +function generateRandomSigma(): `0x${string}` { + return ("0x" + + crypto + .getRandomValues(new Uint8Array(32)) + .reduce((acc, byte) => acc + byte.toString(16).padStart(2, "0"), "")) as Hex; +} + +async function main() { + try { + // Set decryption timestamp (e.g., 24 hours from now) + const decryptionTimestamp = Math.floor(Date.now() / 1000) + 86400; // 24 hours from now + + // Fetch encryption data from Shutter API + console.log(`Fetching encryption data for decryption at timestamp ${decryptionTimestamp}...`); + const shutterData = await fetchShutterData(decryptionTimestamp); + + // Extract the eon key and identity from the response and ensure they have the correct format + const eonKeyHex = ensureHexString(shutterData.eon_key); + const identityHex = ensureHexString(shutterData.identity); + + // Message to encrypt + const msgHex = stringToHex("my very secret vote"); + + // Generate a random sigma + const sigmaHex = generateRandomSigma(); + + console.log("Eon Key:", eonKeyHex); + console.log("Identity:", identityHex); + console.log("Sigma:", sigmaHex); + + // Encrypt the message + const encryptedCommitment = await encryptData(msgHex, identityHex, eonKeyHex, sigmaHex); + + // Print the encrypted commitment + console.log("Encrypted Commitment:", encryptedCommitment); + } catch (error) { + console.error("Error:", error); + } +} + +// Execute the main function +main(); diff --git a/yarn.lock b/yarn.lock index 6aa34039e..f46f859f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5560,6 +5560,7 @@ __metadata: "@nomiclabs/hardhat-solhint": "npm:^4.0.1" "@openzeppelin/contracts": "npm:^5.2.0" "@openzeppelin/upgrades-core": "npm:^1.42.2" + "@shutter-network/shutter-sdk": "npm:^0.0.1" "@typechain/ethers-v6": "npm:^0.5.1" "@typechain/hardhat": "npm:^9.1.0" "@types/chai": "npm:^4.3.20" @@ -5585,6 +5586,7 @@ __metadata: hardhat-gas-reporter: "npm:^2.2.2" hardhat-tracer: "npm:^3.1.0" hardhat-watcher: "npm:^2.5.0" + isomorphic-fetch: "npm:^3.0.0" node-fetch: "npm:^3.3.2" pino: "npm:^8.21.0" pino-pretty: "npm:^10.3.1" @@ -6888,6 +6890,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:1.8.2": + version: 1.8.2 + resolution: "@noble/curves@npm:1.8.2" + dependencies: + "@noble/hashes": "npm:1.7.2" + checksum: 10/540e7b7a8fe92ecd5cef846f84d07180662eb7fd7d8e9172b8960c31827e74f148fe4630da962138a6be093ae9f8992d14ab23d3682a2cc32be839aa57c03a46 + languageName: node + linkType: hard + "@noble/curves@npm:^1.7.0": version: 1.7.0 resolution: "@noble/curves@npm:1.7.0" @@ -6946,6 +6957,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.7.2": + version: 1.7.2 + resolution: "@noble/hashes@npm:1.7.2" + checksum: 10/b5af9e4b91543dcc46a811b5b2c57bfdeb41728361979a19d6110a743e2cb0459872553f68d3a46326d21959964db2776b8c8b4db85ac1d9f63ebcaddf7d59b6 + languageName: node + linkType: hard + "@noble/hashes@npm:^1.6.1": version: 1.6.1 resolution: "@noble/hashes@npm:1.6.1" @@ -8561,6 +8579,17 @@ __metadata: languageName: node linkType: hard +"@shutter-network/shutter-sdk@npm:^0.0.1": + version: 0.0.1 + resolution: "@shutter-network/shutter-sdk@npm:0.0.1" + dependencies: + browser-or-node: "npm:^3.0.0" + lodash: "npm:^4.17.21" + viem: "npm:^2.23.2" + checksum: 10/5e021c9dc27cb88dd487e1a289501394302d88fe349a873525610405eb2b351563556b1d0ef2ac789cff99b03ba6019c0a9761a093a0aef5a82941986ca58517 + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.24.1": version: 0.24.51 resolution: "@sinclair/typebox@npm:0.24.51" @@ -12986,6 +13015,13 @@ __metadata: languageName: node linkType: hard +"browser-or-node@npm:^3.0.0": + version: 3.0.0 + resolution: "browser-or-node@npm:3.0.0" + checksum: 10/51d74cc5d0139da3d37e83ff3906fcca20d02c42aa8b81a48d9ea01806f36df1a4b55006670071b1d7423967777275920054ec8b723410534b580b0232c5093d + languageName: node + linkType: hard + "browser-process-hrtime@npm:^1.0.0": version: 1.0.0 resolution: "browser-process-hrtime@npm:1.0.0" @@ -21179,6 +21215,16 @@ __metadata: languageName: node linkType: hard +"isomorphic-fetch@npm:^3.0.0": + version: 3.0.0 + resolution: "isomorphic-fetch@npm:3.0.0" + dependencies: + node-fetch: "npm:^2.6.1" + whatwg-fetch: "npm:^3.4.1" + checksum: 10/568fe0307528c63405c44dd3873b7b6c96c0d19ff795cb15846e728b6823bdbc68cc8c97ac23324509661316f12f551e43dac2929bc7030b8bc4d6aa1158b857 + languageName: node + linkType: hard + "isomorphic-timers-promises@npm:^1.0.1": version: 1.0.1 resolution: "isomorphic-timers-promises@npm:1.0.1" @@ -33420,6 +33466,27 @@ __metadata: languageName: node linkType: hard +"viem@npm:^2.23.2": + version: 2.28.0 + resolution: "viem@npm:2.28.0" + dependencies: + "@noble/curves": "npm:1.8.2" + "@noble/hashes": "npm:1.7.2" + "@scure/bip32": "npm:1.6.2" + "@scure/bip39": "npm:1.5.4" + abitype: "npm:1.0.8" + isows: "npm:1.0.6" + ox: "npm:0.6.9" + ws: "npm:8.18.1" + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/fbdf2ce3020b0ee37457726375cb2479cf716e5ef021470a79f2713c5def1ae53c881458cc3853d1cab8ba655385280aeebbdc155e81b8cb54c6387758e59435 + languageName: node + linkType: hard + "vite-node@npm:1.6.0": version: 1.6.0 resolution: "vite-node@npm:1.6.0" @@ -34149,6 +34216,13 @@ __metadata: languageName: node linkType: hard +"whatwg-fetch@npm:^3.4.1": + version: 3.6.20 + resolution: "whatwg-fetch@npm:3.6.20" + checksum: 10/2b4ed92acd6a7ad4f626a6cb18b14ec982bbcaf1093e6fe903b131a9c6decd14d7f9c9ca3532663c2759d1bdf01d004c77a0adfb2716a5105465c20755a8c57c + languageName: node + linkType: hard + "whatwg-fetch@npm:^3.6.2": version: 3.6.2 resolution: "whatwg-fetch@npm:3.6.2" From 3570b46675771cae2a3c601d3220793cd383e60c Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 19 Mar 2025 19:19:24 +0000 Subject: [PATCH 02/26] feat(shutter): added decryption logic --- contracts/scripts/shutter.ts | 206 ++++++++++++++++++++++++++++++----- 1 file changed, 179 insertions(+), 27 deletions(-) diff --git a/contracts/scripts/shutter.ts b/contracts/scripts/shutter.ts index e5ad5bd77..6a7c73f90 100644 --- a/contracts/scripts/shutter.ts +++ b/contracts/scripts/shutter.ts @@ -1,5 +1,5 @@ -import { encryptData } from "@shutter-network/shutter-sdk"; -import { Hex, stringToHex } from "viem"; +import { encryptData, decrypt as shutterDecrypt } from "@shutter-network/shutter-sdk"; +import { Hex, stringToHex, hexToString } from "viem"; import crypto from "crypto"; import "isomorphic-fetch"; @@ -16,6 +16,17 @@ interface ShutterApiResponse { error?: string; } +interface ShutterDecryptionKeyData { + decryption_key: string; + identity: string; + decryption_timestamp: number; +} + +interface ShutterDecryptionKeyResponse { + message: ShutterDecryptionKeyData; + error?: string; +} + /** * Fetches encryption data from the Shutter API * @param decryptionTimestamp Unix timestamp when decryption should be possible @@ -25,13 +36,20 @@ async function fetchShutterData(decryptionTimestamp: number): Promise { + try { + console.log(`Fetching decryption key for identity: ${identity}`); + + const response = await fetch(`https://shutter-api.shutter.network/api/get_decryption_key?identity=${identity}`, { + method: "GET", + headers: { + accept: "application/json", + }, + }); + + // Log the response status + console.log(`API response status: ${response.status}`); + + // Get the response text + const responseText = await response.text(); + + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}: ${responseText}`); + } + + // Parse the JSON response + let jsonResponse: ShutterDecryptionKeyResponse; + try { + jsonResponse = JSON.parse(responseText); + } catch (error) { + throw new Error(`Failed to parse API response as JSON: ${responseText}`); + } + + // Check if we have the message data + if (!jsonResponse.message) { + throw new Error(`API response missing message data: ${JSON.stringify(jsonResponse)}`); + } + + return jsonResponse.message; + } catch (error) { + console.error("Error fetching decryption key:", error); + throw error; + } +} + /** * Ensures a string is a valid hex string with 0x prefix * @param hexString The hex string to validate @@ -80,46 +144,134 @@ function ensureHexString(hexString: string | undefined): `0x${string}` { } /** - * Generates a random sigma value (32 bytes) - * @returns Random sigma as a hex string with 0x prefix + * Generates a random 32 bytes + * @returns Random 32 bytes as a hex string with 0x prefix */ -function generateRandomSigma(): `0x${string}` { +function generateRandomBytes32(): `0x${string}` { return ("0x" + crypto .getRandomValues(new Uint8Array(32)) .reduce((acc, byte) => acc + byte.toString(16).padStart(2, "0"), "")) as Hex; } -async function main() { +/** + * Encrypts a message using the Shutter API + * @param message The message to encrypt + * @returns Promise with the encrypted commitment + */ +async function encrypt(message: string): Promise { + // Set decryption timestamp + const decryptionTimestamp = Math.floor(Date.now() / 1000) + 120; + + // Fetch encryption data from Shutter API + console.log(`Fetching encryption data for decryption at timestamp ${decryptionTimestamp}...`); + const shutterData = await fetchShutterData(decryptionTimestamp); + + // Extract the eon key and identity from the response and ensure they have the correct format + const eonKeyHex = ensureHexString(shutterData.eon_key); + const identityHex = ensureHexString(shutterData.identity); + + // Message to encrypt + const msgHex = stringToHex(message); + + // Generate a random sigma + const sigmaHex = generateRandomBytes32(); + + console.log("Eon Key:", eonKeyHex); + console.log("Identity:", identityHex); + console.log("Sigma:", sigmaHex); + + // Encrypt the message + const encryptedCommitment = await encryptData(msgHex, identityHex, eonKeyHex, sigmaHex); + + return encryptedCommitment; +} + +/** + * Decrypts a message using the Shutter API + * @param encryptedMessage The encrypted message to decrypt + * @returns Promise with the decrypted message + */ +async function decrypt(encryptedMessage: string): Promise { try { - // Set decryption timestamp (e.g., 24 hours from now) - const decryptionTimestamp = Math.floor(Date.now() / 1000) + 86400; // 24 hours from now + // Extract the identity from the encrypted message + // TODO: In a real implementation, you would need to store and retrieve the identity + // used for encryption. For now, we'll need to pass it as an additional parameter + // or store it alongside the encrypted message. + const identity = process.argv[4]; // Temporary solution: pass identity as an additional argument + if (!identity) { + throw new Error("Please provide the identity used for encryption as the third argument"); + } - // Fetch encryption data from Shutter API - console.log(`Fetching encryption data for decryption at timestamp ${decryptionTimestamp}...`); - const shutterData = await fetchShutterData(decryptionTimestamp); + // Fetch the decryption key + const decryptionKeyData = await fetchDecryptionKey(identity); + console.log("Decryption key:", decryptionKeyData.decryption_key); - // Extract the eon key and identity from the response and ensure they have the correct format - const eonKeyHex = ensureHexString(shutterData.eon_key); - const identityHex = ensureHexString(shutterData.identity); + // Ensure the decryption key is properly formatted + const decryptionKey = ensureHexString(decryptionKeyData.decryption_key); - // Message to encrypt - const msgHex = stringToHex("my very secret vote"); + // Decrypt the message + const decryptedHexMessage = await shutterDecrypt(encryptedMessage, decryptionKey); - // Generate a random sigma - const sigmaHex = generateRandomSigma(); + // Convert the decrypted hex message back to a string + return hexToString(decryptedHexMessage as `0x${string}`); + } catch (error) { + console.error("Error during decryption:", error); + throw error; + } +} + +async function main() { + try { + const command = process.argv[2]?.toLowerCase(); + + if (!command) { + console.error(` +Usage: yarn ts-node shutter.ts [arguments] - console.log("Eon Key:", eonKeyHex); - console.log("Identity:", identityHex); - console.log("Sigma:", sigmaHex); +Commands: + encrypt Encrypt a message + decrypt Decrypt a message (requires the identity used during encryption) - // Encrypt the message - const encryptedCommitment = await encryptData(msgHex, identityHex, eonKeyHex, sigmaHex); +Examples: + yarn ts-node shutter.ts encrypt "my secret message" + yarn ts-node shutter.ts decrypt "encrypted-data" "0x1234..."`); + process.exit(1); + } - // Print the encrypted commitment - console.log("Encrypted Commitment:", encryptedCommitment); + switch (command) { + case "encrypt": { + const message = process.argv[3]; + if (!message) { + console.error("Error: Missing message to encrypt"); + console.error("Usage: yarn ts-node shutter.ts encrypt "); + process.exit(1); + } + const encryptedCommitment = await encrypt(message); + console.log("\nEncrypted Commitment:", encryptedCommitment); + break; + } + case "decrypt": { + const [encryptedMessage, identity] = [process.argv[3], process.argv[4]]; + if (!encryptedMessage || !identity) { + console.error("Error: Missing required arguments for decrypt"); + console.error("Usage: yarn ts-node shutter.ts decrypt "); + console.error("Note: The identity is the one returned during encryption"); + process.exit(1); + } + const decryptedMessage = await decrypt(encryptedMessage); + console.log("\nDecrypted Message:", decryptedMessage); + break; + } + default: { + console.error(`Error: Unknown command '${command}'`); + console.error("Valid commands are: encrypt, decrypt"); + process.exit(1); + } + } } catch (error) { - console.error("Error:", error); + console.error("\nError:", error); + process.exit(1); } } From ddae29a78d5640b1a100bd808706bedf49e464e5 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 19 Mar 2025 19:30:52 +0000 Subject: [PATCH 03/26] fix: better error handling --- contracts/scripts/shutter.ts | 106 +++++++++++++++++------------------ 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/contracts/scripts/shutter.ts b/contracts/scripts/shutter.ts index 6a7c73f90..aab9eff4a 100644 --- a/contracts/scripts/shutter.ts +++ b/contracts/scripts/shutter.ts @@ -3,6 +3,9 @@ import { Hex, stringToHex, hexToString } from "viem"; import crypto from "crypto"; import "isomorphic-fetch"; +/** Time in seconds to wait before the message can be decrypted */ +const DECRYPTION_DELAY = 120; // 2 minutes + interface ShutterApiMessageData { eon: number; identity: string; @@ -88,44 +91,44 @@ async function fetchShutterData(decryptionTimestamp: number): Promise { - try { - console.log(`Fetching decryption key for identity: ${identity}`); + console.log(`Fetching decryption key for identity: ${identity}`); - const response = await fetch(`https://shutter-api.shutter.network/api/get_decryption_key?identity=${identity}`, { - method: "GET", - headers: { - accept: "application/json", - }, - }); + const response = await fetch(`https://shutter-api.shutter.network/api/get_decryption_key?identity=${identity}`, { + method: "GET", + headers: { + accept: "application/json", + }, + }); - // Log the response status - console.log(`API response status: ${response.status}`); + // Get the response text + const responseText = await response.text(); - // Get the response text - const responseText = await response.text(); - - if (!response.ok) { - throw new Error(`API request failed with status ${response.status}: ${responseText}`); - } - - // Parse the JSON response - let jsonResponse: ShutterDecryptionKeyResponse; - try { - jsonResponse = JSON.parse(responseText); - } catch (error) { - throw new Error(`Failed to parse API response as JSON: ${responseText}`); - } + // Try to parse the error response even if the request failed + let jsonResponse; + try { + jsonResponse = JSON.parse(responseText); + } catch (error) { + throw new Error(`Failed to parse API response as JSON: ${responseText}`); + } - // Check if we have the message data - if (!jsonResponse.message) { - throw new Error(`API response missing message data: ${JSON.stringify(jsonResponse)}`); + // Handle the "too early" error case specifically + if (!response.ok) { + if (jsonResponse?.description?.includes("timestamp not reached yet")) { + throw new Error( + `Cannot decrypt yet: The decryption timestamp has not been reached.\n` + + `Please wait at least ${DECRYPTION_DELAY} seconds after encryption before attempting to decrypt.\n` + + `Error details: ${jsonResponse.description}` + ); } + throw new Error(`API request failed with status ${response.status}: ${responseText}`); + } - return jsonResponse.message; - } catch (error) { - console.error("Error fetching decryption key:", error); - throw error; + // Check if we have the message data + if (!jsonResponse.message) { + throw new Error(`API response missing message data: ${JSON.stringify(jsonResponse)}`); } + + return jsonResponse.message; } /** @@ -161,7 +164,7 @@ function generateRandomBytes32(): `0x${string}` { */ async function encrypt(message: string): Promise { // Set decryption timestamp - const decryptionTimestamp = Math.floor(Date.now() / 1000) + 120; + const decryptionTimestamp = Math.floor(Date.now() / 1000) + DECRYPTION_DELAY; // Fetch encryption data from Shutter API console.log(`Fetching encryption data for decryption at timestamp ${decryptionTimestamp}...`); @@ -193,32 +196,27 @@ async function encrypt(message: string): Promise { * @returns Promise with the decrypted message */ async function decrypt(encryptedMessage: string): Promise { - try { - // Extract the identity from the encrypted message - // TODO: In a real implementation, you would need to store and retrieve the identity - // used for encryption. For now, we'll need to pass it as an additional parameter - // or store it alongside the encrypted message. - const identity = process.argv[4]; // Temporary solution: pass identity as an additional argument - if (!identity) { - throw new Error("Please provide the identity used for encryption as the third argument"); - } + // Extract the identity from the encrypted message + // TODO: In a real implementation, you would need to store and retrieve the identity + // used for encryption. For now, we'll need to pass it as an additional parameter + // or store it alongside the encrypted message. + const identity = process.argv[4]; // Temporary solution: pass identity as an additional argument + if (!identity) { + throw new Error("Please provide the identity used for encryption as the third argument"); + } - // Fetch the decryption key - const decryptionKeyData = await fetchDecryptionKey(identity); - console.log("Decryption key:", decryptionKeyData.decryption_key); + // Fetch the decryption key + const decryptionKeyData = await fetchDecryptionKey(identity); + console.log("Decryption key:", decryptionKeyData.decryption_key); - // Ensure the decryption key is properly formatted - const decryptionKey = ensureHexString(decryptionKeyData.decryption_key); + // Ensure the decryption key is properly formatted + const decryptionKey = ensureHexString(decryptionKeyData.decryption_key); - // Decrypt the message - const decryptedHexMessage = await shutterDecrypt(encryptedMessage, decryptionKey); + // Decrypt the message + const decryptedHexMessage = await shutterDecrypt(encryptedMessage, decryptionKey); - // Convert the decrypted hex message back to a string - return hexToString(decryptedHexMessage as `0x${string}`); - } catch (error) { - console.error("Error during decryption:", error); - throw error; - } + // Convert the decrypted hex message back to a string + return hexToString(decryptedHexMessage as `0x${string}`); } async function main() { From 04e3f5c42a06d961652aca9eb14acd1d60dd40bd Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 24 Apr 2025 20:58:06 +0100 Subject: [PATCH 04/26] feat: naive shutterized dispute kit and auto-voting bot --- contracts/deploy/09-shutter.ts | 26 +++ contracts/scripts/shutter.ts | 35 ++- contracts/scripts/shutterAutoVote.ts | 210 ++++++++++++++++++ .../dispute-kits/DisputeKitShutterPoC.sol | 105 +++++++++ 4 files changed, 356 insertions(+), 20 deletions(-) create mode 100644 contracts/deploy/09-shutter.ts create mode 100644 contracts/scripts/shutterAutoVote.ts create mode 100644 contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol diff --git a/contracts/deploy/09-shutter.ts b/contracts/deploy/09-shutter.ts new file mode 100644 index 000000000..b8d53fb1a --- /dev/null +++ b/contracts/deploy/09-shutter.ts @@ -0,0 +1,26 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { HomeChains, isSkipped } from "./utils"; + +const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, getNamedAccounts, getChainId } = hre; + const { deploy } = deployments; + + // 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); + + await deploy("DisputeKitShutterPoC", { + from: deployer, + args: [], + log: true, + }); +}; + +deployArbitration.tags = ["Shutter"]; +deployArbitration.skip = async ({ network }) => { + return isSkipped(network, !HomeChains[network.config.chainId ?? 0]); +}; + +export default deployArbitration; diff --git a/contracts/scripts/shutter.ts b/contracts/scripts/shutter.ts index aab9eff4a..f4d917d6d 100644 --- a/contracts/scripts/shutter.ts +++ b/contracts/scripts/shutter.ts @@ -4,7 +4,7 @@ import crypto from "crypto"; import "isomorphic-fetch"; /** Time in seconds to wait before the message can be decrypted */ -const DECRYPTION_DELAY = 120; // 2 minutes +export const DECRYPTION_DELAY = 20; interface ShutterApiMessageData { eon: number; @@ -160,9 +160,9 @@ function generateRandomBytes32(): `0x${string}` { /** * Encrypts a message using the Shutter API * @param message The message to encrypt - * @returns Promise with the encrypted commitment + * @returns Promise with the encrypted commitment and identity */ -async function encrypt(message: string): Promise { +export async function encrypt(message: string): Promise<{ encryptedCommitment: string; identity: string }> { // Set decryption timestamp const decryptionTimestamp = Math.floor(Date.now() / 1000) + DECRYPTION_DELAY; @@ -187,24 +187,16 @@ async function encrypt(message: string): Promise { // Encrypt the message const encryptedCommitment = await encryptData(msgHex, identityHex, eonKeyHex, sigmaHex); - return encryptedCommitment; + return { encryptedCommitment, identity: identityHex }; } /** * Decrypts a message using the Shutter API * @param encryptedMessage The encrypted message to decrypt + * @param identity The identity used for encryption * @returns Promise with the decrypted message */ -async function decrypt(encryptedMessage: string): Promise { - // Extract the identity from the encrypted message - // TODO: In a real implementation, you would need to store and retrieve the identity - // used for encryption. For now, we'll need to pass it as an additional parameter - // or store it alongside the encrypted message. - const identity = process.argv[4]; // Temporary solution: pass identity as an additional argument - if (!identity) { - throw new Error("Please provide the identity used for encryption as the third argument"); - } - +export async function decrypt(encryptedMessage: string, identity: string): Promise { // Fetch the decryption key const decryptionKeyData = await fetchDecryptionKey(identity); console.log("Decryption key:", decryptionKeyData.decryption_key); @@ -228,8 +220,8 @@ async function main() { Usage: yarn ts-node shutter.ts [arguments] Commands: - encrypt Encrypt a message - decrypt Decrypt a message (requires the identity used during encryption) + encrypt Encrypt a message + decrypt Decrypt a message (requires the identity used during encryption) Examples: yarn ts-node shutter.ts encrypt "my secret message" @@ -245,8 +237,9 @@ Examples: console.error("Usage: yarn ts-node shutter.ts encrypt "); process.exit(1); } - const encryptedCommitment = await encrypt(message); + const { encryptedCommitment, identity } = await encrypt(message); console.log("\nEncrypted Commitment:", encryptedCommitment); + console.log("Identity:", identity); break; } case "decrypt": { @@ -257,7 +250,7 @@ Examples: console.error("Note: The identity is the one returned during encryption"); process.exit(1); } - const decryptedMessage = await decrypt(encryptedMessage); + const decryptedMessage = await decrypt(encryptedMessage, identity); console.log("\nDecrypted Message:", decryptedMessage); break; } @@ -273,5 +266,7 @@ Examples: } } -// Execute the main function -main(); +// Execute if run directly +if (require.main === module) { + main(); +} diff --git a/contracts/scripts/shutterAutoVote.ts b/contracts/scripts/shutterAutoVote.ts new file mode 100644 index 000000000..f1990256d --- /dev/null +++ b/contracts/scripts/shutterAutoVote.ts @@ -0,0 +1,210 @@ +/** + * TODO: + * The goal is to automatically decrypt each encrypted voteID previously cast as encrypted commitments, and cast them as votes. + * - modify shutter.ts encrypt() to return {encryptedCommitment, identity} + * - implement shutterAutoVote.ts that: + * - provides a castCommit() function which + * - calls shutter.ts encrypt() with the message "disputeId␟voteId␟choice␟justification" with `U+241F` as separator + * - calls the DisputeKitShutterPoC.castCommit() function with the encryptedCommitment, voteId, choice and justification + * - retrieve the DisputeKitShutterPoC.CommitCast event and log its parameters + * - provides an autoVote() function which + * - runs continuously as a loop, waking up every 30 seconds + * - upon wake up, retrieve the details of the previously encrypted messages (and corresponding identities) which have not yet been decrypted and have been encrypted for more than shutter.ts `DECRYPTION_DELAY`. + * - for each of these messages, call shutter.ts decrypt() with the identity and the encryptedCommitment + * - if the decryption is successful, call the DisputeKitShutterPoC.castVote() function with the voteId, choice and justification + * - if the decryption is not successful, log an error + * - if the castVote() function was called, retrieve the DisputeKitShutterPoC.VoteCast event and log its parameters + * - shutterAutoVote.ts needs to know: + * - the _voteIDs: they start from 0 and go up to DisputeKitShutterPoC.maxVoteIDs() + * - the _coreDisputeID: just use 0 for now. + **/ + +import { createPublicClient, createWalletClient, http, Hex, decodeEventLog, Log, getContract } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { hardhat } from "viem/chains"; +import { encrypt, decrypt, DECRYPTION_DELAY } from "./shutter"; +import dotenv from "dotenv"; +import { abi as DisputeKitShutterPoCAbi } from "../deployments/localhost/DisputeKitShutterPoC.json"; + +// Load environment variables +dotenv.config(); + +// Constants +const SEPARATOR = "␟"; // U+241F + +// Validate environment variables +if (!process.env.PRIVATE_KEY) throw new Error("PRIVATE_KEY environment variable is required"); + +/** + * Split a hex string into bytes32 chunks + */ +function splitToBytes32(hex: string): Hex[] { + // Remove 0x prefix if present + const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex; + + // Split into chunks of 64 characters (32 bytes) + const chunks: Hex[] = []; + for (let i = 0; i < cleanHex.length; i += 64) { + const chunk = `0x${cleanHex.slice(i, i + 64)}` as Hex; + chunks.push(chunk); + } + + return chunks; +} + +// Store encrypted votes for later decryption +interface EncryptedVote { + encryptedCommitment: string; + identity: Hex; + timestamp: number; + voteId: bigint; +} + +const encryptedVotes: EncryptedVote[] = []; + +// Initialize Viem clients +const publicClient = createPublicClient({ + chain: hardhat, + transport: http(), +}); + +const PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" as Hex; +const CONTRACT_ADDRESS = "0x5FbDB2315678afecb367f032d93F642f64180aa3" as const; + +const account = privateKeyToAccount(PRIVATE_KEY); +const walletClient = createWalletClient({ + account, + chain: hardhat, + transport: http(), +}); + +const disputeKit = getContract({ + address: CONTRACT_ADDRESS, + abi: DisputeKitShutterPoCAbi, + client: { public: publicClient, wallet: walletClient }, +}); + +/** + * Cast an encrypted commit for a vote + */ +export async function castCommit({ + disputeId, + voteId, + choice, + justification, +}: { + disputeId: bigint; + voteId: bigint; + choice: bigint; + justification: string; +}) { + try { + // Create message with U+241F separator + const message = `${disputeId}${SEPARATOR}${voteId}${SEPARATOR}${choice}${SEPARATOR}${justification}`; + + // Encrypt the message + const { encryptedCommitment, identity } = await encrypt(message); + + // Split encrypted commitment into bytes32 chunks + const commitmentChunks = splitToBytes32(encryptedCommitment); + console.log("Commitment chunks:", commitmentChunks); + + // Cast the commit on-chain + const hash = await disputeKit.write.castCommit([disputeId, [voteId], encryptedCommitment as Hex, identity as Hex]); + + // Store encrypted vote for later decryption + encryptedVotes.push({ + encryptedCommitment, + identity: identity as Hex, + timestamp: Math.floor(Date.now() / 1000), + voteId, + }); + + // Watch for CommitCast event + const events = await disputeKit.getEvents.CommitCast(); + console.log("CommitCast event:", (events[0] as any).args); + + return { encryptedCommitment, identity }; + } catch (error) { + console.error("Error in castCommit:", error); + throw error; + } +} + +/** + * Continuously monitor for votes ready to be decrypted and cast + */ +export async function autoVote() { + while (true) { + try { + const currentTime = Math.floor(Date.now() / 1000); + + // Find votes ready for decryption + const readyVotes = encryptedVotes.filter((vote) => currentTime - vote.timestamp >= DECRYPTION_DELAY); + console.log("Ready votes:", readyVotes); + + for (const vote of readyVotes) { + try { + console.log("Decrypting vote:", vote); + + // Attempt to decrypt the vote + const decryptedMessage = await decrypt(vote.encryptedCommitment, vote.identity); + console.log("Decrypted message:", decryptedMessage); + + // Parse the decrypted message + const [, , choice, justification] = decryptedMessage.split(SEPARATOR); + + // Cast the vote on-chain + const hash = await disputeKit.write.castVote([ + BigInt(0), + [vote.voteId], + BigInt(choice), + justification, + vote.identity, + ]); + + // Watch for VoteCast event + const events = await disputeKit.getEvents.VoteCast(); + console.log("VoteCast event:", (events[0] as any).args); + + // Remove the processed vote + const index = encryptedVotes.indexOf(vote); + if (index > -1) encryptedVotes.splice(index, 1); + } catch (error) { + console.error(`Error processing vote ${vote.voteId}:`, error); + } + } + + // Sleep for 30 seconds + console.log("Sleeping for 30 seconds"); + await new Promise((resolve) => setTimeout(resolve, 30000)); + } catch (error) { + console.error("Error in autoVote loop:", error); + // Continue the loop even if there's an error + } + } +} + +// Main function to start the auto voting process +async function main() { + try { + // Cast an encrypted commit + await castCommit({ + disputeId: BigInt(0), + voteId: BigInt(0), + choice: BigInt(2), + justification: "This is my vote justification", + }); + + // Start the auto voting process + await autoVote(); + } catch (error) { + console.error("Error in main:", error); + process.exit(1); + } +} + +// Execute if run directly +if (require.main === module) { + main(); +} diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol new file mode 100644 index 000000000..6d8e5b991 --- /dev/null +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "hardhat/console.sol"; + +contract DisputeKitShutterPoC { + struct Vote { + address account; // The address of the juror. + bytes commit; // The commit of the juror. For courts with hidden votes. + bytes32 identity; // The Shutter identity. + uint256 choice; // The choice of the juror. + bool voted; // True if the vote has been cast. + } + + address public revealer; + Vote[] public votes; + uint256 public winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first. + mapping(uint256 => uint256) public counts; // The sum of votes for each choice in the form `counts[choice]`. + bool public tied; // True if there is a tie, false otherwise. + uint256 public totalCommitted; + uint256 public totalVoted; + + event CommitCast( + uint256 indexed _coreDisputeID, + address indexed _juror, + uint256[] _voteIDs, + bytes _commit, + bytes32 _identity + ); + + event VoteCast( + uint256 indexed _coreDisputeID, + address indexed _juror, + uint256[] _voteIDs, + uint256 indexed _choice, + string _justification + ); + + constructor() { + revealer = msg.sender; + address juror = msg.sender; + votes.push(Vote({account: juror, commit: bytes(""), identity: bytes32(0), choice: 0, voted: false})); + } + + function castCommit( + uint256 _coreDisputeID, + uint256[] calldata _voteIDs, + bytes calldata _commit, + bytes32 _identity + ) external { + // Store the commitment and identity for each voteID + for (uint256 i = 0; i < _voteIDs.length; i++) { + console.log("votes[_voteIDs[i]].account:", votes[_voteIDs[i]].account); + console.log("msg.sender:", msg.sender); + require(votes[_voteIDs[i]].account == msg.sender, "The caller has to own the vote."); + votes[_voteIDs[i]].commit = _commit; + votes[_voteIDs[i]].identity = _identity; + } + + totalCommitted += _voteIDs.length; + emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit, _identity); + } + + function castVote( + uint256 _coreDisputeID, + uint256[] calldata _voteIDs, + uint256 _choice, + string memory _justification, + bytes32 _identity + ) external { + require(_voteIDs.length > 0, "No voteID provided"); + require(revealer == msg.sender, "The caller has to own the vote."); + // TODO: what happens if hiddenVotes are not enabled? + for (uint256 i = 0; i < _voteIDs.length; i++) { + // Not useful to check the identity here? + require(votes[_voteIDs[i]].identity == _identity, "The identity has to match the commitment."); + + require(!votes[_voteIDs[i]].voted, "Vote already cast."); + votes[_voteIDs[i]].choice = _choice; + votes[_voteIDs[i]].voted = true; + } + + totalVoted += _voteIDs.length; + + counts[_choice] += _voteIDs.length; + if (_choice == winningChoice) { + if (tied) tied = false; + } else { + // Voted for another choice. + if (counts[_choice] == counts[winningChoice]) { + // Tie. + if (!tied) tied = true; + } else if (counts[_choice] > counts[winningChoice]) { + // New winner. + winningChoice = _choice; + tied = false; + } + } + emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification); + } + + function maxVoteIDs() public view returns (uint256) { + return votes.length - 1; + } +} From be6e1ce1d63d5cf344165d0ce925949342dc918f Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 29 Apr 2025 21:30:54 +0100 Subject: [PATCH 05/26] feat: commitment hashing and verification onchain --- contracts/scripts/shutterAutoVote.ts | 109 ++++++++---------- .../dispute-kits/DisputeKitShutterPoC.sol | 51 +++++--- 2 files changed, 82 insertions(+), 78 deletions(-) diff --git a/contracts/scripts/shutterAutoVote.ts b/contracts/scripts/shutterAutoVote.ts index f1990256d..6c1be9f75 100644 --- a/contracts/scripts/shutterAutoVote.ts +++ b/contracts/scripts/shutterAutoVote.ts @@ -19,63 +19,42 @@ * - the _coreDisputeID: just use 0 for now. **/ -import { createPublicClient, createWalletClient, http, Hex, decodeEventLog, Log, getContract } from "viem"; +import { createPublicClient, createWalletClient, http, Hex, decodeEventLog, getContract } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { hardhat } from "viem/chains"; import { encrypt, decrypt, DECRYPTION_DELAY } from "./shutter"; -import dotenv from "dotenv"; import { abi as DisputeKitShutterPoCAbi } from "../deployments/localhost/DisputeKitShutterPoC.json"; - -// Load environment variables -dotenv.config(); +import crypto from "crypto"; // Constants const SEPARATOR = "␟"; // U+241F -// Validate environment variables -if (!process.env.PRIVATE_KEY) throw new Error("PRIVATE_KEY environment variable is required"); - -/** - * Split a hex string into bytes32 chunks - */ -function splitToBytes32(hex: string): Hex[] { - // Remove 0x prefix if present - const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex; - - // Split into chunks of 64 characters (32 bytes) - const chunks: Hex[] = []; - for (let i = 0; i < cleanHex.length; i += 64) { - const chunk = `0x${cleanHex.slice(i, i + 64)}` as Hex; - chunks.push(chunk); - } - - return chunks; -} - // Store encrypted votes for later decryption interface EncryptedVote { encryptedCommitment: string; identity: Hex; timestamp: number; voteId: bigint; + salt: Hex; } const encryptedVotes: EncryptedVote[] = []; -// Initialize Viem clients +const PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" as const; + +const CONTRACT_ADDRESS = "0x5FbDB2315678afecb367f032d93F642f64180aa3" as const; + +const transport = http(); const publicClient = createPublicClient({ chain: hardhat, - transport: http(), + transport, }); -const PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" as Hex; -const CONTRACT_ADDRESS = "0x5FbDB2315678afecb367f032d93F642f64180aa3" as const; - const account = privateKeyToAccount(PRIVATE_KEY); const walletClient = createWalletClient({ account, chain: hardhat, - transport: http(), + transport, }); const disputeKit = getContract({ @@ -85,46 +64,57 @@ const disputeKit = getContract({ }); /** - * Cast an encrypted commit for a vote + * Generate a random salt */ -export async function castCommit({ - disputeId, - voteId, +function generateSalt(): Hex { + return ("0x" + crypto.randomBytes(32).toString("hex")) as Hex; +} + +/** + * Cast a commit on-chain + */ +async function castCommit({ + coreDisputeID, + voteIDs, choice, justification, }: { - disputeId: bigint; - voteId: bigint; + coreDisputeID: bigint; + voteIDs: bigint[]; choice: bigint; justification: string; }) { try { // Create message with U+241F separator - const message = `${disputeId}${SEPARATOR}${voteId}${SEPARATOR}${choice}${SEPARATOR}${justification}`; + const message = `${coreDisputeID}${SEPARATOR}${voteIDs[0]}${SEPARATOR}${choice}${SEPARATOR}${justification}`; - // Encrypt the message + // Encrypt the message using shutter.ts const { encryptedCommitment, identity } = await encrypt(message); - // Split encrypted commitment into bytes32 chunks - const commitmentChunks = splitToBytes32(encryptedCommitment); - console.log("Commitment chunks:", commitmentChunks); + // Generate salt and compute hash + const salt = generateSalt(); + const commitHash = await disputeKit.read.hashVote([coreDisputeID, voteIDs[0], choice, justification, salt]); // Cast the commit on-chain - const hash = await disputeKit.write.castCommit([disputeId, [voteId], encryptedCommitment as Hex, identity as Hex]); + const txHash = await disputeKit.write.castCommit([coreDisputeID, voteIDs, commitHash, identity as Hex]); + + // Wait for transaction to be mined + await publicClient.waitForTransactionReceipt({ hash: txHash }); + + // Watch for CommitCast event + const events = await disputeKit.getEvents.CommitCast(); + console.log("CommitCast event:", (events[0] as any).args); // Store encrypted vote for later decryption encryptedVotes.push({ encryptedCommitment, identity: identity as Hex, timestamp: Math.floor(Date.now() / 1000), - voteId, + voteId: voteIDs[0], + salt, }); - // Watch for CommitCast event - const events = await disputeKit.getEvents.CommitCast(); - console.log("CommitCast event:", (events[0] as any).args); - - return { encryptedCommitment, identity }; + return { commitHash, identity, salt }; } catch (error) { console.error("Error in castCommit:", error); throw error; @@ -140,29 +130,28 @@ export async function autoVote() { const currentTime = Math.floor(Date.now() / 1000); // Find votes ready for decryption - const readyVotes = encryptedVotes.filter((vote) => currentTime - vote.timestamp >= DECRYPTION_DELAY); - console.log("Ready votes:", readyVotes); + const readyVotes = encryptedVotes.filter((vote) => currentTime - vote.timestamp >= DECRYPTION_DELAY + 10); for (const vote of readyVotes) { try { - console.log("Decrypting vote:", vote); - // Attempt to decrypt the vote const decryptedMessage = await decrypt(vote.encryptedCommitment, vote.identity); - console.log("Decrypted message:", decryptedMessage); // Parse the decrypted message - const [, , choice, justification] = decryptedMessage.split(SEPARATOR); + const [coreDisputeID, , choice, justification] = decryptedMessage.split(SEPARATOR); // Cast the vote on-chain - const hash = await disputeKit.write.castVote([ - BigInt(0), + const txHash = await disputeKit.write.castVote([ + BigInt(coreDisputeID), [vote.voteId], BigInt(choice), justification, - vote.identity, + vote.salt, ]); + // Wait for transaction to be mined + await publicClient.waitForTransactionReceipt({ hash: txHash }); + // Watch for VoteCast event const events = await disputeKit.getEvents.VoteCast(); console.log("VoteCast event:", (events[0] as any).args); @@ -190,8 +179,8 @@ async function main() { try { // Cast an encrypted commit await castCommit({ - disputeId: BigInt(0), - voteId: BigInt(0), + coreDisputeID: BigInt(0), + voteIDs: [BigInt(0)], choice: BigInt(2), justification: "This is my vote justification", }); diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol index 6d8e5b991..a5e5576ef 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol @@ -6,13 +6,11 @@ import "hardhat/console.sol"; contract DisputeKitShutterPoC { struct Vote { address account; // The address of the juror. - bytes commit; // The commit of the juror. For courts with hidden votes. - bytes32 identity; // The Shutter identity. + bytes32 commitHash; // The hash of the encrypted message + salt uint256 choice; // The choice of the juror. bool voted; // True if the vote has been cast. } - address public revealer; Vote[] public votes; uint256 public winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first. mapping(uint256 => uint256) public counts; // The sum of votes for each choice in the form `counts[choice]`. @@ -24,7 +22,7 @@ contract DisputeKitShutterPoC { uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, - bytes _commit, + bytes32 _commitHash, bytes32 _identity ); @@ -37,28 +35,44 @@ contract DisputeKitShutterPoC { ); constructor() { - revealer = msg.sender; address juror = msg.sender; - votes.push(Vote({account: juror, commit: bytes(""), identity: bytes32(0), choice: 0, voted: false})); + votes.push(Vote({account: juror, commitHash: bytes32(0), choice: 0, voted: false})); + } + + /** + * @dev Computes the hash of a vote using ABI encoding + * @param _coreDisputeID The ID of the core dispute + * @param _voteID The ID of the vote + * @param _choice The choice being voted for + * @param _justification The justification for the vote + * @param _salt A random salt for commitment + * @return bytes32 The hash of the encoded vote parameters + */ + function hashVote( + uint256 _coreDisputeID, + uint256 _voteID, + uint256 _choice, + string memory _justification, + bytes32 _salt + ) public pure returns (bytes32) { + bytes32 justificationHash = keccak256(bytes(_justification)); + return keccak256(abi.encode(_coreDisputeID, _voteID, _choice, justificationHash, _salt)); } function castCommit( uint256 _coreDisputeID, uint256[] calldata _voteIDs, - bytes calldata _commit, + bytes32 _commitHash, bytes32 _identity ) external { - // Store the commitment and identity for each voteID + // Store the commitment hash for each voteID for (uint256 i = 0; i < _voteIDs.length; i++) { - console.log("votes[_voteIDs[i]].account:", votes[_voteIDs[i]].account); - console.log("msg.sender:", msg.sender); require(votes[_voteIDs[i]].account == msg.sender, "The caller has to own the vote."); - votes[_voteIDs[i]].commit = _commit; - votes[_voteIDs[i]].identity = _identity; + votes[_voteIDs[i]].commitHash = _commitHash; } totalCommitted += _voteIDs.length; - emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit, _identity); + emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commitHash, _identity); } function castVote( @@ -66,15 +80,16 @@ contract DisputeKitShutterPoC { uint256[] calldata _voteIDs, uint256 _choice, string memory _justification, - bytes32 _identity + bytes32 _salt ) external { require(_voteIDs.length > 0, "No voteID provided"); - require(revealer == msg.sender, "The caller has to own the vote."); + // TODO: what happens if hiddenVotes are not enabled? - for (uint256 i = 0; i < _voteIDs.length; i++) { - // Not useful to check the identity here? - require(votes[_voteIDs[i]].identity == _identity, "The identity has to match the commitment."); + for (uint256 i = 0; i < _voteIDs.length; i++) { + // Verify the commitment hash + bytes32 computedHash = hashVote(_coreDisputeID, _voteIDs[i], _choice, _justification, _salt); + require(votes[_voteIDs[i]].commitHash == computedHash, "The commitment hash does not match."); require(!votes[_voteIDs[i]].voted, "Vote already cast."); votes[_voteIDs[i]].choice = _choice; votes[_voteIDs[i]].voted = true; From 020dbabc2eec92a99886a8da002db092e1e666e4 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 29 Apr 2025 21:35:18 +0100 Subject: [PATCH 06/26] chore: cleanup --- contracts/scripts/shutterAutoVote.ts | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/contracts/scripts/shutterAutoVote.ts b/contracts/scripts/shutterAutoVote.ts index 6c1be9f75..4393ff943 100644 --- a/contracts/scripts/shutterAutoVote.ts +++ b/contracts/scripts/shutterAutoVote.ts @@ -1,25 +1,4 @@ -/** - * TODO: - * The goal is to automatically decrypt each encrypted voteID previously cast as encrypted commitments, and cast them as votes. - * - modify shutter.ts encrypt() to return {encryptedCommitment, identity} - * - implement shutterAutoVote.ts that: - * - provides a castCommit() function which - * - calls shutter.ts encrypt() with the message "disputeId␟voteId␟choice␟justification" with `U+241F` as separator - * - calls the DisputeKitShutterPoC.castCommit() function with the encryptedCommitment, voteId, choice and justification - * - retrieve the DisputeKitShutterPoC.CommitCast event and log its parameters - * - provides an autoVote() function which - * - runs continuously as a loop, waking up every 30 seconds - * - upon wake up, retrieve the details of the previously encrypted messages (and corresponding identities) which have not yet been decrypted and have been encrypted for more than shutter.ts `DECRYPTION_DELAY`. - * - for each of these messages, call shutter.ts decrypt() with the identity and the encryptedCommitment - * - if the decryption is successful, call the DisputeKitShutterPoC.castVote() function with the voteId, choice and justification - * - if the decryption is not successful, log an error - * - if the castVote() function was called, retrieve the DisputeKitShutterPoC.VoteCast event and log its parameters - * - shutterAutoVote.ts needs to know: - * - the _voteIDs: they start from 0 and go up to DisputeKitShutterPoC.maxVoteIDs() - * - the _coreDisputeID: just use 0 for now. - **/ - -import { createPublicClient, createWalletClient, http, Hex, decodeEventLog, getContract } from "viem"; +import { createPublicClient, createWalletClient, http, Hex, getContract } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { hardhat } from "viem/chains"; import { encrypt, decrypt, DECRYPTION_DELAY } from "./shutter"; From 30804a858765c26882a4361cf8d8e5bc78e89990 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 30 Apr 2025 22:00:55 +0100 Subject: [PATCH 07/26] feat: support for multiple voteIDs at once, fixed salt handling by bot --- contracts/scripts/shutterAutoVote.ts | 87 ++++++++++++++----- .../dispute-kits/DisputeKitShutterPoC.sol | 14 +-- 2 files changed, 74 insertions(+), 27 deletions(-) diff --git a/contracts/scripts/shutterAutoVote.ts b/contracts/scripts/shutterAutoVote.ts index 4393ff943..35920476d 100644 --- a/contracts/scripts/shutterAutoVote.ts +++ b/contracts/scripts/shutterAutoVote.ts @@ -1,5 +1,5 @@ import { createPublicClient, createWalletClient, http, Hex, getContract } from "viem"; -import { privateKeyToAccount } from "viem/accounts"; +import { mnemonicToAccount } from "viem/accounts"; import { hardhat } from "viem/chains"; import { encrypt, decrypt, DECRYPTION_DELAY } from "./shutter"; import { abi as DisputeKitShutterPoCAbi } from "../deployments/localhost/DisputeKitShutterPoC.json"; @@ -9,19 +9,20 @@ import crypto from "crypto"; const SEPARATOR = "␟"; // U+241F // Store encrypted votes for later decryption -interface EncryptedVote { +type EncryptedVote = { encryptedCommitment: string; identity: Hex; timestamp: number; - voteId: bigint; + voteIDs: bigint[]; salt: Hex; -} +}; const encryptedVotes: EncryptedVote[] = []; -const PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" as const; +const disputeKitAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3" as const; -const CONTRACT_ADDRESS = "0x5FbDB2315678afecb367f032d93F642f64180aa3" as const; +const MNEMONIC = "test test test test test test test test test test test junk"; +const account = mnemonicToAccount(MNEMONIC); const transport = http(); const publicClient = createPublicClient({ @@ -29,7 +30,6 @@ const publicClient = createPublicClient({ transport, }); -const account = privateKeyToAccount(PRIVATE_KEY); const walletClient = createWalletClient({ account, chain: hardhat, @@ -37,7 +37,7 @@ const walletClient = createWalletClient({ }); const disputeKit = getContract({ - address: CONTRACT_ADDRESS, + address: disputeKitAddress, abi: DisputeKitShutterPoCAbi, client: { public: publicClient, wallet: walletClient }, }); @@ -49,6 +49,41 @@ function generateSalt(): Hex { return ("0x" + crypto.randomBytes(32).toString("hex")) as Hex; } +/** + * Encodes vote parameters into a message string with separators + */ +function encode({ + coreDisputeID, + voteIDs, + choice, + justification, + salt, +}: { + coreDisputeID: bigint; + voteIDs: bigint[]; + choice: bigint; + justification: string; + salt: Hex; +}): string { + return `${coreDisputeID}${SEPARATOR}${voteIDs.join(",")}${SEPARATOR}${choice}${SEPARATOR}${justification}${SEPARATOR}${salt}`; +} + +/** + * Decodes a message string into its component parts + * @param message The message to decode + * @returns Object containing the decoded components + */ +function decode(message: string) { + const [coreDisputeID, voteIDsStr, choice, justification, salt] = message.split(SEPARATOR); + return { + coreDisputeID, + voteIDs: voteIDsStr.split(",").map((id) => BigInt(id)), + choice, + justification, + salt, + }; +} + /** * Cast a commit on-chain */ @@ -64,15 +99,23 @@ async function castCommit({ justification: string; }) { try { - // Create message with U+241F separator - const message = `${coreDisputeID}${SEPARATOR}${voteIDs[0]}${SEPARATOR}${choice}${SEPARATOR}${justification}`; + // Generate salt first + const salt = generateSalt(); + + // Encode the vote parameters into a message + const message = encode({ + coreDisputeID, + voteIDs, + choice, + justification, + salt, + }); // Encrypt the message using shutter.ts const { encryptedCommitment, identity } = await encrypt(message); - // Generate salt and compute hash - const salt = generateSalt(); - const commitHash = await disputeKit.read.hashVote([coreDisputeID, voteIDs[0], choice, justification, salt]); + // Compute hash using all vote IDs + const commitHash = await disputeKit.read.hashVote([coreDisputeID, voteIDs, choice, justification, salt]); // Cast the commit on-chain const txHash = await disputeKit.write.castCommit([coreDisputeID, voteIDs, commitHash, identity as Hex]); @@ -89,7 +132,7 @@ async function castCommit({ encryptedCommitment, identity: identity as Hex, timestamp: Math.floor(Date.now() / 1000), - voteId: voteIDs[0], + voteIDs, salt, }); @@ -116,16 +159,16 @@ export async function autoVote() { // Attempt to decrypt the vote const decryptedMessage = await decrypt(vote.encryptedCommitment, vote.identity); - // Parse the decrypted message - const [coreDisputeID, , choice, justification] = decryptedMessage.split(SEPARATOR); + // Decode the decrypted message + const { coreDisputeID, voteIDs, choice, justification, salt } = decode(decryptedMessage); // Cast the vote on-chain const txHash = await disputeKit.write.castVote([ BigInt(coreDisputeID), - [vote.voteId], + voteIDs, BigInt(choice), justification, - vote.salt, + salt, ]); // Wait for transaction to be mined @@ -139,7 +182,7 @@ export async function autoVote() { const index = encryptedVotes.indexOf(vote); if (index > -1) encryptedVotes.splice(index, 1); } catch (error) { - console.error(`Error processing vote ${vote.voteId}:`, error); + console.error(`Error processing vote ${vote.voteIDs.join(",")}:`, error); } } @@ -158,9 +201,9 @@ async function main() { try { // Cast an encrypted commit await castCommit({ - coreDisputeID: BigInt(0), - voteIDs: [BigInt(0)], - choice: BigInt(2), + coreDisputeID: 0n, + voteIDs: [0n, 1n, 2n], + choice: 2n, justification: "This is my vote justification", }); diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol index a5e5576ef..20c6f6f88 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol @@ -37,12 +37,14 @@ contract DisputeKitShutterPoC { constructor() { address juror = msg.sender; votes.push(Vote({account: juror, commitHash: bytes32(0), choice: 0, voted: false})); + votes.push(Vote({account: juror, commitHash: bytes32(0), choice: 0, voted: false})); + votes.push(Vote({account: juror, commitHash: bytes32(0), choice: 0, voted: false})); } /** * @dev Computes the hash of a vote using ABI encoding * @param _coreDisputeID The ID of the core dispute - * @param _voteID The ID of the vote + * @param _voteIDs Array of vote IDs * @param _choice The choice being voted for * @param _justification The justification for the vote * @param _salt A random salt for commitment @@ -50,13 +52,14 @@ contract DisputeKitShutterPoC { */ function hashVote( uint256 _coreDisputeID, - uint256 _voteID, + uint256[] calldata _voteIDs, uint256 _choice, string memory _justification, bytes32 _salt ) public pure returns (bytes32) { bytes32 justificationHash = keccak256(bytes(_justification)); - return keccak256(abi.encode(_coreDisputeID, _voteID, _choice, justificationHash, _salt)); + bytes32 voteIDsHash = keccak256(abi.encodePacked(_voteIDs)); + return keccak256(abi.encode(_coreDisputeID, voteIDsHash, _choice, justificationHash, _salt)); } function castCommit( @@ -86,9 +89,10 @@ contract DisputeKitShutterPoC { // TODO: what happens if hiddenVotes are not enabled? + // Verify the commitment hash for all votes at once + bytes32 computedHash = hashVote(_coreDisputeID, _voteIDs, _choice, _justification, _salt); + for (uint256 i = 0; i < _voteIDs.length; i++) { - // Verify the commitment hash - bytes32 computedHash = hashVote(_coreDisputeID, _voteIDs[i], _choice, _justification, _salt); require(votes[_voteIDs[i]].commitHash == computedHash, "The commitment hash does not match."); require(!votes[_voteIDs[i]].voted, "Vote already cast."); votes[_voteIDs[i]].choice = _choice; From 1a9b72db339db27b46b06b8ce8ec028272d4ad93 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 30 Apr 2025 22:56:50 +0100 Subject: [PATCH 08/26] chore: cleanup before integration into a fully fletched dispute kit --- contracts/scripts/shutter.ts | 9 +--- contracts/scripts/shutterAutoVote.ts | 50 +++++++------------ .../dispute-kits/DisputeKitShutterPoC.sol | 37 ++++++-------- 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/contracts/scripts/shutter.ts b/contracts/scripts/shutter.ts index f4d917d6d..a1c05e1c3 100644 --- a/contracts/scripts/shutter.ts +++ b/contracts/scripts/shutter.ts @@ -3,8 +3,8 @@ import { Hex, stringToHex, hexToString } from "viem"; import crypto from "crypto"; import "isomorphic-fetch"; -/** Time in seconds to wait before the message can be decrypted */ -export const DECRYPTION_DELAY = 20; +// Time in seconds to wait before the message can be decrypted +export const DECRYPTION_DELAY = 5; interface ShutterApiMessageData { eon: number; @@ -25,11 +25,6 @@ interface ShutterDecryptionKeyData { decryption_timestamp: number; } -interface ShutterDecryptionKeyResponse { - message: ShutterDecryptionKeyData; - error?: string; -} - /** * Fetches encryption data from the Shutter API * @param decryptionTimestamp Unix timestamp when decryption should be possible diff --git a/contracts/scripts/shutterAutoVote.ts b/contracts/scripts/shutterAutoVote.ts index 35920476d..9a6c4fe47 100644 --- a/contracts/scripts/shutterAutoVote.ts +++ b/contracts/scripts/shutterAutoVote.ts @@ -10,6 +10,7 @@ const SEPARATOR = "␟"; // U+241F // Store encrypted votes for later decryption type EncryptedVote = { + coreDisputeID: bigint; encryptedCommitment: string; identity: Hex; timestamp: number; @@ -52,20 +53,8 @@ function generateSalt(): Hex { /** * Encodes vote parameters into a message string with separators */ -function encode({ - coreDisputeID, - voteIDs, - choice, - justification, - salt, -}: { - coreDisputeID: bigint; - voteIDs: bigint[]; - choice: bigint; - justification: string; - salt: Hex; -}): string { - return `${coreDisputeID}${SEPARATOR}${voteIDs.join(",")}${SEPARATOR}${choice}${SEPARATOR}${justification}${SEPARATOR}${salt}`; +function encode({ choice, salt, justification }: { choice: bigint; salt: Hex; justification: string }): string { + return `${choice}${SEPARATOR}${salt}${SEPARATOR}${justification}`; } /** @@ -74,13 +63,11 @@ function encode({ * @returns Object containing the decoded components */ function decode(message: string) { - const [coreDisputeID, voteIDsStr, choice, justification, salt] = message.split(SEPARATOR); + const [choice, salt, justification] = message.split(SEPARATOR); return { - coreDisputeID, - voteIDs: voteIDsStr.split(",").map((id) => BigInt(id)), - choice, - justification, + choice: BigInt(choice), salt, + justification, }; } @@ -104,18 +91,16 @@ async function castCommit({ // Encode the vote parameters into a message const message = encode({ - coreDisputeID, - voteIDs, choice, - justification, salt, + justification, }); // Encrypt the message using shutter.ts const { encryptedCommitment, identity } = await encrypt(message); // Compute hash using all vote IDs - const commitHash = await disputeKit.read.hashVote([coreDisputeID, voteIDs, choice, justification, salt]); + const commitHash = await disputeKit.read.hashVote([choice, salt, justification]); // Cast the commit on-chain const txHash = await disputeKit.write.castCommit([coreDisputeID, voteIDs, commitHash, identity as Hex]); @@ -129,6 +114,7 @@ async function castCommit({ // Store encrypted vote for later decryption encryptedVotes.push({ + coreDisputeID, encryptedCommitment, identity: identity as Hex, timestamp: Math.floor(Date.now() / 1000), @@ -150,9 +136,10 @@ export async function autoVote() { while (true) { try { const currentTime = Math.floor(Date.now() / 1000); + const sleep = DECRYPTION_DELAY + 10; // Find votes ready for decryption - const readyVotes = encryptedVotes.filter((vote) => currentTime - vote.timestamp >= DECRYPTION_DELAY + 10); + const readyVotes = encryptedVotes.filter((vote) => currentTime - vote.timestamp >= sleep); for (const vote of readyVotes) { try { @@ -160,15 +147,15 @@ export async function autoVote() { const decryptedMessage = await decrypt(vote.encryptedCommitment, vote.identity); // Decode the decrypted message - const { coreDisputeID, voteIDs, choice, justification, salt } = decode(decryptedMessage); + const { choice, salt, justification } = decode(decryptedMessage); // Cast the vote on-chain const txHash = await disputeKit.write.castVote([ - BigInt(coreDisputeID), - voteIDs, - BigInt(choice), - justification, + vote.coreDisputeID, + vote.voteIDs, + choice, salt, + justification, ]); // Wait for transaction to be mined @@ -186,9 +173,8 @@ export async function autoVote() { } } - // Sleep for 30 seconds - console.log("Sleeping for 30 seconds"); - await new Promise((resolve) => setTimeout(resolve, 30000)); + console.log(`Sleeping for ${sleep} seconds`); + await new Promise((resolve) => setTimeout(resolve, sleep * 1000)); } catch (error) { console.error("Error in autoVote loop:", error); // Continue the loop even if there's an error diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol index 20c6f6f88..4d2d76add 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol @@ -6,7 +6,7 @@ import "hardhat/console.sol"; contract DisputeKitShutterPoC { struct Vote { address account; // The address of the juror. - bytes32 commitHash; // The hash of the encrypted message + salt + bytes32 commit; // The hash of the encrypted message + salt uint256 choice; // The choice of the juror. bool voted; // True if the vote has been cast. } @@ -22,7 +22,7 @@ contract DisputeKitShutterPoC { uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, - bytes32 _commitHash, + bytes32 _commit, bytes32 _identity ); @@ -36,64 +36,55 @@ contract DisputeKitShutterPoC { constructor() { address juror = msg.sender; - votes.push(Vote({account: juror, commitHash: bytes32(0), choice: 0, voted: false})); - votes.push(Vote({account: juror, commitHash: bytes32(0), choice: 0, voted: false})); - votes.push(Vote({account: juror, commitHash: bytes32(0), choice: 0, voted: false})); + votes.push(Vote({account: juror, commit: bytes32(0), choice: 0, voted: false})); + votes.push(Vote({account: juror, commit: bytes32(0), choice: 0, voted: false})); + votes.push(Vote({account: juror, commit: bytes32(0), choice: 0, voted: false})); } /** * @dev Computes the hash of a vote using ABI encoding - * @param _coreDisputeID The ID of the core dispute - * @param _voteIDs Array of vote IDs * @param _choice The choice being voted for * @param _justification The justification for the vote * @param _salt A random salt for commitment * @return bytes32 The hash of the encoded vote parameters */ - function hashVote( - uint256 _coreDisputeID, - uint256[] calldata _voteIDs, - uint256 _choice, - string memory _justification, - bytes32 _salt - ) public pure returns (bytes32) { + function hashVote(uint256 _choice, bytes32 _salt, string memory _justification) public pure returns (bytes32) { bytes32 justificationHash = keccak256(bytes(_justification)); - bytes32 voteIDsHash = keccak256(abi.encodePacked(_voteIDs)); - return keccak256(abi.encode(_coreDisputeID, voteIDsHash, _choice, justificationHash, _salt)); + return keccak256(abi.encode(_choice, _salt, justificationHash)); } function castCommit( uint256 _coreDisputeID, uint256[] calldata _voteIDs, - bytes32 _commitHash, + bytes32 _commit, bytes32 _identity ) external { // Store the commitment hash for each voteID for (uint256 i = 0; i < _voteIDs.length; i++) { require(votes[_voteIDs[i]].account == msg.sender, "The caller has to own the vote."); - votes[_voteIDs[i]].commitHash = _commitHash; + votes[_voteIDs[i]].commit = _commit; } totalCommitted += _voteIDs.length; - emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commitHash, _identity); + emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit, _identity); } function castVote( uint256 _coreDisputeID, uint256[] calldata _voteIDs, uint256 _choice, - string memory _justification, - bytes32 _salt + bytes32 _salt, + string memory _justification ) external { require(_voteIDs.length > 0, "No voteID provided"); // TODO: what happens if hiddenVotes are not enabled? // Verify the commitment hash for all votes at once - bytes32 computedHash = hashVote(_coreDisputeID, _voteIDs, _choice, _justification, _salt); + bytes32 computedHash = hashVote(_choice, _salt, _justification); for (uint256 i = 0; i < _voteIDs.length; i++) { - require(votes[_voteIDs[i]].commitHash == computedHash, "The commitment hash does not match."); + require(votes[_voteIDs[i]].commit == computedHash, "The commitment hash does not match."); require(!votes[_voteIDs[i]].voted, "Vote already cast."); votes[_voteIDs[i]].choice = _choice; votes[_voteIDs[i]].voted = true; From b5805561e5f96bb59d0b7e1baefad5fa2d1bb07e Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 30 Apr 2025 23:09:19 +0100 Subject: [PATCH 09/26] feat: fully fletched DisputeKitShutter --- .../dispute-kits/DisputeKitClassic.sol | 2 +- .../dispute-kits/DisputeKitClassicBase.sol | 23 ++++++++++++++++--- .../dispute-kits/DisputeKitGated.sol | 2 +- contracts/test/foundry/KlerosCore.t.sol | 4 ++-- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol index 3aacdcea7..97dfcd2ba 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol @@ -11,7 +11,7 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol"; /// - an incentive system: equal split between coherent votes, /// - an appeal system: fund 2 choices only, vote on any choice. contract DisputeKitClassic is DisputeKitClassicBase { - string public constant override version = "0.8.0"; + string public constant override version = "0.9.0"; // ************************************* // // * Constructor * // diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol index ff6291e58..85a9cd8cb 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol @@ -238,7 +238,7 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi /// `n` is the number of votes. /// @param _coreDisputeID The ID of the dispute in Kleros Core. /// @param _voteIDs The IDs of the votes. - /// @param _commit The commit. Note that justification string is a part of the commit. + /// @param _commit The commitment hash. function castCommit( uint256 _coreDisputeID, uint256[] calldata _voteIDs, @@ -283,13 +283,14 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi Round storage round = dispute.rounds[dispute.rounds.length - 1]; (uint96 courtID, , , , ) = core.disputes(_coreDisputeID); (, bool hiddenVotes, , , , , ) = core.courts(courtID); + bytes32 voteHash = hashVote(_choice, _salt, _justification); // Save the votes. for (uint256 i = 0; i < _voteIDs.length; i++) { require(round.votes[_voteIDs[i]].account == msg.sender, "The caller has to own the vote."); require( - !hiddenVotes || round.votes[_voteIDs[i]].commit == keccak256(abi.encodePacked(_choice, _salt)), - "The commit must match the choice in courts with hidden votes." + !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash, + "The vote hash must match the commitment in courts with hidden votes." ); require(!round.votes[_voteIDs[i]].voted, "Vote already cast."); round.votes[_voteIDs[i]].choice = _choice; @@ -435,6 +436,22 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi // * Public Views * // // ************************************* // + /** + * @dev Computes the hash of a vote using ABI encoding + * @dev The unused parameters may be used by overriding contracts. + * @param _choice The choice being voted for + * @param _justification The justification for the vote + * @param _salt A random salt for commitment + * @return bytes32 The hash of the encoded vote parameters + */ + function hashVote( + uint256 _choice, + uint256 _salt, + string memory _justification + ) public pure virtual returns (bytes32) { + return keccak256(abi.encodePacked(_choice, _salt)); + } + function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) { Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]]; Round storage lastRound = dispute.rounds[dispute.rounds.length - 1]; diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol b/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol index c3788c432..1e9165048 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol @@ -27,7 +27,7 @@ interface IBalanceHolderERC1155 { /// - an incentive system: equal split between coherent votes, /// - an appeal system: fund 2 choices only, vote on any choice. contract DisputeKitGated is DisputeKitClassicBase { - string public constant override version = "0.8.0"; + string public constant override version = "0.9.0"; // ************************************* // // * Storage * // diff --git a/contracts/test/foundry/KlerosCore.t.sol b/contracts/test/foundry/KlerosCore.t.sol index 291b969d0..16d81cbe2 100644 --- a/contracts/test/foundry/KlerosCore.t.sol +++ b/contracts/test/foundry/KlerosCore.t.sol @@ -1654,11 +1654,11 @@ contract KlerosCoreTest is Test { // Check the require with the wrong choice and then with the wrong salt vm.prank(staker1); - vm.expectRevert(bytes("The commit must match the choice in courts with hidden votes.")); + vm.expectRevert(bytes("The vote hash must match the commitment in courts with hidden votes.")); disputeKit.castVote(disputeID, voteIDs, 2, salt, "XYZ"); vm.prank(staker1); - vm.expectRevert(bytes("The commit must match the choice in courts with hidden votes.")); + vm.expectRevert(bytes("The vote hash must match the commitment in courts with hidden votes.")); disputeKit.castVote(disputeID, voteIDs, YES, salt - 1, "XYZ"); vm.prank(staker1); From 8819241b0f2e6adb42f79629b8975f4607fd3fb6 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 30 Apr 2025 23:10:57 +0100 Subject: [PATCH 10/26] chore: removed redundant node-fetch --- contracts/package.json | 1 - yarn.lock | 1 - 2 files changed, 2 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 101f5ec34..a1b1a8b5d 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -140,7 +140,6 @@ "hardhat-gas-reporter": "^2.2.2", "hardhat-tracer": "^3.1.0", "hardhat-watcher": "^2.5.0", - "node-fetch": "^3.3.2", "pino": "^8.21.0", "pino-pretty": "^10.3.1", "prettier": "^3.3.3", diff --git a/yarn.lock b/yarn.lock index f46f859f8..6ea49d46d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5587,7 +5587,6 @@ __metadata: hardhat-tracer: "npm:^3.1.0" hardhat-watcher: "npm:^2.5.0" isomorphic-fetch: "npm:^3.0.0" - node-fetch: "npm:^3.3.2" pino: "npm:^8.21.0" pino-pretty: "npm:^10.3.1" prettier: "npm:^3.3.3" From cd016b3dc880a3b523c48422c72be585791475a3 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 30 Apr 2025 23:14:48 +0100 Subject: [PATCH 11/26] chore: cleanup --- .../src/arbitration/dispute-kits/DisputeKitShutterPoC.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol index 4d2d76add..31b8617d1 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol @@ -108,8 +108,4 @@ contract DisputeKitShutterPoC { } emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification); } - - function maxVoteIDs() public view returns (uint256) { - return votes.length - 1; - } } From 8e46e05f7c32185f4210db963d218ee7ce74d6a8 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 30 Apr 2025 23:20:34 +0100 Subject: [PATCH 12/26] feat: fully fletched DisputeKitShutter --- contracts/deploy/09-shutter.ts | 26 --- contracts/scripts/shutterAutoVote.ts | 207 ------------------ .../dispute-kits/DisputeKitShutter.sol | 93 ++++++++ .../dispute-kits/DisputeKitShutterPoC.sol | 111 ---------- 4 files changed, 93 insertions(+), 344 deletions(-) delete mode 100644 contracts/deploy/09-shutter.ts delete mode 100644 contracts/scripts/shutterAutoVote.ts create mode 100644 contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol delete mode 100644 contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol diff --git a/contracts/deploy/09-shutter.ts b/contracts/deploy/09-shutter.ts deleted file mode 100644 index b8d53fb1a..000000000 --- a/contracts/deploy/09-shutter.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { HomeChains, isSkipped } from "./utils"; - -const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - const { deployments, getNamedAccounts, getChainId } = hre; - const { deploy } = deployments; - - // 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); - - await deploy("DisputeKitShutterPoC", { - from: deployer, - args: [], - log: true, - }); -}; - -deployArbitration.tags = ["Shutter"]; -deployArbitration.skip = async ({ network }) => { - return isSkipped(network, !HomeChains[network.config.chainId ?? 0]); -}; - -export default deployArbitration; diff --git a/contracts/scripts/shutterAutoVote.ts b/contracts/scripts/shutterAutoVote.ts deleted file mode 100644 index 9a6c4fe47..000000000 --- a/contracts/scripts/shutterAutoVote.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { createPublicClient, createWalletClient, http, Hex, getContract } from "viem"; -import { mnemonicToAccount } from "viem/accounts"; -import { hardhat } from "viem/chains"; -import { encrypt, decrypt, DECRYPTION_DELAY } from "./shutter"; -import { abi as DisputeKitShutterPoCAbi } from "../deployments/localhost/DisputeKitShutterPoC.json"; -import crypto from "crypto"; - -// Constants -const SEPARATOR = "␟"; // U+241F - -// Store encrypted votes for later decryption -type EncryptedVote = { - coreDisputeID: bigint; - encryptedCommitment: string; - identity: Hex; - timestamp: number; - voteIDs: bigint[]; - salt: Hex; -}; - -const encryptedVotes: EncryptedVote[] = []; - -const disputeKitAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3" as const; - -const MNEMONIC = "test test test test test test test test test test test junk"; -const account = mnemonicToAccount(MNEMONIC); - -const transport = http(); -const publicClient = createPublicClient({ - chain: hardhat, - transport, -}); - -const walletClient = createWalletClient({ - account, - chain: hardhat, - transport, -}); - -const disputeKit = getContract({ - address: disputeKitAddress, - abi: DisputeKitShutterPoCAbi, - client: { public: publicClient, wallet: walletClient }, -}); - -/** - * Generate a random salt - */ -function generateSalt(): Hex { - return ("0x" + crypto.randomBytes(32).toString("hex")) as Hex; -} - -/** - * Encodes vote parameters into a message string with separators - */ -function encode({ choice, salt, justification }: { choice: bigint; salt: Hex; justification: string }): string { - return `${choice}${SEPARATOR}${salt}${SEPARATOR}${justification}`; -} - -/** - * Decodes a message string into its component parts - * @param message The message to decode - * @returns Object containing the decoded components - */ -function decode(message: string) { - const [choice, salt, justification] = message.split(SEPARATOR); - return { - choice: BigInt(choice), - salt, - justification, - }; -} - -/** - * Cast a commit on-chain - */ -async function castCommit({ - coreDisputeID, - voteIDs, - choice, - justification, -}: { - coreDisputeID: bigint; - voteIDs: bigint[]; - choice: bigint; - justification: string; -}) { - try { - // Generate salt first - const salt = generateSalt(); - - // Encode the vote parameters into a message - const message = encode({ - choice, - salt, - justification, - }); - - // Encrypt the message using shutter.ts - const { encryptedCommitment, identity } = await encrypt(message); - - // Compute hash using all vote IDs - const commitHash = await disputeKit.read.hashVote([choice, salt, justification]); - - // Cast the commit on-chain - const txHash = await disputeKit.write.castCommit([coreDisputeID, voteIDs, commitHash, identity as Hex]); - - // Wait for transaction to be mined - await publicClient.waitForTransactionReceipt({ hash: txHash }); - - // Watch for CommitCast event - const events = await disputeKit.getEvents.CommitCast(); - console.log("CommitCast event:", (events[0] as any).args); - - // Store encrypted vote for later decryption - encryptedVotes.push({ - coreDisputeID, - encryptedCommitment, - identity: identity as Hex, - timestamp: Math.floor(Date.now() / 1000), - voteIDs, - salt, - }); - - return { commitHash, identity, salt }; - } catch (error) { - console.error("Error in castCommit:", error); - throw error; - } -} - -/** - * Continuously monitor for votes ready to be decrypted and cast - */ -export async function autoVote() { - while (true) { - try { - const currentTime = Math.floor(Date.now() / 1000); - const sleep = DECRYPTION_DELAY + 10; - - // Find votes ready for decryption - const readyVotes = encryptedVotes.filter((vote) => currentTime - vote.timestamp >= sleep); - - for (const vote of readyVotes) { - try { - // Attempt to decrypt the vote - const decryptedMessage = await decrypt(vote.encryptedCommitment, vote.identity); - - // Decode the decrypted message - const { choice, salt, justification } = decode(decryptedMessage); - - // Cast the vote on-chain - const txHash = await disputeKit.write.castVote([ - vote.coreDisputeID, - vote.voteIDs, - choice, - salt, - justification, - ]); - - // Wait for transaction to be mined - await publicClient.waitForTransactionReceipt({ hash: txHash }); - - // Watch for VoteCast event - const events = await disputeKit.getEvents.VoteCast(); - console.log("VoteCast event:", (events[0] as any).args); - - // Remove the processed vote - const index = encryptedVotes.indexOf(vote); - if (index > -1) encryptedVotes.splice(index, 1); - } catch (error) { - console.error(`Error processing vote ${vote.voteIDs.join(",")}:`, error); - } - } - - console.log(`Sleeping for ${sleep} seconds`); - await new Promise((resolve) => setTimeout(resolve, sleep * 1000)); - } catch (error) { - console.error("Error in autoVote loop:", error); - // Continue the loop even if there's an error - } - } -} - -// Main function to start the auto voting process -async function main() { - try { - // Cast an encrypted commit - await castCommit({ - coreDisputeID: 0n, - voteIDs: [0n, 1n, 2n], - choice: 2n, - justification: "This is my vote justification", - }); - - // Start the auto voting process - await autoVote(); - } catch (error) { - console.error("Error in main:", error); - process.exit(1); - } -} - -// Execute if run directly -if (require.main === module) { - main(); -} diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol new file mode 100644 index 000000000..2f2a292c4 --- /dev/null +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol"; + +/// @title DisputeKitShutter +/// Dispute kit implementation of the Kleros v1 features including: +/// - a drawing system: proportional to staked PNK, +/// - a vote aggregation system: plurality, +/// - an incentive system: equal split between coherent votes, +/// - an appeal system: fund 2 choices only, vote on any choice. +/// Added functionality: an Shutter-specific event emitted when a vote is cast. +contract DisputeKitShutter is DisputeKitClassicBase { + string public constant override version = "0.9.0"; + + // ************************************* // + // * Events * // + // ************************************* // + + /// @dev Emitted when a vote is cast. + /// @param _commit The commitment hash. + /// @param _identity The Shutter identity used for encryption. + event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity); + + // ************************************* // + // * Constructor * // + // ************************************* // + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @dev Initializer. + /// @param _governor The governor's address. + /// @param _core The KlerosCore arbitrator. + function initialize(address _governor, KlerosCore _core) external reinitializer(1) { + __DisputeKitClassicBase_initialize(_governor, _core); + } + + // ************************ // + // * Governance * // + // ************************ // + + /// @dev Access Control to perform implementation upgrades (UUPS Proxiable) + /// Only the governor can perform upgrades (`onlyByGovernor`) + function _authorizeUpgrade(address) internal view override onlyByGovernor { + // NOP + } + + // ************************************* // + // * State Modifiers * // + // ************************************* // + + /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the + /// commit period, each call overrides the commits of the previous one. + /// `O(n)` where + /// `n` is the number of votes. + /// @param _coreDisputeID The ID of the dispute in Kleros Core. + /// @param _voteIDs The IDs of the votes. + /// @param _commit The commitment hash including the justification. + /// @param _identity The Shutter identity used for encryption. + function castCommitShutter( + uint256 _coreDisputeID, + uint256[] calldata _voteIDs, + bytes32 _commit, + bytes32 _identity + ) external notJumped(_coreDisputeID) { + this.castCommit(_coreDisputeID, _voteIDs, _commit); + emit CommitCastShutter(_commit, _identity); + } + + // ************************************* // + // * Public Views * // + // ************************************* // + + /** + * @dev Computes the hash of a vote using ABI encoding + * @param _choice The choice being voted for + * @param _justification The justification for the vote + * @param _salt A random salt for commitment + * @return bytes32 The hash of the encoded vote parameters + */ + function hashVote( + uint256 _choice, + uint256 _salt, + string memory _justification + ) public pure override returns (bytes32) { + bytes32 justificationHash = keccak256(bytes(_justification)); + return keccak256(abi.encode(_choice, _salt, justificationHash)); + } +} diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol deleted file mode 100644 index 31b8617d1..000000000 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutterPoC.sol +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "hardhat/console.sol"; - -contract DisputeKitShutterPoC { - struct Vote { - address account; // The address of the juror. - bytes32 commit; // The hash of the encrypted message + salt - uint256 choice; // The choice of the juror. - bool voted; // True if the vote has been cast. - } - - Vote[] public votes; - uint256 public winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first. - mapping(uint256 => uint256) public counts; // The sum of votes for each choice in the form `counts[choice]`. - bool public tied; // True if there is a tie, false otherwise. - uint256 public totalCommitted; - uint256 public totalVoted; - - event CommitCast( - uint256 indexed _coreDisputeID, - address indexed _juror, - uint256[] _voteIDs, - bytes32 _commit, - bytes32 _identity - ); - - event VoteCast( - uint256 indexed _coreDisputeID, - address indexed _juror, - uint256[] _voteIDs, - uint256 indexed _choice, - string _justification - ); - - constructor() { - address juror = msg.sender; - votes.push(Vote({account: juror, commit: bytes32(0), choice: 0, voted: false})); - votes.push(Vote({account: juror, commit: bytes32(0), choice: 0, voted: false})); - votes.push(Vote({account: juror, commit: bytes32(0), choice: 0, voted: false})); - } - - /** - * @dev Computes the hash of a vote using ABI encoding - * @param _choice The choice being voted for - * @param _justification The justification for the vote - * @param _salt A random salt for commitment - * @return bytes32 The hash of the encoded vote parameters - */ - function hashVote(uint256 _choice, bytes32 _salt, string memory _justification) public pure returns (bytes32) { - bytes32 justificationHash = keccak256(bytes(_justification)); - return keccak256(abi.encode(_choice, _salt, justificationHash)); - } - - function castCommit( - uint256 _coreDisputeID, - uint256[] calldata _voteIDs, - bytes32 _commit, - bytes32 _identity - ) external { - // Store the commitment hash for each voteID - for (uint256 i = 0; i < _voteIDs.length; i++) { - require(votes[_voteIDs[i]].account == msg.sender, "The caller has to own the vote."); - votes[_voteIDs[i]].commit = _commit; - } - - totalCommitted += _voteIDs.length; - emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit, _identity); - } - - function castVote( - uint256 _coreDisputeID, - uint256[] calldata _voteIDs, - uint256 _choice, - bytes32 _salt, - string memory _justification - ) external { - require(_voteIDs.length > 0, "No voteID provided"); - - // TODO: what happens if hiddenVotes are not enabled? - - // Verify the commitment hash for all votes at once - bytes32 computedHash = hashVote(_choice, _salt, _justification); - - for (uint256 i = 0; i < _voteIDs.length; i++) { - require(votes[_voteIDs[i]].commit == computedHash, "The commitment hash does not match."); - require(!votes[_voteIDs[i]].voted, "Vote already cast."); - votes[_voteIDs[i]].choice = _choice; - votes[_voteIDs[i]].voted = true; - } - - totalVoted += _voteIDs.length; - - counts[_choice] += _voteIDs.length; - if (_choice == winningChoice) { - if (tied) tied = false; - } else { - // Voted for another choice. - if (counts[_choice] == counts[winningChoice]) { - // Tie. - if (!tied) tied = true; - } else if (counts[_choice] > counts[winningChoice]) { - // New winner. - winningChoice = _choice; - tied = false; - } - } - emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification); - } -} From 98ec3ba5d4e32952de4b53e7cc7a0069d95992d3 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 30 Apr 2025 23:53:05 +0100 Subject: [PATCH 13/26] chore: deployment of DisputeKitShutter in devnet --- contracts/README.md | 1 + contracts/deploy/00-home-chain-arbitration.ts | 8 + .../DisputeKitShutter.json | 1130 +++++++++++ .../DisputeKitShutter_Implementation.json | 1725 +++++++++++++++++ .../DisputeKitShutter_Proxy.json | 81 + contracts/src/proxy/KlerosProxies.sol | 4 + contracts/test/arbitration/index.ts | 15 +- 7 files changed, 2958 insertions(+), 6 deletions(-) create mode 100644 contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json create mode 100644 contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json create mode 100644 contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Proxy.json diff --git a/contracts/README.md b/contracts/README.md index 187020388..5ad78d2ed 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -79,6 +79,7 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [DAIFaucet](https://sepolia.arbiscan.io/address/0xB5b39A1bcD2D7097A8824B3cC18Ebd2dFb0D9B5E) - [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x2246821E1313A93e2F8CdF7a3422d078f560b457), [implementation](https://sepolia.arbiscan.io/address/0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24) - [DisputeKitClassicUniversity: proxy](https://sepolia.arbiscan.io/address/0xd6E96b7c993763B5CDDa1139C7387B82A7c8B8B5), [implementation](https://sepolia.arbiscan.io/address/0x87e863b94d2CB79A8aB53bD87Dc4A10E11C0918B) +- [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4) - [DisputeResolver](https://sepolia.arbiscan.io/address/0x524C5541f440204E0B4577334c439277018F971f) - [DisputeResolverRuler](https://sepolia.arbiscan.io/address/0x199893232ECC74cC7898B24b5Ff58d613029f6B7) - [DisputeResolverUniversity](https://sepolia.arbiscan.io/address/0x2Aa1a94307E772BeE42E9EfbD137b1053F1fCfd4) diff --git a/contracts/deploy/00-home-chain-arbitration.ts b/contracts/deploy/00-home-chain-arbitration.ts index e61805f31..2cdbbb2c0 100644 --- a/contracts/deploy/00-home-chain-arbitration.ts +++ b/contracts/deploy/00-home-chain-arbitration.ts @@ -96,6 +96,14 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) console.error("failed to change currency rates:", e); } + // Extra dispute kits + const disputeKitShutter = await deployUpgradable(deployments, "DisputeKitShutter", { + from: deployer, + args: [deployer, core.target], + log: true, + }); + await core.addNewDisputeKit(disputeKitShutter.address); + await deploy("KlerosCoreSnapshotProxy", { from: deployer, args: [deployer, core.target], diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json new file mode 100644 index 000000000..0418b22a5 --- /dev/null +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json @@ -0,0 +1,1130 @@ +{ + "address": "0x09F3d00B995186D76Af9AA8627D06351d0d9f950", + "abi": [ + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "FailedDelegateCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "ChoiceFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_juror", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + } + ], + "name": "CommitCast", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_identity", + "type": "bytes32" + } + ], + "name": "CommitCastShutter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Contribution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "DisputeCreation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_juror", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "VoteCast", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "LOSER_APPEAL_PERIOD_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOSER_STAKE_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE_BASIS_POINT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WINNER_STAKE_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "areCommitsAllCast", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "areVotesAllCast", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + } + ], + "name": "castCommit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_identity", + "type": "bytes32" + } + ], + "name": "castCommitShutter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "castVote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_core", + "type": "address" + } + ], + "name": "changeCore", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_governor", + "type": "address" + } + ], + "name": "changeGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "core", + "outputs": [ + { + "internalType": "contract KlerosCore", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "coreDisputeIDToLocal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_nbVotes", + "type": "uint256" + } + ], + "name": "createDispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "currentRuling", + "outputs": [ + { + "internalType": "uint256", + "name": "ruling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "overridden", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "disputes", + "outputs": [ + { + "internalType": "uint256", + "name": "numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "jumped", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "draw", + "outputs": [ + { + "internalType": "address", + "name": "drawnAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_destination", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "executeGovernorProposal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "fundAppeal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + } + ], + "name": "getCoherentCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_voteID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "getDegreeOfCoherence", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "getFundedChoices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "fundedChoices", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "getRoundInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "winningChoice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "totalVoted", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalCommited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nbVoters", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "choiceCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_voteID", + "type": "uint256" + } + ], + "name": "getVoteInfo", + "outputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "commit", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "choice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "voted", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "hashVote", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "contract KlerosCore", + "name": "_core", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "isAppealFunded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_voteID", + "type": "uint256" + } + ], + "name": "isVoteActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "singleDrawPerJuror", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_beneficiary", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "withdrawFeesAndRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "transactionHash": "0x6274653a9b2599193a56cb902e82ea9860ac9321588e6b5daa2e2d93bf0c1274", + "receipt": { + "to": null, + "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "contractAddress": "0x09F3d00B995186D76Af9AA8627D06351d0d9f950", + "transactionIndex": 2, + "gasUsed": "240379", + "logsBloom": "0x00000000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe962e1a9d690b93ef86a8757e1d9d97537e53577738fbe29092cb9dc27bd112b", + "transactionHash": "0x6274653a9b2599193a56cb902e82ea9860ac9321588e6b5daa2e2d93bf0c1274", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 148194178, + "transactionHash": "0x6274653a9b2599193a56cb902e82ea9860ac9321588e6b5daa2e2d93bf0c1274", + "address": "0x09F3d00B995186D76Af9AA8627D06351d0d9f950", + "topics": [ + "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 4, + "blockHash": "0xe962e1a9d690b93ef86a8757e1d9d97537e53577738fbe29092cb9dc27bd112b" + } + ], + "blockNumber": 148194178, + "cumulativeGasUsed": "361637", + "status": 1, + "byzantium": true + }, + "args": [ + "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "0x485cc955000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c590000000000000000000000004838e31e0ea315232c431598110fe677caf2d6e6" + ], + "numDeployments": 1, + "solcInputHash": "96b8e3f55478438b6784f67c1730309e", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitShutterProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitShutterProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x209228b56d42a8444ca70919e1ded5711fba434a746f26d426e230f57526fc6c\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", + "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", + "execute": { + "methodName": "initialize", + "args": [ + "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "0x4838e31E0ea315232c431598110FE677cAF2D6E6" + ] + }, + "implementation": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json new file mode 100644 index 000000000..d1d63d2c0 --- /dev/null +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json @@ -0,0 +1,1725 @@ +{ + "address": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadyInitialized", + "type": "error" + }, + { + "inputs": [], + "name": "FailedDelegateCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "ChoiceFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_juror", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + } + ], + "name": "CommitCast", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_identity", + "type": "bytes32" + } + ], + "name": "CommitCastShutter", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Contribution", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + } + ], + "name": "DisputeCreation", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_juror", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "VoteCast", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "LOSER_APPEAL_PERIOD_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "LOSER_STAKE_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ONE_BASIS_POINT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WINNER_STAKE_MULTIPLIER", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "areCommitsAllCast", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "areVotesAllCast", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + } + ], + "name": "castCommit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "bytes32", + "name": "_commit", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_identity", + "type": "bytes32" + } + ], + "name": "castCommitShutter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "castVote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_core", + "type": "address" + } + ], + "name": "changeCore", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_governor", + "type": "address" + } + ], + "name": "changeGovernor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "core", + "outputs": [ + { + "internalType": "contract KlerosCore", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "coreDisputeIDToLocal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_extraData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_nbVotes", + "type": "uint256" + } + ], + "name": "createDispute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "currentRuling", + "outputs": [ + { + "internalType": "uint256", + "name": "ruling", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "internalType": "bool", + "name": "overridden", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "disputes", + "outputs": [ + { + "internalType": "uint256", + "name": "numberOfChoices", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "jumped", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "extraData", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "draw", + "outputs": [ + { + "internalType": "address", + "name": "drawnAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_destination", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "executeGovernorProposal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "fundAppeal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + } + ], + "name": "getCoherentCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_voteID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "getDegreeOfCoherence", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "getFundedChoices", + "outputs": [ + { + "internalType": "uint256[]", + "name": "fundedChoices", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "getRoundInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "winningChoice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "tied", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "totalVoted", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalCommited", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nbVoters", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "choiceCount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_voteID", + "type": "uint256" + } + ], + "name": "getVoteInfo", + "outputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "commit", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "choice", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "voted", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "governor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "hashVote", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governor", + "type": "address" + }, + { + "internalType": "contract KlerosCore", + "name": "_core", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "isAppealFunded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_voteID", + "type": "uint256" + } + ], + "name": "isVoteActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "singleDrawPerJuror", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "_beneficiary", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + } + ], + "name": "withdrawFeesAndRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x781be3b0e5e768d27f0f0b524e966e9c7586565987c27424cad63642a879d645", + "receipt": { + "to": null, + "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "contractAddress": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "transactionIndex": 2, + "gasUsed": "4277181", + "logsBloom": "0x00000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000002000000", + "blockHash": "0x700eac84757560eefe085d6376772071ba2bd8935f1ab19a4b8d01e79122806b", + "transactionHash": "0x781be3b0e5e768d27f0f0b524e966e9c7586565987c27424cad63642a879d645", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 148194170, + "transactionHash": "0x781be3b0e5e768d27f0f0b524e966e9c7586565987c27424cad63642a879d645", + "address": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "topics": [ + "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" + ], + "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", + "logIndex": 0, + "blockHash": "0x700eac84757560eefe085d6376772071ba2bd8935f1ab19a4b8d01e79122806b" + } + ], + "blockNumber": 148194170, + "cumulativeGasUsed": "4327957", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "82d7e5c337ef3643567db1fed5df6b5b", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"}],\"name\":\"CommitCastShutter\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"}],\"name\":\"castCommitShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"CommitCastShutter(bytes32,bytes32)\":{\"details\":\"Emitted when a vote is cast.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_identity\":\"The Shutter identity used for encryption.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castCommitShutter(uint256,uint256[],bytes32,bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash including the justification.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encoding\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":\"DisputeKitShutter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbf209306f450437b609837aab267810dcf8311442ed28abb32ad5d62ed43bd9b\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitShutter\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\n/// Added functionality: an Shutter-specific event emitted when a vote is cast.\\ncontract DisputeKitShutter is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.0\\\";\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev Emitted when a vote is cast.\\n /// @param _commit The commitment hash.\\n /// @param _identity The Shutter identity used for encryption.\\n event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity);\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash including the justification.\\n /// @param _identity The Shutter identity used for encryption.\\n function castCommitShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit,\\n bytes32 _identity\\n ) external notJumped(_coreDisputeID) {\\n this.castCommit(_coreDisputeID, _voteIDs, _commit);\\n emit CommitCastShutter(_commit, _identity);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure override returns (bytes32) {\\n bytes32 justificationHash = keccak256(bytes(_justification));\\n return keccak256(abi.encode(_choice, _salt, justificationHash));\\n }\\n}\\n\",\"keccak256\":\"0x778ad0e02dd092c733a958342f743fbdaba1c55304296a2ed381cdc2c022db44\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161441462000103600039600081816118560152818161187f0152611a7701526144146000f3fe6080604052600436106101b95760003560e01c8063675926f6116100ed578063b34bfaa811610090578063b34bfaa8146105a3578063b6ede540146105b9578063ba66fde7146105d9578063be467604146105f9578063d2b8035a1461060f578063da3beb8c1461062f578063e349ad3014610501578063e4c0aaf41461064f578063f2f4eb261461066f57600080fd5b8063675926f61461045457806369f3f041146104745780636d4cd8ea146104c1578063751accd0146104e1578063796490f9146105015780637c04034e146105175780638e42646014610537578063a7cc08fe1461055757600080fd5b8063362c347911610160578063362c34791461031f578063485cc9551461033f5780634b2f0ea01461035f5780634f1ef2861461037257806352d1902d1461038557806354fd4d501461039a578063564a565d146103d85780635c92e2f61461040757806365540b961461042757600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e35780632c535e54146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d9366004613609565b61068f565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e366004613609565b610757565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b50610278610266366004613609565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a1366004613609565b6107ce565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de366004613700565b61093c565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b5061031d61031836600461379a565b610979565b005b34801561032b57600080fd5b5061027861033a36600461380c565b610a77565b34801561034b57600080fd5b5061031d61035a366004613849565b610efd565b61031d61036d366004613882565b610fdb565b61031d6103803660046138a4565b611842565b34801561039157600080fd5b50610278611a6a565b3480156103a657600080fd5b506103cb604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea9190613943565b3480156103e457600080fd5b506103f86103f3366004613609565b611ac8565b6040516101ea9392919061395d565b34801561041357600080fd5b5061031d61042236600461397e565b611b8e565b34801561043357600080fd5b50610447610442366004613609565b611e93565b6040516101ea91906139d0565b34801561046057600080fd5b5061027861046f366004613a14565b611f57565b34801561048057600080fd5b5061049461048f366004613a4f565b61209a565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104cd57600080fd5b506101de6104dc366004613609565b612152565b3480156104ed57600080fd5b5061031d6104fc366004613a7b565b6122d5565b34801561050d57600080fd5b5061027861271081565b34801561052357600080fd5b5061031d610532366004613abd565b6123a1565b34801561054357600080fd5b5061031d610552366004613b41565b612a64565b34801561056357600080fd5b50610577610572366004613a4f565b612ab0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b3480156105af57600080fd5b50610278614e2081565b3480156105c557600080fd5b5061031d6105d4366004613b5e565b612b76565b3480156105e557600080fd5b506101de6105f4366004613a4f565b612d4b565b34801561060557600080fd5b5061027861138881565b34801561061b57600080fd5b5061023361062a366004613882565b612de6565b34801561063b57600080fd5b5061027861064a366004613882565b613100565b34801561065b57600080fd5b5061031d61066a366004613b41565b613253565b34801561067b57600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107009190613be5565b91509150600061070f85611e93565b90508051600014801561074e575061271061138861072d8585613c1f565b6107379190613c32565b6107419190613c49565b61074b8442613c1f565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077b5761077b613c6b565b6000918252602082206005909102018054909250829061079d90600190613c1f565b815481106107ad576107ad613c6b565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107fa576107fa613c6b565b6000918252602082206005909102018054909250829061081c90600190613c1f565b8154811061082c5761082c613c6b565b60009182526020909120600d90910201600381015460ff16945090508361085757806001015461085a565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cd9190613cad565b50909350600492506108dd915050565b8160048111156108ef576108ef613d14565b036109325760006108ff88611e93565b90508051600103610930578060008151811061091d5761091d613c6b565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60008581526003602052604090205460028054879290811061099d5761099d613c6b565b600091825260209091206002600590920201015460ff16156109da5760405162461bcd60e51b81526004016109d190613d2a565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610a03908990899089908990600401613d93565b600060405180830381600087803b158015610a1d57600080fd5b505af1158015610a31573d6000803e3d6000fd5b50505050827f3c1878f78414f58910bc05ea442313ff44d18eb5935c60352518bb2da0eb881283604051610a6791815260200190565b60405180910390a2505050505050565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae99190613cad565b50935050505080610b3c5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016109d1565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190613dbe565b15610bf15760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016109d1565b600086815260036020526040812054600280549091908110610c1557610c15613c6b565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c4957610c49613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc89190613dd9565b5050600087815260078401602052604090205490915060ff16610d12576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e57565b808603610d87576000868152600683016020526040902054610d35576000610d80565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d769190613c32565b610d809190613c49565b9450610e57565b600081815260078301602052604090205460ff16610e575781600601600083600a01600181548110610dbb57610dbb613c6b565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610df157610df1613c6b565b9060005260206000200154815260200190815260200160002054610e159190613e15565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e4a9190613c32565b610e549190613c49565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ef1576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805460019190600160401b900460ff1680610f46575080546001600160401b03808416911610155b15610f635760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f8e848461329f565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fff57610fff613c6b565b600091825260209091206002600590920201015460ff16156110335760405162461bcd60e51b81526004016109d190613d2a565b60008381526003602052604081205460028054909190811061105757611057613c6b565b9060005260206000209060050201905080600101548311156110bb5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016109d1565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c9190613be5565b9150915081421015801561113f57508042105b6111845760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016109d1565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e99190613dd9565b505090508681036111fe57612710915061127f565b61271061138861120e8686613c1f565b6112189190613c32565b6112229190613c49565b61122c8542613c1f565b106112795760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016109d1565b614e2091505b8454600090869061129290600190613c1f565b815481106112a2576112a2613c6b565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015611301573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113259190613e28565b61132f9190613c1f565b60008a815260078401602052604090205490915060ff16156113935760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016109d1565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190613e28565b905060006127106114128784613c32565b61141c9190613c49565b6114269083613e15565b60008c8152600686016020526040812054919250908211156114d75760008c8152600686016020526040902054349061145f9084613c1f565b116114845760008c815260068601602052604090205461147f9083613c1f565b611486565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516114ce929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611503908490613e15565b909155505060008c815260068601602052604081208054839290611528908490613e15565b909155505060008c815260068601602052604090205482116115fa5760008c81526006860160205260408120546009870180549192909161156a908490613e15565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611805578285600901546116179190613c1f565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611665573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116899190613dbe565b156116a25760028a01805460ff19166001179055611785565b895460038b0160006116b5876001613e15565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161173091815260200190565b602060405180830381865afa15801561174d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117719190613e28565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016117d293929190613e7b565b6000604051808303818588803b1580156117eb57600080fd5b505af11580156117ff573d6000803e3d6000fd5b50505050505b8034111561183357336108fc61181b8334613c1f565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61184b826132d5565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806118c957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166118bd6000805160206143bf8339815191525490565b6001600160a01b031614155b156118e75760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611941575060408051601f3d908101601f1916820190925261193e91810190613e28565b60015b61196957604051630c76093760e01b81526001600160a01b03831660048201526024016109d1565b6000805160206143bf833981519152811461199a57604051632a87526960e21b8152600481018290526024016109d1565b6000805160206143bf8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a65576000836001600160a01b031683604051611a019190613f1a565b600060405180830381855af49150503d8060008114611a3c576040519150601f19603f3d011682016040523d82523d6000602084013e611a41565b606091505b5050905080611a63576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ab55760405163703e46dd60e11b815260040160405180910390fd5b506000805160206143bf83398151915290565b60028181548110611ad857600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611b0b90613e41565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3790613e41565b8015611b845780601f10611b5957610100808354040283529160200191611b84565b820191906000526020600020905b815481529060010190602001808311611b6757829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611bb257611bb2613c6b565b600091825260209091206002600590920201015460ff1615611be65760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c549190613cad565b5090935060019250611c64915050565b816004811115611c7657611c76613d14565b14611cd35760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016109d1565b82611d105760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016109d1565b600086815260036020526040812054600280549091908110611d3457611d34613c6b565b60009182526020822060059091020180549092508290611d5690600190613c1f565b81548110611d6657611d66613c6b565b90600052602060002090600d0201905060005b86811015611e2c573382898984818110611d9557611d95613c6b565b9050602002013581548110611dac57611dac613c6b565b60009182526020909120600490910201546001600160a01b031614611de35760405162461bcd60e51b81526004016109d190613f36565b8582898984818110611df757611df7613c6b565b9050602002013581548110611e0e57611e0e613c6b565b60009182526020909120600160049092020181019190915501611d79565b5086869050816005016000828254611e449190613e15565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611e81908b908b908b90613f6d565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611eb957611eb9613c6b565b60009182526020822060059091020180549092508290611edb90600190613c1f565b81548110611eeb57611eeb613c6b565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611f4957602002820191906000526020600020905b815481526020019060010190808311611f35575b505050505092505050919050565b600085815260036020526040812054600280548392908110611f7b57611f7b613c6b565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611faf57611faf613c6b565b90600052602060002090600d02016000018681548110611fd157611fd1613c6b565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561202f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120539190613dd9565b506003850154919350915060ff168015612077575081836002015414806120775750805b1561208a5761271094505050505061074e565b5060009998505050505050505050565b60008060008060008060006002600360008c815260200190815260200160002054815481106120cb576120cb613c6b565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106120ff576120ff613c6b565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061217657612176613c6b565b6000918252602082206005909102018054909250829061219890600190613c1f565b815481106121a8576121a8613c6b565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612203573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122279190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a69190613f91565b50505050509150506000816122bc5783546122c2565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146122ff5760405162461bcd60e51b81526004016109d190613ffb565b6000836001600160a01b0316838360405161231a9190613f1a565b60006040518083038185875af1925050503d8060008114612357576040519150601f19603f3d011682016040523d82523d6000602084013e61235c565b606091505b5050905080611a635760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016109d1565b6000868152600360205260409020546002805488929081106123c5576123c5613c6b565b600091825260209091206002600590920201015460ff16156123f95760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612443573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124679190613cad565b5090935060029250612477915050565b81600481111561248957612489613d14565b146124e45760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016109d1565b856125265760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016109d1565b60008881526003602052604081205460028054909190811061254a5761254a613c6b565b9060005260206000209060050201905080600101548611156125a55760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016109d1565b805460009082906125b890600190613c1f565b815481106125c8576125c8613c6b565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126479190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156126a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c69190613f91565b505050505091505060006126db8a8a8a61093c565b905060005b8b8110156129295733858e8e848181106126fc576126fc613c6b565b905060200201358154811061271357612713613c6b565b60009182526020909120600490910201546001600160a01b03161461274a5760405162461bcd60e51b81526004016109d190613f36565b821580612791575081858e8e8481811061276657612766613c6b565b905060200201358154811061277d5761277d613c6b565b906000526020600020906004020160010154145b6128115760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016109d1565b848d8d8381811061282457612824613c6b565b905060200201358154811061283b5761283b613c6b565b600091825260209091206003600490920201015460ff16156128945760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016109d1565b8a858e8e848181106128a8576128a8613c6b565b90506020020135815481106128bf576128bf613c6b565b60009182526020909120600260049092020101556001858e8e848181106128e8576128e8613c6b565b90506020020135815481106128ff576128ff613c6b565b60009182526020909120600490910201600301805460ff19169115159190911790556001016126e0565b508b8b90508460040160008282546129419190613e15565b909155505060008a8152600285016020526040812080548d9290612966908490613e15565b909155505060018401548a0361299557600384015460ff16156129905760038401805460ff191690555b612a0e565b60018401546000908152600285016020526040808220548c8352912054036129d757600384015460ff166129905760038401805460ff19166001179055612a0e565b60018401546000908152600285016020526040808220548c83529120541115612a0e57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612a4d9392919061403d565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612a8e5760405162461bcd60e51b81526004016109d190613ffb565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612ade57612ade613c6b565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612b1257612b12613c6b565b90600052602060002090600d02016000018781548110612b3457612b34613c6b565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612ba05760405162461bcd60e51b81526004016109d19061406d565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612c2b858783614101565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca69190613e28565b612cb09190613c1f565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612d39908a908a908a906141c1565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612d6f57612d6f613c6b565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612da357612da3613c6b565b90600052602060002090600d02016000018481548110612dc557612dc5613c6b565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612e135760405162461bcd60e51b81526004016109d19061406d565b600083815260036020526040902054600280548592908110612e3757612e37613c6b565b600091825260209091206002600590920201015460ff1615612e6b5760405162461bcd60e51b81526004016109d190613d2a565b600084815260036020526040812054600280549091908110612e8f57612e8f613c6b565b60009182526020822060059091020180549092508290612eb190600190613c1f565b81548110612ec157612ec1613c6b565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4a91906141f7565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fbd9190613cad565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015613021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304591906141f7565b9650613052848a89613302565b156130ef57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556130f4565b600096505b50505050505092915050565b60008281526003602052604081205460028054839290811061312457613124613c6b565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061315857613158613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156131b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131db9190613dd9565b509150915082600401546000148061320a57508015801561320a57506000828152600284016020526040902054155b1561321c57600094505050505061324d565b801561323157505060040154915061324d9050565b50600090815260029091016020526040902054915061324d9050565b92915050565b6000546001600160a01b0316331461327d5760405162461bcd60e51b81526004016109d190613ffb565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6132a76135be565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132ff5760405162461bcd60e51b81526004016109d190613ffb565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133749190613cad565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156133d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f79190613e28565b6134019190613c1f565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613442573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261346a91908101906142a7565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ea91906141f7565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135659190614388565b50509150915082816135779190613e15565b60045490831015955060ff16156135b3578480156135b057506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e54600160401b900460ff1661360757604051631afcd79f60e31b815260040160405180910390fd5b565b60006020828403121561361b57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561365b5761365b613622565b60405290565b604051601f8201601f191681016001600160401b038111828210171561368957613689613622565b604052919050565b600082601f8301126136a257600080fd5b81356001600160401b038111156136bb576136bb613622565b6136ce601f8201601f1916602001613661565b8181528460208386010111156136e357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561371557600080fd5b833592506020840135915060408401356001600160401b0381111561373957600080fd5b61374586828701613691565b9150509250925092565b60008083601f84011261376157600080fd5b5081356001600160401b0381111561377857600080fd5b6020830191508360208260051b850101111561379357600080fd5b9250929050565b6000806000806000608086880312156137b257600080fd5b8535945060208601356001600160401b038111156137cf57600080fd5b6137db8882890161374f565b9699909850959660408101359660609091013595509350505050565b6001600160a01b03811681146132ff57600080fd5b6000806000806080858703121561382257600080fd5b843593506020850135613834816137f7565b93969395505050506040820135916060013590565b6000806040838503121561385c57600080fd5b8235613867816137f7565b91506020830135613877816137f7565b809150509250929050565b6000806040838503121561389557600080fd5b50508035926020909101359150565b600080604083850312156138b757600080fd5b82356138c2816137f7565b915060208301356001600160401b038111156138dd57600080fd5b6138e985828601613691565b9150509250929050565b60005b8381101561390e5781810151838201526020016138f6565b50506000910152565b6000815180845261392f8160208601602086016138f3565b601f01601f19169290920160200192915050565b6020815260006139566020830184613917565b9392505050565b838152821515602082015260606040820152600061074e6060830184613917565b6000806000806060858703121561399457600080fd5b8435935060208501356001600160401b038111156139b157600080fd5b6139bd8782880161374f565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613a08578351835292840192918401916001016139ec565b50909695505050505050565b600080600080600060a08688031215613a2c57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613a6457600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613a9057600080fd5b8335613a9b816137f7565b92506020840135915060408401356001600160401b0381111561373957600080fd5b60008060008060008060a08789031215613ad657600080fd5b8635955060208701356001600160401b0380821115613af457600080fd5b613b008a838b0161374f565b909750955060408901359450606089013593506080890135915080821115613b2757600080fd5b50613b3489828a01613691565b9150509295509295509295565b600060208284031215613b5357600080fd5b8135613956816137f7565b600080600080600060808688031215613b7657600080fd5b853594506020860135935060408601356001600160401b0380821115613b9b57600080fd5b818801915088601f830112613baf57600080fd5b813581811115613bbe57600080fd5b896020828501011115613bd057600080fd5b96999598505060200195606001359392505050565b60008060408385031215613bf857600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561324d5761324d613c09565b808202811582820484141761324d5761324d613c09565b600082613c6657634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613c9857600080fd5b919050565b80518015158114613c9857600080fd5b600080600080600060a08688031215613cc557600080fd5b613cce86613c81565b94506020860151613cde816137f7565b604087015190945060058110613cf357600080fd5b9250613d0160608701613c9d565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613d7a57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613dad606083018587613d61565b905082604083015295945050505050565b600060208284031215613dd057600080fd5b61395682613c9d565b600080600060608486031215613dee57600080fd5b83519250613dfe60208501613c9d565b9150613e0c60408501613c9d565b90509250925092565b8082018082111561324d5761324d613c09565b600060208284031215613e3a57600080fd5b5051919050565b600181811c90821680613e5557607f821691505b602082108103613e7557634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613e9c81613e41565b8060608701526080600180841660008114613ebe5760018114613eda57613f0a565b60ff19851660808a0152608084151560051b8a01019550613f0a565b89600052602060002060005b85811015613f015781548b8201860152908301908801613ee6565b8a016080019650505b50939a9950505050505050505050565b60008251613f2c8184602087016138f3565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b604081526000613f81604083018587613d61565b9050826020830152949350505050565b600080600080600080600060e0888a031215613fac57600080fd5b613fb588613c81565b9650613fc360208901613c9d565b955060408801519450606088015193506080880151925060a08801519150613fed60c08901613c9d565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000614051604083018587613d61565b82810360208401526140638185613917565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a65576000816000526020600020601f850160051c810160208610156140da5750805b601f850160051c820191505b818110156140f9578281556001016140e6565b505050505050565b6001600160401b0383111561411857614118613622565b61412c836141268354613e41565b836140b1565b6000601f84116001811461416057600085156141485750838201355b600019600387901b1c1916600186901b1783556141ba565b600083815260209020601f19861690835b828110156141915786850135825560209485019460019092019101614171565b50868210156141ae5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561420957600080fd5b8151613956816137f7565b600082601f83011261422557600080fd5b815160206001600160401b0382111561424057614240613622565b8160051b61424f828201613661565b928352848101820192828101908785111561426957600080fd5b83870192505b84831015614291578251614282816137f7565b8252918301919083019061426f565b979650505050505050565b8051613c98816137f7565b6000602082840312156142b957600080fd5b81516001600160401b03808211156142d057600080fd5b9083019061016082860312156142e557600080fd5b6142ed613638565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561433557600080fd5b61434187828601614214565b60c08301525060e083810151908201526101008084015190820152610120915061436c82840161429c565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561439e57600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca264697066735822122065e497a857ef0d9707e217ef2b0b31f4d78d648c7c168df7b39e9cfeb52d1c0d64736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106101b95760003560e01c8063675926f6116100ed578063b34bfaa811610090578063b34bfaa8146105a3578063b6ede540146105b9578063ba66fde7146105d9578063be467604146105f9578063d2b8035a1461060f578063da3beb8c1461062f578063e349ad3014610501578063e4c0aaf41461064f578063f2f4eb261461066f57600080fd5b8063675926f61461045457806369f3f041146104745780636d4cd8ea146104c1578063751accd0146104e1578063796490f9146105015780637c04034e146105175780638e42646014610537578063a7cc08fe1461055757600080fd5b8063362c347911610160578063362c34791461031f578063485cc9551461033f5780634b2f0ea01461035f5780634f1ef2861461037257806352d1902d1461038557806354fd4d501461039a578063564a565d146103d85780635c92e2f61461040757806365540b961461042757600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e35780632c535e54146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d9366004613609565b61068f565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e366004613609565b610757565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b50610278610266366004613609565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a1366004613609565b6107ce565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de366004613700565b61093c565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b5061031d61031836600461379a565b610979565b005b34801561032b57600080fd5b5061027861033a36600461380c565b610a77565b34801561034b57600080fd5b5061031d61035a366004613849565b610efd565b61031d61036d366004613882565b610fdb565b61031d6103803660046138a4565b611842565b34801561039157600080fd5b50610278611a6a565b3480156103a657600080fd5b506103cb604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea9190613943565b3480156103e457600080fd5b506103f86103f3366004613609565b611ac8565b6040516101ea9392919061395d565b34801561041357600080fd5b5061031d61042236600461397e565b611b8e565b34801561043357600080fd5b50610447610442366004613609565b611e93565b6040516101ea91906139d0565b34801561046057600080fd5b5061027861046f366004613a14565b611f57565b34801561048057600080fd5b5061049461048f366004613a4f565b61209a565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104cd57600080fd5b506101de6104dc366004613609565b612152565b3480156104ed57600080fd5b5061031d6104fc366004613a7b565b6122d5565b34801561050d57600080fd5b5061027861271081565b34801561052357600080fd5b5061031d610532366004613abd565b6123a1565b34801561054357600080fd5b5061031d610552366004613b41565b612a64565b34801561056357600080fd5b50610577610572366004613a4f565b612ab0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b3480156105af57600080fd5b50610278614e2081565b3480156105c557600080fd5b5061031d6105d4366004613b5e565b612b76565b3480156105e557600080fd5b506101de6105f4366004613a4f565b612d4b565b34801561060557600080fd5b5061027861138881565b34801561061b57600080fd5b5061023361062a366004613882565b612de6565b34801561063b57600080fd5b5061027861064a366004613882565b613100565b34801561065b57600080fd5b5061031d61066a366004613b41565b613253565b34801561067b57600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107009190613be5565b91509150600061070f85611e93565b90508051600014801561074e575061271061138861072d8585613c1f565b6107379190613c32565b6107419190613c49565b61074b8442613c1f565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077b5761077b613c6b565b6000918252602082206005909102018054909250829061079d90600190613c1f565b815481106107ad576107ad613c6b565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107fa576107fa613c6b565b6000918252602082206005909102018054909250829061081c90600190613c1f565b8154811061082c5761082c613c6b565b60009182526020909120600d90910201600381015460ff16945090508361085757806001015461085a565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cd9190613cad565b50909350600492506108dd915050565b8160048111156108ef576108ef613d14565b036109325760006108ff88611e93565b90508051600103610930578060008151811061091d5761091d613c6b565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60008581526003602052604090205460028054879290811061099d5761099d613c6b565b600091825260209091206002600590920201015460ff16156109da5760405162461bcd60e51b81526004016109d190613d2a565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610a03908990899089908990600401613d93565b600060405180830381600087803b158015610a1d57600080fd5b505af1158015610a31573d6000803e3d6000fd5b50505050827f3c1878f78414f58910bc05ea442313ff44d18eb5935c60352518bb2da0eb881283604051610a6791815260200190565b60405180910390a2505050505050565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae99190613cad565b50935050505080610b3c5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016109d1565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190613dbe565b15610bf15760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016109d1565b600086815260036020526040812054600280549091908110610c1557610c15613c6b565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c4957610c49613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc89190613dd9565b5050600087815260078401602052604090205490915060ff16610d12576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e57565b808603610d87576000868152600683016020526040902054610d35576000610d80565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d769190613c32565b610d809190613c49565b9450610e57565b600081815260078301602052604090205460ff16610e575781600601600083600a01600181548110610dbb57610dbb613c6b565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610df157610df1613c6b565b9060005260206000200154815260200190815260200160002054610e159190613e15565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e4a9190613c32565b610e549190613c49565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ef1576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805460019190600160401b900460ff1680610f46575080546001600160401b03808416911610155b15610f635760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f8e848461329f565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fff57610fff613c6b565b600091825260209091206002600590920201015460ff16156110335760405162461bcd60e51b81526004016109d190613d2a565b60008381526003602052604081205460028054909190811061105757611057613c6b565b9060005260206000209060050201905080600101548311156110bb5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016109d1565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c9190613be5565b9150915081421015801561113f57508042105b6111845760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016109d1565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e99190613dd9565b505090508681036111fe57612710915061127f565b61271061138861120e8686613c1f565b6112189190613c32565b6112229190613c49565b61122c8542613c1f565b106112795760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016109d1565b614e2091505b8454600090869061129290600190613c1f565b815481106112a2576112a2613c6b565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015611301573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113259190613e28565b61132f9190613c1f565b60008a815260078401602052604090205490915060ff16156113935760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016109d1565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190613e28565b905060006127106114128784613c32565b61141c9190613c49565b6114269083613e15565b60008c8152600686016020526040812054919250908211156114d75760008c8152600686016020526040902054349061145f9084613c1f565b116114845760008c815260068601602052604090205461147f9083613c1f565b611486565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516114ce929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611503908490613e15565b909155505060008c815260068601602052604081208054839290611528908490613e15565b909155505060008c815260068601602052604090205482116115fa5760008c81526006860160205260408120546009870180549192909161156a908490613e15565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611805578285600901546116179190613c1f565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611665573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116899190613dbe565b156116a25760028a01805460ff19166001179055611785565b895460038b0160006116b5876001613e15565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161173091815260200190565b602060405180830381865afa15801561174d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117719190613e28565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016117d293929190613e7b565b6000604051808303818588803b1580156117eb57600080fd5b505af11580156117ff573d6000803e3d6000fd5b50505050505b8034111561183357336108fc61181b8334613c1f565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61184b826132d5565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806118c957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166118bd6000805160206143bf8339815191525490565b6001600160a01b031614155b156118e75760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611941575060408051601f3d908101601f1916820190925261193e91810190613e28565b60015b61196957604051630c76093760e01b81526001600160a01b03831660048201526024016109d1565b6000805160206143bf833981519152811461199a57604051632a87526960e21b8152600481018290526024016109d1565b6000805160206143bf8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a65576000836001600160a01b031683604051611a019190613f1a565b600060405180830381855af49150503d8060008114611a3c576040519150601f19603f3d011682016040523d82523d6000602084013e611a41565b606091505b5050905080611a63576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ab55760405163703e46dd60e11b815260040160405180910390fd5b506000805160206143bf83398151915290565b60028181548110611ad857600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611b0b90613e41565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3790613e41565b8015611b845780601f10611b5957610100808354040283529160200191611b84565b820191906000526020600020905b815481529060010190602001808311611b6757829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611bb257611bb2613c6b565b600091825260209091206002600590920201015460ff1615611be65760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c549190613cad565b5090935060019250611c64915050565b816004811115611c7657611c76613d14565b14611cd35760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016109d1565b82611d105760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016109d1565b600086815260036020526040812054600280549091908110611d3457611d34613c6b565b60009182526020822060059091020180549092508290611d5690600190613c1f565b81548110611d6657611d66613c6b565b90600052602060002090600d0201905060005b86811015611e2c573382898984818110611d9557611d95613c6b565b9050602002013581548110611dac57611dac613c6b565b60009182526020909120600490910201546001600160a01b031614611de35760405162461bcd60e51b81526004016109d190613f36565b8582898984818110611df757611df7613c6b565b9050602002013581548110611e0e57611e0e613c6b565b60009182526020909120600160049092020181019190915501611d79565b5086869050816005016000828254611e449190613e15565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611e81908b908b908b90613f6d565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611eb957611eb9613c6b565b60009182526020822060059091020180549092508290611edb90600190613c1f565b81548110611eeb57611eeb613c6b565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611f4957602002820191906000526020600020905b815481526020019060010190808311611f35575b505050505092505050919050565b600085815260036020526040812054600280548392908110611f7b57611f7b613c6b565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611faf57611faf613c6b565b90600052602060002090600d02016000018681548110611fd157611fd1613c6b565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561202f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120539190613dd9565b506003850154919350915060ff168015612077575081836002015414806120775750805b1561208a5761271094505050505061074e565b5060009998505050505050505050565b60008060008060008060006002600360008c815260200190815260200160002054815481106120cb576120cb613c6b565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106120ff576120ff613c6b565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061217657612176613c6b565b6000918252602082206005909102018054909250829061219890600190613c1f565b815481106121a8576121a8613c6b565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612203573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122279190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a69190613f91565b50505050509150506000816122bc5783546122c2565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146122ff5760405162461bcd60e51b81526004016109d190613ffb565b6000836001600160a01b0316838360405161231a9190613f1a565b60006040518083038185875af1925050503d8060008114612357576040519150601f19603f3d011682016040523d82523d6000602084013e61235c565b606091505b5050905080611a635760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016109d1565b6000868152600360205260409020546002805488929081106123c5576123c5613c6b565b600091825260209091206002600590920201015460ff16156123f95760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612443573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124679190613cad565b5090935060029250612477915050565b81600481111561248957612489613d14565b146124e45760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016109d1565b856125265760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016109d1565b60008881526003602052604081205460028054909190811061254a5761254a613c6b565b9060005260206000209060050201905080600101548611156125a55760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016109d1565b805460009082906125b890600190613c1f565b815481106125c8576125c8613c6b565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126479190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156126a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c69190613f91565b505050505091505060006126db8a8a8a61093c565b905060005b8b8110156129295733858e8e848181106126fc576126fc613c6b565b905060200201358154811061271357612713613c6b565b60009182526020909120600490910201546001600160a01b03161461274a5760405162461bcd60e51b81526004016109d190613f36565b821580612791575081858e8e8481811061276657612766613c6b565b905060200201358154811061277d5761277d613c6b565b906000526020600020906004020160010154145b6128115760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016109d1565b848d8d8381811061282457612824613c6b565b905060200201358154811061283b5761283b613c6b565b600091825260209091206003600490920201015460ff16156128945760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016109d1565b8a858e8e848181106128a8576128a8613c6b565b90506020020135815481106128bf576128bf613c6b565b60009182526020909120600260049092020101556001858e8e848181106128e8576128e8613c6b565b90506020020135815481106128ff576128ff613c6b565b60009182526020909120600490910201600301805460ff19169115159190911790556001016126e0565b508b8b90508460040160008282546129419190613e15565b909155505060008a8152600285016020526040812080548d9290612966908490613e15565b909155505060018401548a0361299557600384015460ff16156129905760038401805460ff191690555b612a0e565b60018401546000908152600285016020526040808220548c8352912054036129d757600384015460ff166129905760038401805460ff19166001179055612a0e565b60018401546000908152600285016020526040808220548c83529120541115612a0e57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612a4d9392919061403d565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612a8e5760405162461bcd60e51b81526004016109d190613ffb565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612ade57612ade613c6b565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612b1257612b12613c6b565b90600052602060002090600d02016000018781548110612b3457612b34613c6b565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612ba05760405162461bcd60e51b81526004016109d19061406d565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612c2b858783614101565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca69190613e28565b612cb09190613c1f565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612d39908a908a908a906141c1565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612d6f57612d6f613c6b565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612da357612da3613c6b565b90600052602060002090600d02016000018481548110612dc557612dc5613c6b565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612e135760405162461bcd60e51b81526004016109d19061406d565b600083815260036020526040902054600280548592908110612e3757612e37613c6b565b600091825260209091206002600590920201015460ff1615612e6b5760405162461bcd60e51b81526004016109d190613d2a565b600084815260036020526040812054600280549091908110612e8f57612e8f613c6b565b60009182526020822060059091020180549092508290612eb190600190613c1f565b81548110612ec157612ec1613c6b565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4a91906141f7565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fbd9190613cad565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015613021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304591906141f7565b9650613052848a89613302565b156130ef57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556130f4565b600096505b50505050505092915050565b60008281526003602052604081205460028054839290811061312457613124613c6b565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061315857613158613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156131b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131db9190613dd9565b509150915082600401546000148061320a57508015801561320a57506000828152600284016020526040902054155b1561321c57600094505050505061324d565b801561323157505060040154915061324d9050565b50600090815260029091016020526040902054915061324d9050565b92915050565b6000546001600160a01b0316331461327d5760405162461bcd60e51b81526004016109d190613ffb565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6132a76135be565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132ff5760405162461bcd60e51b81526004016109d190613ffb565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133749190613cad565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156133d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f79190613e28565b6134019190613c1f565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613442573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261346a91908101906142a7565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ea91906141f7565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135659190614388565b50509150915082816135779190613e15565b60045490831015955060ff16156135b3578480156135b057506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e54600160401b900460ff1661360757604051631afcd79f60e31b815260040160405180910390fd5b565b60006020828403121561361b57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561365b5761365b613622565b60405290565b604051601f8201601f191681016001600160401b038111828210171561368957613689613622565b604052919050565b600082601f8301126136a257600080fd5b81356001600160401b038111156136bb576136bb613622565b6136ce601f8201601f1916602001613661565b8181528460208386010111156136e357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561371557600080fd5b833592506020840135915060408401356001600160401b0381111561373957600080fd5b61374586828701613691565b9150509250925092565b60008083601f84011261376157600080fd5b5081356001600160401b0381111561377857600080fd5b6020830191508360208260051b850101111561379357600080fd5b9250929050565b6000806000806000608086880312156137b257600080fd5b8535945060208601356001600160401b038111156137cf57600080fd5b6137db8882890161374f565b9699909850959660408101359660609091013595509350505050565b6001600160a01b03811681146132ff57600080fd5b6000806000806080858703121561382257600080fd5b843593506020850135613834816137f7565b93969395505050506040820135916060013590565b6000806040838503121561385c57600080fd5b8235613867816137f7565b91506020830135613877816137f7565b809150509250929050565b6000806040838503121561389557600080fd5b50508035926020909101359150565b600080604083850312156138b757600080fd5b82356138c2816137f7565b915060208301356001600160401b038111156138dd57600080fd5b6138e985828601613691565b9150509250929050565b60005b8381101561390e5781810151838201526020016138f6565b50506000910152565b6000815180845261392f8160208601602086016138f3565b601f01601f19169290920160200192915050565b6020815260006139566020830184613917565b9392505050565b838152821515602082015260606040820152600061074e6060830184613917565b6000806000806060858703121561399457600080fd5b8435935060208501356001600160401b038111156139b157600080fd5b6139bd8782880161374f565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613a08578351835292840192918401916001016139ec565b50909695505050505050565b600080600080600060a08688031215613a2c57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613a6457600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613a9057600080fd5b8335613a9b816137f7565b92506020840135915060408401356001600160401b0381111561373957600080fd5b60008060008060008060a08789031215613ad657600080fd5b8635955060208701356001600160401b0380821115613af457600080fd5b613b008a838b0161374f565b909750955060408901359450606089013593506080890135915080821115613b2757600080fd5b50613b3489828a01613691565b9150509295509295509295565b600060208284031215613b5357600080fd5b8135613956816137f7565b600080600080600060808688031215613b7657600080fd5b853594506020860135935060408601356001600160401b0380821115613b9b57600080fd5b818801915088601f830112613baf57600080fd5b813581811115613bbe57600080fd5b896020828501011115613bd057600080fd5b96999598505060200195606001359392505050565b60008060408385031215613bf857600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561324d5761324d613c09565b808202811582820484141761324d5761324d613c09565b600082613c6657634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613c9857600080fd5b919050565b80518015158114613c9857600080fd5b600080600080600060a08688031215613cc557600080fd5b613cce86613c81565b94506020860151613cde816137f7565b604087015190945060058110613cf357600080fd5b9250613d0160608701613c9d565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613d7a57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613dad606083018587613d61565b905082604083015295945050505050565b600060208284031215613dd057600080fd5b61395682613c9d565b600080600060608486031215613dee57600080fd5b83519250613dfe60208501613c9d565b9150613e0c60408501613c9d565b90509250925092565b8082018082111561324d5761324d613c09565b600060208284031215613e3a57600080fd5b5051919050565b600181811c90821680613e5557607f821691505b602082108103613e7557634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613e9c81613e41565b8060608701526080600180841660008114613ebe5760018114613eda57613f0a565b60ff19851660808a0152608084151560051b8a01019550613f0a565b89600052602060002060005b85811015613f015781548b8201860152908301908801613ee6565b8a016080019650505b50939a9950505050505050505050565b60008251613f2c8184602087016138f3565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b604081526000613f81604083018587613d61565b9050826020830152949350505050565b600080600080600080600060e0888a031215613fac57600080fd5b613fb588613c81565b9650613fc360208901613c9d565b955060408801519450606088015193506080880151925060a08801519150613fed60c08901613c9d565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000614051604083018587613d61565b82810360208401526140638185613917565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a65576000816000526020600020601f850160051c810160208610156140da5750805b601f850160051c820191505b818110156140f9578281556001016140e6565b505050505050565b6001600160401b0383111561411857614118613622565b61412c836141268354613e41565b836140b1565b6000601f84116001811461416057600085156141485750838201355b600019600387901b1c1916600186901b1783556141ba565b600083815260209020601f19861690835b828110156141915786850135825560209485019460019092019101614171565b50868210156141ae5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561420957600080fd5b8151613956816137f7565b600082601f83011261422557600080fd5b815160206001600160401b0382111561424057614240613622565b8160051b61424f828201613661565b928352848101820192828101908785111561426957600080fd5b83870192505b84831015614291578251614282816137f7565b8252918301919083019061426f565b979650505050505050565b8051613c98816137f7565b6000602082840312156142b957600080fd5b81516001600160401b03808211156142d057600080fd5b9083019061016082860312156142e557600080fd5b6142ed613638565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561433557600080fd5b61434187828601614214565b60c08301525060e083810151908201526101008084015190820152610120915061436c82840161429c565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561439e57600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca264697066735822122065e497a857ef0d9707e217ef2b0b31f4d78d648c7c168df7b39e9cfeb52d1c0d64736f6c63430008180033", + "devdoc": { + "errors": { + "AlreadyInitialized()": [ + { + "details": "The contract is already initialized." + } + ], + "InvalidImplementation(address)": [ + { + "details": "The `implementation` is not UUPS-compliant" + } + ], + "NotInitializing()": [ + { + "details": "The contract is not initializing." + } + ], + "UUPSUnauthorizedCallContext()": [ + { + "details": "The call is from an unauthorized context." + } + ], + "UUPSUnsupportedProxiableUUID(bytes32)": [ + { + "details": "The storage `slot` is unsupported as a UUID." + } + ] + }, + "events": { + "ChoiceFunded(uint256,uint256,uint256)": { + "details": "To be emitted when a choice is fully funded for an appeal.", + "params": { + "_choice": "The choice that is being funded.", + "_coreDisputeID": "The identifier of the dispute in the Arbitrator contract.", + "_coreRoundID": "The identifier of the round in the Arbitrator contract." + } + }, + "CommitCast(uint256,address,uint256[],bytes32)": { + "details": "To be emitted when a vote commitment is cast.", + "params": { + "_commit": "The commitment of the juror.", + "_coreDisputeID": "The identifier of the dispute in the Arbitrator contract.", + "_juror": "The address of the juror casting the vote commitment.", + "_voteIDs": "The identifiers of the votes in the dispute." + } + }, + "CommitCastShutter(bytes32,bytes32)": { + "details": "Emitted when a vote is cast.", + "params": { + "_commit": "The commitment hash.", + "_identity": "The Shutter identity used for encryption." + } + }, + "Contribution(uint256,uint256,uint256,address,uint256)": { + "details": "To be emitted when a funding contribution is made.", + "params": { + "_amount": "The amount contributed.", + "_choice": "The choice that is being funded.", + "_contributor": "The address of the contributor.", + "_coreDisputeID": "The identifier of the dispute in the Arbitrator contract.", + "_coreRoundID": "The identifier of the round in the Arbitrator contract." + } + }, + "DisputeCreation(uint256,uint256,bytes)": { + "details": "To be emitted when a dispute is created.", + "params": { + "_coreDisputeID": "The identifier of the dispute in the Arbitrator contract.", + "_extraData": "The extra data for the dispute.", + "_numberOfChoices": "The number of choices available in the dispute." + } + }, + "Initialized(uint64)": { + "details": "Triggered when the contract has been initialized or reinitialized." + }, + "Upgraded(address)": { + "details": "Emitted when the `implementation` has been successfully upgraded.", + "params": { + "newImplementation": "Address of the new implementation the proxy is now forwarding calls to." + } + }, + "VoteCast(uint256,address,uint256[],uint256,string)": { + "details": "Emitted when casting a vote to provide the justification of juror's choice.", + "params": { + "_choice": "The choice juror voted for.", + "_coreDisputeID": "The identifier of the dispute in the Arbitrator contract.", + "_juror": "Address of the juror.", + "_justification": "Justification of the choice.", + "_voteIDs": "The identifiers of the votes in the dispute." + } + }, + "Withdrawal(uint256,uint256,uint256,address,uint256)": { + "details": "To be emitted when the contributed funds are withdrawn.", + "params": { + "_amount": "The amount withdrawn.", + "_choice": "The choice that is being funded.", + "_contributor": "The address of the contributor.", + "_coreDisputeID": "The identifier of the dispute in the Arbitrator contract.", + "_coreRoundID": "The identifier of the round in the Arbitrator contract." + } + } + }, + "kind": "dev", + "methods": { + "areCommitsAllCast(uint256)": { + "details": "Returns true if all of the jurors have cast their commits for the last round.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core." + }, + "returns": { + "_0": "Whether all of the jurors have cast their commits for the last round." + } + }, + "areVotesAllCast(uint256)": { + "details": "Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core." + }, + "returns": { + "_0": "Whether all of the jurors have cast their votes for the last round." + } + }, + "castCommit(uint256,uint256[],bytes32)": { + "details": "Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.", + "params": { + "_commit": "The commitment hash.", + "_coreDisputeID": "The ID of the dispute in Kleros Core.", + "_voteIDs": "The IDs of the votes." + } + }, + "castCommitShutter(uint256,uint256[],bytes32,bytes32)": { + "details": "Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.", + "params": { + "_commit": "The commitment hash including the justification.", + "_coreDisputeID": "The ID of the dispute in Kleros Core.", + "_identity": "The Shutter identity used for encryption.", + "_voteIDs": "The IDs of the votes." + } + }, + "castVote(uint256,uint256[],uint256,uint256,string)": { + "details": "Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.", + "params": { + "_choice": "The choice.", + "_coreDisputeID": "The ID of the dispute in Kleros Core.", + "_justification": "Justification of the choice.", + "_salt": "The salt for the commit if the votes were hidden.", + "_voteIDs": "The IDs of the votes." + } + }, + "changeCore(address)": { + "details": "Changes the `core` storage variable.", + "params": { + "_core": "The new value for the `core` storage variable." + } + }, + "changeGovernor(address)": { + "details": "Changes the `governor` storage variable.", + "params": { + "_governor": "The new value for the `governor` storage variable." + } + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "createDispute(uint256,uint256,bytes,uint256)": { + "details": "Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core.", + "_extraData": "Additional info about the dispute, for possible use in future dispute kits.", + "_nbVotes": "Number of votes for this dispute.", + "_numberOfChoices": "Number of choices of the dispute" + } + }, + "currentRuling(uint256)": { + "details": "Gets the current ruling of a specified dispute.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core." + }, + "returns": { + "overridden": "Whether the ruling was overridden by appeal funding or not.", + "ruling": "The current ruling.", + "tied": "Whether it's a tie or not." + } + }, + "draw(uint256,uint256)": { + "details": "Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core.", + "_nonce": "Nonce of the drawing iteration." + }, + "returns": { + "drawnAddress": "The drawn address." + } + }, + "executeGovernorProposal(address,uint256,bytes)": { + "details": "Allows the governor to call anything on behalf of the contract.", + "params": { + "_amount": "The value sent with the call.", + "_data": "The data sent with the call.", + "_destination": "The destination of the call." + } + }, + "fundAppeal(uint256,uint256)": { + "details": "Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.", + "params": { + "_choice": "A choice that receives funding.", + "_coreDisputeID": "Index of the dispute in Kleros Core." + } + }, + "getCoherentCount(uint256,uint256)": { + "details": "Gets the number of jurors who are eligible to a reward in this round.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core, not in the Dispute Kit.", + "_coreRoundID": "The ID of the round in Kleros Core, not in the Dispute Kit." + }, + "returns": { + "_0": "The number of coherent jurors." + } + }, + "getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)": { + "details": "Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core, not in the Dispute Kit.", + "_coreRoundID": "The ID of the round in Kleros Core, not in the Dispute Kit.", + "_voteID": "The ID of the vote." + }, + "returns": { + "_0": "The degree of coherence in basis points." + } + }, + "hashVote(uint256,uint256,string)": { + "details": "Computes the hash of a vote using ABI encoding", + "params": { + "_choice": "The choice being voted for", + "_justification": "The justification for the vote", + "_salt": "A random salt for commitment" + }, + "returns": { + "_0": "bytes32 The hash of the encoded vote parameters" + } + }, + "initialize(address,address)": { + "details": "Initializer.", + "params": { + "_core": "The KlerosCore arbitrator.", + "_governor": "The governor's address." + } + }, + "isAppealFunded(uint256)": { + "details": "Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core, not in the Dispute Kit." + }, + "returns": { + "_0": "Whether the appeal funding is finished." + } + }, + "isVoteActive(uint256,uint256,uint256)": { + "details": "Returns true if the specified voter was active in this round.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core, not in the Dispute Kit.", + "_coreRoundID": "The ID of the round in Kleros Core, not in the Dispute Kit.", + "_voteID": "The ID of the voter." + }, + "returns": { + "_0": "Whether the voter was active or not." + } + }, + "proxiableUUID()": { + "details": "Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.", + "params": { + "data": "Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.", + "newImplementation": "Address of the new implementation contract." + } + }, + "withdrawFeesAndRewards(uint256,address,uint256,uint256)": { + "details": "Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.", + "params": { + "_beneficiary": "The address whose rewards to withdraw.", + "_choice": "The ruling option that the caller wants to withdraw from.", + "_coreDisputeID": "Index of the dispute in Kleros Core contract.", + "_coreRoundID": "The round in the Kleros Core contract the caller wants to withdraw from." + }, + "returns": { + "amount": "The withdrawn amount." + } + } + }, + "stateVariables": { + "version": { + "details": "Returns the version of the implementation.", + "return": "Version string.", + "returns": { + "_0": "Version string." + } + } + }, + "title": "DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.", + "version": 1 + }, + "userdoc": { + "errors": { + "FailedDelegateCall()": [ + { + "notice": "Failed Delegated call" + } + ] + }, + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3889, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "governor", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3892, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "core", + "offset": 0, + "slot": "1", + "type": "t_contract(KlerosCore)165" + }, + { + "astId": 3896, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "disputes", + "offset": 0, + "slot": "2", + "type": "t_array(t_struct(Dispute)3824_storage)dyn_storage" + }, + { + "astId": 3900, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "coreDisputeIDToLocal", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 3902, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "singleDrawPerJuror", + "offset": 0, + "slot": "4", + "type": "t_bool" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Dispute)3824_storage)dyn_storage": { + "base": "t_struct(Dispute)3824_storage", + "encoding": "dynamic_array", + "label": "struct DisputeKitClassicBase.Dispute[]", + "numberOfBytes": "32" + }, + "t_array(t_struct(Round)3866_storage)dyn_storage": { + "base": "t_struct(Round)3866_storage", + "encoding": "dynamic_array", + "label": "struct DisputeKitClassicBase.Round[]", + "numberOfBytes": "32" + }, + "t_array(t_struct(Vote)3875_storage)dyn_storage": { + "base": "t_struct(Vote)3875_storage", + "encoding": "dynamic_array", + "label": "struct DisputeKitClassicBase.Vote[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)dyn_storage": { + "base": "t_uint256", + "encoding": "dynamic_array", + "label": "uint256[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_bytes_storage": { + "encoding": "bytes", + "label": "bytes", + "numberOfBytes": "32" + }, + "t_contract(KlerosCore)165": { + "encoding": "inplace", + "label": "contract KlerosCore", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_uint256,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(uint256 => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_uint256)" + }, + "t_mapping(t_uint256,t_bool)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(Dispute)3824_storage": { + "encoding": "inplace", + "label": "struct DisputeKitClassicBase.Dispute", + "members": [ + { + "astId": 3813, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "rounds", + "offset": 0, + "slot": "0", + "type": "t_array(t_struct(Round)3866_storage)dyn_storage" + }, + { + "astId": 3815, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "numberOfChoices", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 3817, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "jumped", + "offset": 0, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 3821, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "coreRoundIDToLocal", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 3823, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "extraData", + "offset": 0, + "slot": "4", + "type": "t_bytes_storage" + } + ], + "numberOfBytes": "160" + }, + "t_struct(Round)3866_storage": { + "encoding": "inplace", + "label": "struct DisputeKitClassicBase.Round", + "members": [ + { + "astId": 3828, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "votes", + "offset": 0, + "slot": "0", + "type": "t_array(t_struct(Vote)3875_storage)dyn_storage" + }, + { + "astId": 3830, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "winningChoice", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 3834, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "counts", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 3836, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "tied", + "offset": 0, + "slot": "3", + "type": "t_bool" + }, + { + "astId": 3838, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "totalVoted", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 3840, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "totalCommitted", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 3844, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "paidFees", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 3848, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "hasPaid", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_uint256,t_bool)" + }, + { + "astId": 3854, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "contributions", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" + }, + { + "astId": 3856, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "feeRewards", + "offset": 0, + "slot": "9", + "type": "t_uint256" + }, + { + "astId": 3859, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "fundedChoices", + "offset": 0, + "slot": "10", + "type": "t_array(t_uint256)dyn_storage" + }, + { + "astId": 3861, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "nbVotes", + "offset": 0, + "slot": "11", + "type": "t_uint256" + }, + { + "astId": 3865, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "alreadyDrawn", + "offset": 0, + "slot": "12", + "type": "t_mapping(t_address,t_bool)" + } + ], + "numberOfBytes": "416" + }, + "t_struct(Vote)3875_storage": { + "encoding": "inplace", + "label": "struct DisputeKitClassicBase.Vote", + "members": [ + { + "astId": 3868, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "account", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 3870, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "commit", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 3872, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "choice", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 3874, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "voted", + "offset": 0, + "slot": "3", + "type": "t_bool" + } + ], + "numberOfBytes": "128" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Proxy.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Proxy.json new file mode 100644 index 000000000..416445053 --- /dev/null +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Proxy.json @@ -0,0 +1,81 @@ +{ + "address": "0x09F3d00B995186D76Af9AA8627D06351d0d9f950", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x6274653a9b2599193a56cb902e82ea9860ac9321588e6b5daa2e2d93bf0c1274", + "receipt": { + "to": null, + "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", + "contractAddress": "0x09F3d00B995186D76Af9AA8627D06351d0d9f950", + "transactionIndex": 2, + "gasUsed": "240379", + "logsBloom": "0x00000000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe962e1a9d690b93ef86a8757e1d9d97537e53577738fbe29092cb9dc27bd112b", + "transactionHash": "0x6274653a9b2599193a56cb902e82ea9860ac9321588e6b5daa2e2d93bf0c1274", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 148194178, + "transactionHash": "0x6274653a9b2599193a56cb902e82ea9860ac9321588e6b5daa2e2d93bf0c1274", + "address": "0x09F3d00B995186D76Af9AA8627D06351d0d9f950", + "topics": [ + "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 4, + "blockHash": "0xe962e1a9d690b93ef86a8757e1d9d97537e53577738fbe29092cb9dc27bd112b" + } + ], + "blockNumber": 148194178, + "cumulativeGasUsed": "361637", + "status": 1, + "byzantium": true + }, + "args": [ + "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "0x485cc955000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c590000000000000000000000004838e31e0ea315232c431598110fe677caf2d6e6" + ], + "numDeployments": 1, + "solcInputHash": "96b8e3f55478438b6784f67c1730309e", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitShutterProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitShutterProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x209228b56d42a8444ca70919e1ded5711fba434a746f26d426e230f57526fc6c\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", + "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/contracts/src/proxy/KlerosProxies.sol b/contracts/src/proxy/KlerosProxies.sol index 2a1a9381f..6490b917b 100644 --- a/contracts/src/proxy/KlerosProxies.sol +++ b/contracts/src/proxy/KlerosProxies.sol @@ -23,6 +23,10 @@ contract DisputeKitGatedProxy is UUPSProxy { constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {} } +contract DisputeKitShutterProxy is UUPSProxy { + constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {} +} + contract DisputeKitSybilResistantProxy is UUPSProxy { constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {} } diff --git a/contracts/test/arbitration/index.ts b/contracts/test/arbitration/index.ts index fa2bc24f3..dcc7d960f 100644 --- a/contracts/test/arbitration/index.ts +++ b/contracts/test/arbitration/index.ts @@ -1,23 +1,25 @@ import { expect } from "chai"; import { deployments, ethers } from "hardhat"; -import { KlerosCore, DisputeKitClassic } from "../../typechain-types"; +import { KlerosCore, DisputeKitClassic, DisputeKitShutter } from "../../typechain-types"; import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; describe("DisputeKitClassic", async () => { // eslint-disable-next-line no-unused-vars let deployer: HardhatEthersSigner; - let core: KlerosCore, disputeKit: DisputeKitClassic; + let core: KlerosCore, disputeKit: DisputeKitClassic, disputeKitShutter: DisputeKitShutter; before("Deploying", async () => { [deployer] = await ethers.getSigners(); - [core, disputeKit] = await deployContracts(); + [core, disputeKit, disputeKitShutter] = await deployContracts(); }); it("Kleros Core initialization", async () => { const events = await core.queryFilter(core.filters.DisputeKitCreated()); - expect(events.length).to.equal(1); + expect(events.length).to.equal(2); expect(events[0].args._disputeKitID).to.equal(1); expect(events[0].args._disputeKitAddress).to.equal(disputeKit.target); + expect(events[1].args._disputeKitID).to.equal(2); + expect(events[1].args._disputeKitAddress).to.equal(disputeKitShutter.target); // Reminder: the Forking court will be added which will break these expectations. const events2 = await core.queryFilter(core.filters.CourtCreated()); @@ -60,12 +62,13 @@ describe("DisputeKitClassic", async () => { }); }); -async function deployContracts(): Promise<[KlerosCore, DisputeKitClassic]> { +async function deployContracts(): Promise<[KlerosCore, DisputeKitClassic, DisputeKitShutter]> { await deployments.fixture(["Arbitration", "VeaMock"], { fallbackToGlobal: true, keepExistingDeployments: false, }); const disputeKit = (await ethers.getContract("DisputeKitClassic")) as DisputeKitClassic; + const disputeKitShutter = (await ethers.getContract("DisputeKitShutter")) as DisputeKitShutter; const core = (await ethers.getContract("KlerosCore")) as KlerosCore; - return [core, disputeKit]; + return [core, disputeKit, disputeKitShutter]; } From 74d150619bf702a3fad7247ab943ab9086693b57 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 1 May 2025 00:31:55 +0100 Subject: [PATCH 14/26] fix: missing parameter, upgraded DisputeKitShutter --- contracts/README.md | 6 +- .../DisputeKitShutter.json | 29 +++++++-- .../DisputeKitShutter_Implementation.json | 64 ++++++++++++------- .../dispute-kits/DisputeKitShutter.sol | 15 +++-- 4 files changed, 78 insertions(+), 36 deletions(-) diff --git a/contracts/README.md b/contracts/README.md index 5ad78d2ed..ea2576e4d 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -41,8 +41,8 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [EvidenceModule: proxy](https://sepolia.arbiscan.io/address/0xA88A9a25cE7f1d8b3941dA3b322Ba91D009E1397), [implementation](https://sepolia.arbiscan.io/address/0xC4e64e6E949936a18269937FC1e18cb11E3db14D) - [KlerosCore: proxy](https://sepolia.arbiscan.io/address/0xE8442307d36e9bf6aB27F1A009F95CE8E11C3479), [implementation](https://sepolia.arbiscan.io/address/0x3Dc15eb9673b7228c69aBcF056d4c4044325fdf7) - [KlerosCoreSnapshotProxy](https://sepolia.arbiscan.io/address/0xd74e61A4dB9C6c3F2C97b62a319aE194f616858C) -- [PNKFaucet](https://sepolia.arbiscan.io/address/0x9f6ffc13B685A68ae359fCA128dfE776458Df464) - [PinakionV2](https://sepolia.arbiscan.io/address/0x34B944D42cAcfC8266955D07A80181D2054aa225) +- [PNKFaucet](https://sepolia.arbiscan.io/address/0x9f6ffc13B685A68ae359fCA128dfE776458Df464) - [PolicyRegistry: proxy](https://sepolia.arbiscan.io/address/0x2668c46A14af8997417138B064ca1bEB70769585), [implementation](https://sepolia.arbiscan.io/address/0x7CC8E0787e381aE159C4d3e137f20f9203313D41) - [RandomizerRNG: proxy](https://sepolia.arbiscan.io/address/0x51a97ad9F0aA818e75819da3cA20CAc319580627), [implementation](https://sepolia.arbiscan.io/address/0x1237F02bBeFDAEA20cE3A66aCAe458C4106Ae203) - [SortitionModule: proxy](https://sepolia.arbiscan.io/address/0xbAA5068F0bD1417046250A3eDe2B1F27e31383BD), [implementation](https://sepolia.arbiscan.io/address/0xAe750D6Fa39b1044d4081CB0bfecF886d176Be5b) @@ -79,7 +79,7 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [DAIFaucet](https://sepolia.arbiscan.io/address/0xB5b39A1bcD2D7097A8824B3cC18Ebd2dFb0D9B5E) - [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x2246821E1313A93e2F8CdF7a3422d078f560b457), [implementation](https://sepolia.arbiscan.io/address/0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24) - [DisputeKitClassicUniversity: proxy](https://sepolia.arbiscan.io/address/0xd6E96b7c993763B5CDDa1139C7387B82A7c8B8B5), [implementation](https://sepolia.arbiscan.io/address/0x87e863b94d2CB79A8aB53bD87Dc4A10E11C0918B) -- [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4) +- [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1) - [DisputeResolver](https://sepolia.arbiscan.io/address/0x524C5541f440204E0B4577334c439277018F971f) - [DisputeResolverRuler](https://sepolia.arbiscan.io/address/0x199893232ECC74cC7898B24b5Ff58d613029f6B7) - [DisputeResolverUniversity](https://sepolia.arbiscan.io/address/0x2Aa1a94307E772BeE42E9EfbD137b1053F1fCfd4) @@ -90,8 +90,8 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [KlerosCoreSnapshotProxy](https://sepolia.arbiscan.io/address/0xa2425b724B32D40cbB85ea6e181cfb023CE9c014) - [KlerosCoreUniversity: proxy](https://sepolia.arbiscan.io/address/0x5AB37F38778Bc175852fA353056591D91c744ce6), [implementation](https://sepolia.arbiscan.io/address/0xF74DaBfC5F5dbdBD07636637204d9C35326D2906) - [KlerosV2NeoEarlyUser](https://sepolia.arbiscan.io/address/0x0d60Ff8bbCF49Bc5352328E7E28e141834d7750F) -- [PNKFaucet](https://sepolia.arbiscan.io/address/0x7EFE468003Ad6A858b5350CDE0A67bBED58739dD) - [PinakionV2](https://sepolia.arbiscan.io/address/0x34B944D42cAcfC8266955D07A80181D2054aa225) +- [PNKFaucet](https://sepolia.arbiscan.io/address/0x7EFE468003Ad6A858b5350CDE0A67bBED58739dD) - [PolicyRegistry: proxy](https://sepolia.arbiscan.io/address/0x31d067405184d7FaA64b0834511cBcFAF32CdC4b), [implementation](https://sepolia.arbiscan.io/address/0x09ba3234B3aD786aE46EcDAF388C93D54c145DC0) - [SortitionModule: proxy](https://sepolia.arbiscan.io/address/0xb34651b65A40553C444c6F0D27286C80ec34fbfD), [implementation](https://sepolia.arbiscan.io/address/0xB37919A50d3BddA9982e3c84aA47e501c454364B) - [SortitionModuleUniversity: proxy](https://sepolia.arbiscan.io/address/0x4B2c2d048921f694cCE3AEa35698c6B1f5fcbb79), [implementation](https://sepolia.arbiscan.io/address/0x5CAD621D69E0535422aCFaCC0017bC32beC7A486) diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json index 0418b22a5..c8f3fee8b 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json @@ -121,6 +121,12 @@ "internalType": "bytes32", "name": "_identity", "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_encryptedVote", + "type": "bytes" } ], "name": "CommitCastShutter", @@ -422,6 +428,11 @@ "internalType": "bytes32", "name": "_identity", "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_encryptedVote", + "type": "bytes" } ], "name": "castCommitShutter", @@ -911,6 +922,13 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "initialize2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1100,19 +1118,16 @@ "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", "0x485cc955000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c590000000000000000000000004838e31e0ea315232c431598110fe677caf2d6e6" ], - "numDeployments": 1, + "numDeployments": 2, "solcInputHash": "96b8e3f55478438b6784f67c1730309e", "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitShutterProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitShutterProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x209228b56d42a8444ca70919e1ded5711fba434a746f26d426e230f57526fc6c\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", "execute": { - "methodName": "initialize", - "args": [ - "0xf1C7c037891525E360C59f708739Ac09A7670c59", - "0x4838e31E0ea315232c431598110FE677cAF2D6E6" - ] + "methodName": "initialize2", + "args": [] }, - "implementation": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "implementation": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", "devdoc": { "kind": "dev", "methods": {}, diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json index d1d63d2c0..43fd713f2 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "address": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", "abi": [ { "inputs": [], @@ -118,6 +118,12 @@ "internalType": "bytes32", "name": "_identity", "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_encryptedVote", + "type": "bytes" } ], "name": "CommitCastShutter", @@ -419,6 +425,11 @@ "internalType": "bytes32", "name": "_identity", "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_encryptedVote", + "type": "bytes" } ], "name": "castCommitShutter", @@ -908,6 +919,13 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "initialize2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1048,41 +1066,41 @@ "type": "function" } ], - "transactionHash": "0x781be3b0e5e768d27f0f0b524e966e9c7586565987c27424cad63642a879d645", + "transactionHash": "0x31a2311a33cd1a74a416eeb916aa8f64b65accd95a16a9410203c3fae19e5f5c", "receipt": { "to": null, "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", - "contractAddress": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", - "transactionIndex": 2, - "gasUsed": "4277181", - "logsBloom": "0x00000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000002000000", - "blockHash": "0x700eac84757560eefe085d6376772071ba2bd8935f1ab19a4b8d01e79122806b", - "transactionHash": "0x781be3b0e5e768d27f0f0b524e966e9c7586565987c27424cad63642a879d645", + "contractAddress": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", + "transactionIndex": 1, + "gasUsed": "4159870", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000040000000000000000000000000000000000000000000000000000800000000000800000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1bcabc5ab2d8f545f5091a09103b368cef836aaf173fb51c44d496c0bdd0bf15", + "transactionHash": "0x31a2311a33cd1a74a416eeb916aa8f64b65accd95a16a9410203c3fae19e5f5c", "logs": [ { - "transactionIndex": 2, - "blockNumber": 148194170, - "transactionHash": "0x781be3b0e5e768d27f0f0b524e966e9c7586565987c27424cad63642a879d645", - "address": "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", + "transactionIndex": 1, + "blockNumber": 148204767, + "transactionHash": "0x31a2311a33cd1a74a416eeb916aa8f64b65accd95a16a9410203c3fae19e5f5c", + "address": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", "topics": [ "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" ], "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", "logIndex": 0, - "blockHash": "0x700eac84757560eefe085d6376772071ba2bd8935f1ab19a4b8d01e79122806b" + "blockHash": "0x1bcabc5ab2d8f545f5091a09103b368cef836aaf173fb51c44d496c0bdd0bf15" } ], - "blockNumber": 148194170, - "cumulativeGasUsed": "4327957", + "blockNumber": 148204767, + "cumulativeGasUsed": "4159870", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "82d7e5c337ef3643567db1fed5df6b5b", - "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"}],\"name\":\"CommitCastShutter\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"}],\"name\":\"castCommitShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"CommitCastShutter(bytes32,bytes32)\":{\"details\":\"Emitted when a vote is cast.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_identity\":\"The Shutter identity used for encryption.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castCommitShutter(uint256,uint256[],bytes32,bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash including the justification.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encoding\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":\"DisputeKitShutter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbf209306f450437b609837aab267810dcf8311442ed28abb32ad5d62ed43bd9b\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitShutter\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\n/// Added functionality: an Shutter-specific event emitted when a vote is cast.\\ncontract DisputeKitShutter is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.0\\\";\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev Emitted when a vote is cast.\\n /// @param _commit The commitment hash.\\n /// @param _identity The Shutter identity used for encryption.\\n event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity);\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash including the justification.\\n /// @param _identity The Shutter identity used for encryption.\\n function castCommitShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit,\\n bytes32 _identity\\n ) external notJumped(_coreDisputeID) {\\n this.castCommit(_coreDisputeID, _voteIDs, _commit);\\n emit CommitCastShutter(_commit, _identity);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure override returns (bytes32) {\\n bytes32 justificationHash = keccak256(bytes(_justification));\\n return keccak256(abi.encode(_choice, _salt, justificationHash));\\n }\\n}\\n\",\"keccak256\":\"0x778ad0e02dd092c733a958342f743fbdaba1c55304296a2ed381cdc2c022db44\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161441462000103600039600081816118560152818161187f0152611a7701526144146000f3fe6080604052600436106101b95760003560e01c8063675926f6116100ed578063b34bfaa811610090578063b34bfaa8146105a3578063b6ede540146105b9578063ba66fde7146105d9578063be467604146105f9578063d2b8035a1461060f578063da3beb8c1461062f578063e349ad3014610501578063e4c0aaf41461064f578063f2f4eb261461066f57600080fd5b8063675926f61461045457806369f3f041146104745780636d4cd8ea146104c1578063751accd0146104e1578063796490f9146105015780637c04034e146105175780638e42646014610537578063a7cc08fe1461055757600080fd5b8063362c347911610160578063362c34791461031f578063485cc9551461033f5780634b2f0ea01461035f5780634f1ef2861461037257806352d1902d1461038557806354fd4d501461039a578063564a565d146103d85780635c92e2f61461040757806365540b961461042757600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e35780632c535e54146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d9366004613609565b61068f565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e366004613609565b610757565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b50610278610266366004613609565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a1366004613609565b6107ce565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de366004613700565b61093c565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b5061031d61031836600461379a565b610979565b005b34801561032b57600080fd5b5061027861033a36600461380c565b610a77565b34801561034b57600080fd5b5061031d61035a366004613849565b610efd565b61031d61036d366004613882565b610fdb565b61031d6103803660046138a4565b611842565b34801561039157600080fd5b50610278611a6a565b3480156103a657600080fd5b506103cb604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea9190613943565b3480156103e457600080fd5b506103f86103f3366004613609565b611ac8565b6040516101ea9392919061395d565b34801561041357600080fd5b5061031d61042236600461397e565b611b8e565b34801561043357600080fd5b50610447610442366004613609565b611e93565b6040516101ea91906139d0565b34801561046057600080fd5b5061027861046f366004613a14565b611f57565b34801561048057600080fd5b5061049461048f366004613a4f565b61209a565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104cd57600080fd5b506101de6104dc366004613609565b612152565b3480156104ed57600080fd5b5061031d6104fc366004613a7b565b6122d5565b34801561050d57600080fd5b5061027861271081565b34801561052357600080fd5b5061031d610532366004613abd565b6123a1565b34801561054357600080fd5b5061031d610552366004613b41565b612a64565b34801561056357600080fd5b50610577610572366004613a4f565b612ab0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b3480156105af57600080fd5b50610278614e2081565b3480156105c557600080fd5b5061031d6105d4366004613b5e565b612b76565b3480156105e557600080fd5b506101de6105f4366004613a4f565b612d4b565b34801561060557600080fd5b5061027861138881565b34801561061b57600080fd5b5061023361062a366004613882565b612de6565b34801561063b57600080fd5b5061027861064a366004613882565b613100565b34801561065b57600080fd5b5061031d61066a366004613b41565b613253565b34801561067b57600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107009190613be5565b91509150600061070f85611e93565b90508051600014801561074e575061271061138861072d8585613c1f565b6107379190613c32565b6107419190613c49565b61074b8442613c1f565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077b5761077b613c6b565b6000918252602082206005909102018054909250829061079d90600190613c1f565b815481106107ad576107ad613c6b565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107fa576107fa613c6b565b6000918252602082206005909102018054909250829061081c90600190613c1f565b8154811061082c5761082c613c6b565b60009182526020909120600d90910201600381015460ff16945090508361085757806001015461085a565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cd9190613cad565b50909350600492506108dd915050565b8160048111156108ef576108ef613d14565b036109325760006108ff88611e93565b90508051600103610930578060008151811061091d5761091d613c6b565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60008581526003602052604090205460028054879290811061099d5761099d613c6b565b600091825260209091206002600590920201015460ff16156109da5760405162461bcd60e51b81526004016109d190613d2a565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610a03908990899089908990600401613d93565b600060405180830381600087803b158015610a1d57600080fd5b505af1158015610a31573d6000803e3d6000fd5b50505050827f3c1878f78414f58910bc05ea442313ff44d18eb5935c60352518bb2da0eb881283604051610a6791815260200190565b60405180910390a2505050505050565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae99190613cad565b50935050505080610b3c5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016109d1565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190613dbe565b15610bf15760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016109d1565b600086815260036020526040812054600280549091908110610c1557610c15613c6b565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c4957610c49613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc89190613dd9565b5050600087815260078401602052604090205490915060ff16610d12576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e57565b808603610d87576000868152600683016020526040902054610d35576000610d80565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d769190613c32565b610d809190613c49565b9450610e57565b600081815260078301602052604090205460ff16610e575781600601600083600a01600181548110610dbb57610dbb613c6b565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610df157610df1613c6b565b9060005260206000200154815260200190815260200160002054610e159190613e15565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e4a9190613c32565b610e549190613c49565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ef1576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805460019190600160401b900460ff1680610f46575080546001600160401b03808416911610155b15610f635760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f8e848461329f565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fff57610fff613c6b565b600091825260209091206002600590920201015460ff16156110335760405162461bcd60e51b81526004016109d190613d2a565b60008381526003602052604081205460028054909190811061105757611057613c6b565b9060005260206000209060050201905080600101548311156110bb5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016109d1565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c9190613be5565b9150915081421015801561113f57508042105b6111845760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016109d1565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e99190613dd9565b505090508681036111fe57612710915061127f565b61271061138861120e8686613c1f565b6112189190613c32565b6112229190613c49565b61122c8542613c1f565b106112795760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016109d1565b614e2091505b8454600090869061129290600190613c1f565b815481106112a2576112a2613c6b565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015611301573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113259190613e28565b61132f9190613c1f565b60008a815260078401602052604090205490915060ff16156113935760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016109d1565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190613e28565b905060006127106114128784613c32565b61141c9190613c49565b6114269083613e15565b60008c8152600686016020526040812054919250908211156114d75760008c8152600686016020526040902054349061145f9084613c1f565b116114845760008c815260068601602052604090205461147f9083613c1f565b611486565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516114ce929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611503908490613e15565b909155505060008c815260068601602052604081208054839290611528908490613e15565b909155505060008c815260068601602052604090205482116115fa5760008c81526006860160205260408120546009870180549192909161156a908490613e15565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611805578285600901546116179190613c1f565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611665573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116899190613dbe565b156116a25760028a01805460ff19166001179055611785565b895460038b0160006116b5876001613e15565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161173091815260200190565b602060405180830381865afa15801561174d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117719190613e28565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016117d293929190613e7b565b6000604051808303818588803b1580156117eb57600080fd5b505af11580156117ff573d6000803e3d6000fd5b50505050505b8034111561183357336108fc61181b8334613c1f565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61184b826132d5565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806118c957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166118bd6000805160206143bf8339815191525490565b6001600160a01b031614155b156118e75760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611941575060408051601f3d908101601f1916820190925261193e91810190613e28565b60015b61196957604051630c76093760e01b81526001600160a01b03831660048201526024016109d1565b6000805160206143bf833981519152811461199a57604051632a87526960e21b8152600481018290526024016109d1565b6000805160206143bf8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a65576000836001600160a01b031683604051611a019190613f1a565b600060405180830381855af49150503d8060008114611a3c576040519150601f19603f3d011682016040523d82523d6000602084013e611a41565b606091505b5050905080611a63576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ab55760405163703e46dd60e11b815260040160405180910390fd5b506000805160206143bf83398151915290565b60028181548110611ad857600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611b0b90613e41565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3790613e41565b8015611b845780601f10611b5957610100808354040283529160200191611b84565b820191906000526020600020905b815481529060010190602001808311611b6757829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611bb257611bb2613c6b565b600091825260209091206002600590920201015460ff1615611be65760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c549190613cad565b5090935060019250611c64915050565b816004811115611c7657611c76613d14565b14611cd35760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016109d1565b82611d105760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016109d1565b600086815260036020526040812054600280549091908110611d3457611d34613c6b565b60009182526020822060059091020180549092508290611d5690600190613c1f565b81548110611d6657611d66613c6b565b90600052602060002090600d0201905060005b86811015611e2c573382898984818110611d9557611d95613c6b565b9050602002013581548110611dac57611dac613c6b565b60009182526020909120600490910201546001600160a01b031614611de35760405162461bcd60e51b81526004016109d190613f36565b8582898984818110611df757611df7613c6b565b9050602002013581548110611e0e57611e0e613c6b565b60009182526020909120600160049092020181019190915501611d79565b5086869050816005016000828254611e449190613e15565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611e81908b908b908b90613f6d565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611eb957611eb9613c6b565b60009182526020822060059091020180549092508290611edb90600190613c1f565b81548110611eeb57611eeb613c6b565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611f4957602002820191906000526020600020905b815481526020019060010190808311611f35575b505050505092505050919050565b600085815260036020526040812054600280548392908110611f7b57611f7b613c6b565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611faf57611faf613c6b565b90600052602060002090600d02016000018681548110611fd157611fd1613c6b565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561202f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120539190613dd9565b506003850154919350915060ff168015612077575081836002015414806120775750805b1561208a5761271094505050505061074e565b5060009998505050505050505050565b60008060008060008060006002600360008c815260200190815260200160002054815481106120cb576120cb613c6b565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106120ff576120ff613c6b565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061217657612176613c6b565b6000918252602082206005909102018054909250829061219890600190613c1f565b815481106121a8576121a8613c6b565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612203573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122279190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a69190613f91565b50505050509150506000816122bc5783546122c2565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146122ff5760405162461bcd60e51b81526004016109d190613ffb565b6000836001600160a01b0316838360405161231a9190613f1a565b60006040518083038185875af1925050503d8060008114612357576040519150601f19603f3d011682016040523d82523d6000602084013e61235c565b606091505b5050905080611a635760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016109d1565b6000868152600360205260409020546002805488929081106123c5576123c5613c6b565b600091825260209091206002600590920201015460ff16156123f95760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612443573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124679190613cad565b5090935060029250612477915050565b81600481111561248957612489613d14565b146124e45760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016109d1565b856125265760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016109d1565b60008881526003602052604081205460028054909190811061254a5761254a613c6b565b9060005260206000209060050201905080600101548611156125a55760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016109d1565b805460009082906125b890600190613c1f565b815481106125c8576125c8613c6b565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126479190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156126a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c69190613f91565b505050505091505060006126db8a8a8a61093c565b905060005b8b8110156129295733858e8e848181106126fc576126fc613c6b565b905060200201358154811061271357612713613c6b565b60009182526020909120600490910201546001600160a01b03161461274a5760405162461bcd60e51b81526004016109d190613f36565b821580612791575081858e8e8481811061276657612766613c6b565b905060200201358154811061277d5761277d613c6b565b906000526020600020906004020160010154145b6128115760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016109d1565b848d8d8381811061282457612824613c6b565b905060200201358154811061283b5761283b613c6b565b600091825260209091206003600490920201015460ff16156128945760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016109d1565b8a858e8e848181106128a8576128a8613c6b565b90506020020135815481106128bf576128bf613c6b565b60009182526020909120600260049092020101556001858e8e848181106128e8576128e8613c6b565b90506020020135815481106128ff576128ff613c6b565b60009182526020909120600490910201600301805460ff19169115159190911790556001016126e0565b508b8b90508460040160008282546129419190613e15565b909155505060008a8152600285016020526040812080548d9290612966908490613e15565b909155505060018401548a0361299557600384015460ff16156129905760038401805460ff191690555b612a0e565b60018401546000908152600285016020526040808220548c8352912054036129d757600384015460ff166129905760038401805460ff19166001179055612a0e565b60018401546000908152600285016020526040808220548c83529120541115612a0e57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612a4d9392919061403d565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612a8e5760405162461bcd60e51b81526004016109d190613ffb565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612ade57612ade613c6b565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612b1257612b12613c6b565b90600052602060002090600d02016000018781548110612b3457612b34613c6b565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612ba05760405162461bcd60e51b81526004016109d19061406d565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612c2b858783614101565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca69190613e28565b612cb09190613c1f565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612d39908a908a908a906141c1565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612d6f57612d6f613c6b565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612da357612da3613c6b565b90600052602060002090600d02016000018481548110612dc557612dc5613c6b565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612e135760405162461bcd60e51b81526004016109d19061406d565b600083815260036020526040902054600280548592908110612e3757612e37613c6b565b600091825260209091206002600590920201015460ff1615612e6b5760405162461bcd60e51b81526004016109d190613d2a565b600084815260036020526040812054600280549091908110612e8f57612e8f613c6b565b60009182526020822060059091020180549092508290612eb190600190613c1f565b81548110612ec157612ec1613c6b565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4a91906141f7565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fbd9190613cad565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015613021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304591906141f7565b9650613052848a89613302565b156130ef57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556130f4565b600096505b50505050505092915050565b60008281526003602052604081205460028054839290811061312457613124613c6b565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061315857613158613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156131b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131db9190613dd9565b509150915082600401546000148061320a57508015801561320a57506000828152600284016020526040902054155b1561321c57600094505050505061324d565b801561323157505060040154915061324d9050565b50600090815260029091016020526040902054915061324d9050565b92915050565b6000546001600160a01b0316331461327d5760405162461bcd60e51b81526004016109d190613ffb565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6132a76135be565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132ff5760405162461bcd60e51b81526004016109d190613ffb565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133749190613cad565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156133d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f79190613e28565b6134019190613c1f565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613442573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261346a91908101906142a7565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ea91906141f7565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135659190614388565b50509150915082816135779190613e15565b60045490831015955060ff16156135b3578480156135b057506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e54600160401b900460ff1661360757604051631afcd79f60e31b815260040160405180910390fd5b565b60006020828403121561361b57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561365b5761365b613622565b60405290565b604051601f8201601f191681016001600160401b038111828210171561368957613689613622565b604052919050565b600082601f8301126136a257600080fd5b81356001600160401b038111156136bb576136bb613622565b6136ce601f8201601f1916602001613661565b8181528460208386010111156136e357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561371557600080fd5b833592506020840135915060408401356001600160401b0381111561373957600080fd5b61374586828701613691565b9150509250925092565b60008083601f84011261376157600080fd5b5081356001600160401b0381111561377857600080fd5b6020830191508360208260051b850101111561379357600080fd5b9250929050565b6000806000806000608086880312156137b257600080fd5b8535945060208601356001600160401b038111156137cf57600080fd5b6137db8882890161374f565b9699909850959660408101359660609091013595509350505050565b6001600160a01b03811681146132ff57600080fd5b6000806000806080858703121561382257600080fd5b843593506020850135613834816137f7565b93969395505050506040820135916060013590565b6000806040838503121561385c57600080fd5b8235613867816137f7565b91506020830135613877816137f7565b809150509250929050565b6000806040838503121561389557600080fd5b50508035926020909101359150565b600080604083850312156138b757600080fd5b82356138c2816137f7565b915060208301356001600160401b038111156138dd57600080fd5b6138e985828601613691565b9150509250929050565b60005b8381101561390e5781810151838201526020016138f6565b50506000910152565b6000815180845261392f8160208601602086016138f3565b601f01601f19169290920160200192915050565b6020815260006139566020830184613917565b9392505050565b838152821515602082015260606040820152600061074e6060830184613917565b6000806000806060858703121561399457600080fd5b8435935060208501356001600160401b038111156139b157600080fd5b6139bd8782880161374f565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613a08578351835292840192918401916001016139ec565b50909695505050505050565b600080600080600060a08688031215613a2c57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613a6457600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613a9057600080fd5b8335613a9b816137f7565b92506020840135915060408401356001600160401b0381111561373957600080fd5b60008060008060008060a08789031215613ad657600080fd5b8635955060208701356001600160401b0380821115613af457600080fd5b613b008a838b0161374f565b909750955060408901359450606089013593506080890135915080821115613b2757600080fd5b50613b3489828a01613691565b9150509295509295509295565b600060208284031215613b5357600080fd5b8135613956816137f7565b600080600080600060808688031215613b7657600080fd5b853594506020860135935060408601356001600160401b0380821115613b9b57600080fd5b818801915088601f830112613baf57600080fd5b813581811115613bbe57600080fd5b896020828501011115613bd057600080fd5b96999598505060200195606001359392505050565b60008060408385031215613bf857600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561324d5761324d613c09565b808202811582820484141761324d5761324d613c09565b600082613c6657634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613c9857600080fd5b919050565b80518015158114613c9857600080fd5b600080600080600060a08688031215613cc557600080fd5b613cce86613c81565b94506020860151613cde816137f7565b604087015190945060058110613cf357600080fd5b9250613d0160608701613c9d565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613d7a57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613dad606083018587613d61565b905082604083015295945050505050565b600060208284031215613dd057600080fd5b61395682613c9d565b600080600060608486031215613dee57600080fd5b83519250613dfe60208501613c9d565b9150613e0c60408501613c9d565b90509250925092565b8082018082111561324d5761324d613c09565b600060208284031215613e3a57600080fd5b5051919050565b600181811c90821680613e5557607f821691505b602082108103613e7557634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613e9c81613e41565b8060608701526080600180841660008114613ebe5760018114613eda57613f0a565b60ff19851660808a0152608084151560051b8a01019550613f0a565b89600052602060002060005b85811015613f015781548b8201860152908301908801613ee6565b8a016080019650505b50939a9950505050505050505050565b60008251613f2c8184602087016138f3565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b604081526000613f81604083018587613d61565b9050826020830152949350505050565b600080600080600080600060e0888a031215613fac57600080fd5b613fb588613c81565b9650613fc360208901613c9d565b955060408801519450606088015193506080880151925060a08801519150613fed60c08901613c9d565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000614051604083018587613d61565b82810360208401526140638185613917565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a65576000816000526020600020601f850160051c810160208610156140da5750805b601f850160051c820191505b818110156140f9578281556001016140e6565b505050505050565b6001600160401b0383111561411857614118613622565b61412c836141268354613e41565b836140b1565b6000601f84116001811461416057600085156141485750838201355b600019600387901b1c1916600186901b1783556141ba565b600083815260209020601f19861690835b828110156141915786850135825560209485019460019092019101614171565b50868210156141ae5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561420957600080fd5b8151613956816137f7565b600082601f83011261422557600080fd5b815160206001600160401b0382111561424057614240613622565b8160051b61424f828201613661565b928352848101820192828101908785111561426957600080fd5b83870192505b84831015614291578251614282816137f7565b8252918301919083019061426f565b979650505050505050565b8051613c98816137f7565b6000602082840312156142b957600080fd5b81516001600160401b03808211156142d057600080fd5b9083019061016082860312156142e557600080fd5b6142ed613638565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561433557600080fd5b61434187828601614214565b60c08301525060e083810151908201526101008084015190820152610120915061436c82840161429c565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561439e57600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca264697066735822122065e497a857ef0d9707e217ef2b0b31f4d78d648c7c168df7b39e9cfeb52d1c0d64736f6c63430008180033", - "deployedBytecode": "0x6080604052600436106101b95760003560e01c8063675926f6116100ed578063b34bfaa811610090578063b34bfaa8146105a3578063b6ede540146105b9578063ba66fde7146105d9578063be467604146105f9578063d2b8035a1461060f578063da3beb8c1461062f578063e349ad3014610501578063e4c0aaf41461064f578063f2f4eb261461066f57600080fd5b8063675926f61461045457806369f3f041146104745780636d4cd8ea146104c1578063751accd0146104e1578063796490f9146105015780637c04034e146105175780638e42646014610537578063a7cc08fe1461055757600080fd5b8063362c347911610160578063362c34791461031f578063485cc9551461033f5780634b2f0ea01461035f5780634f1ef2861461037257806352d1902d1461038557806354fd4d501461039a578063564a565d146103d85780635c92e2f61461040757806365540b961461042757600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e35780632c535e54146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d9366004613609565b61068f565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e366004613609565b610757565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b50610278610266366004613609565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a1366004613609565b6107ce565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de366004613700565b61093c565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b5061031d61031836600461379a565b610979565b005b34801561032b57600080fd5b5061027861033a36600461380c565b610a77565b34801561034b57600080fd5b5061031d61035a366004613849565b610efd565b61031d61036d366004613882565b610fdb565b61031d6103803660046138a4565b611842565b34801561039157600080fd5b50610278611a6a565b3480156103a657600080fd5b506103cb604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea9190613943565b3480156103e457600080fd5b506103f86103f3366004613609565b611ac8565b6040516101ea9392919061395d565b34801561041357600080fd5b5061031d61042236600461397e565b611b8e565b34801561043357600080fd5b50610447610442366004613609565b611e93565b6040516101ea91906139d0565b34801561046057600080fd5b5061027861046f366004613a14565b611f57565b34801561048057600080fd5b5061049461048f366004613a4f565b61209a565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104cd57600080fd5b506101de6104dc366004613609565b612152565b3480156104ed57600080fd5b5061031d6104fc366004613a7b565b6122d5565b34801561050d57600080fd5b5061027861271081565b34801561052357600080fd5b5061031d610532366004613abd565b6123a1565b34801561054357600080fd5b5061031d610552366004613b41565b612a64565b34801561056357600080fd5b50610577610572366004613a4f565b612ab0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b3480156105af57600080fd5b50610278614e2081565b3480156105c557600080fd5b5061031d6105d4366004613b5e565b612b76565b3480156105e557600080fd5b506101de6105f4366004613a4f565b612d4b565b34801561060557600080fd5b5061027861138881565b34801561061b57600080fd5b5061023361062a366004613882565b612de6565b34801561063b57600080fd5b5061027861064a366004613882565b613100565b34801561065b57600080fd5b5061031d61066a366004613b41565b613253565b34801561067b57600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107009190613be5565b91509150600061070f85611e93565b90508051600014801561074e575061271061138861072d8585613c1f565b6107379190613c32565b6107419190613c49565b61074b8442613c1f565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077b5761077b613c6b565b6000918252602082206005909102018054909250829061079d90600190613c1f565b815481106107ad576107ad613c6b565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107fa576107fa613c6b565b6000918252602082206005909102018054909250829061081c90600190613c1f565b8154811061082c5761082c613c6b565b60009182526020909120600d90910201600381015460ff16945090508361085757806001015461085a565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cd9190613cad565b50909350600492506108dd915050565b8160048111156108ef576108ef613d14565b036109325760006108ff88611e93565b90508051600103610930578060008151811061091d5761091d613c6b565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60008581526003602052604090205460028054879290811061099d5761099d613c6b565b600091825260209091206002600590920201015460ff16156109da5760405162461bcd60e51b81526004016109d190613d2a565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610a03908990899089908990600401613d93565b600060405180830381600087803b158015610a1d57600080fd5b505af1158015610a31573d6000803e3d6000fd5b50505050827f3c1878f78414f58910bc05ea442313ff44d18eb5935c60352518bb2da0eb881283604051610a6791815260200190565b60405180910390a2505050505050565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae99190613cad565b50935050505080610b3c5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016109d1565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb39190613dbe565b15610bf15760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016109d1565b600086815260036020526040812054600280549091908110610c1557610c15613c6b565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c4957610c49613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610ca4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc89190613dd9565b5050600087815260078401602052604090205490915060ff16610d12576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e57565b808603610d87576000868152600683016020526040902054610d35576000610d80565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d769190613c32565b610d809190613c49565b9450610e57565b600081815260078301602052604090205460ff16610e575781600601600083600a01600181548110610dbb57610dbb613c6b565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610df157610df1613c6b565b9060005260206000200154815260200190815260200160002054610e159190613e15565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e4a9190613c32565b610e549190613c49565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ef1576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805460019190600160401b900460ff1680610f46575080546001600160401b03808416911610155b15610f635760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f8e848461329f565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fff57610fff613c6b565b600091825260209091206002600590920201015460ff16156110335760405162461bcd60e51b81526004016109d190613d2a565b60008381526003602052604081205460028054909190811061105757611057613c6b565b9060005260206000209060050201905080600101548311156110bb5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016109d1565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015611108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112c9190613be5565b9150915081421015801561113f57508042105b6111845760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016109d1565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa1580156111c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e99190613dd9565b505090508681036111fe57612710915061127f565b61271061138861120e8686613c1f565b6112189190613c32565b6112229190613c49565b61122c8542613c1f565b106112795760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016109d1565b614e2091505b8454600090869061129290600190613c1f565b815481106112a2576112a2613c6b565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015611301573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113259190613e28565b61132f9190613c1f565b60008a815260078401602052604090205490915060ff16156113935760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016109d1565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156113dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114019190613e28565b905060006127106114128784613c32565b61141c9190613c49565b6114269083613e15565b60008c8152600686016020526040812054919250908211156114d75760008c8152600686016020526040902054349061145f9084613c1f565b116114845760008c815260068601602052604090205461147f9083613c1f565b611486565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516114ce929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611503908490613e15565b909155505060008c815260068601602052604081208054839290611528908490613e15565b909155505060008c815260068601602052604090205482116115fa5760008c81526006860160205260408120546009870180549192909161156a908490613e15565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611805578285600901546116179190613c1f565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611665573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116899190613dbe565b156116a25760028a01805460ff19166001179055611785565b895460038b0160006116b5876001613e15565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161173091815260200190565b602060405180830381865afa15801561174d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117719190613e28565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016117d293929190613e7b565b6000604051808303818588803b1580156117eb57600080fd5b505af11580156117ff573d6000803e3d6000fd5b50505050505b8034111561183357336108fc61181b8334613c1f565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61184b826132d5565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806118c957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166118bd6000805160206143bf8339815191525490565b6001600160a01b031614155b156118e75760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611941575060408051601f3d908101601f1916820190925261193e91810190613e28565b60015b61196957604051630c76093760e01b81526001600160a01b03831660048201526024016109d1565b6000805160206143bf833981519152811461199a57604051632a87526960e21b8152600481018290526024016109d1565b6000805160206143bf8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a65576000836001600160a01b031683604051611a019190613f1a565b600060405180830381855af49150503d8060008114611a3c576040519150601f19603f3d011682016040523d82523d6000602084013e611a41565b606091505b5050905080611a63576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ab55760405163703e46dd60e11b815260040160405180910390fd5b506000805160206143bf83398151915290565b60028181548110611ad857600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611b0b90613e41565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3790613e41565b8015611b845780601f10611b5957610100808354040283529160200191611b84565b820191906000526020600020905b815481529060010190602001808311611b6757829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611bb257611bb2613c6b565b600091825260209091206002600590920201015460ff1615611be65760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c549190613cad565b5090935060019250611c64915050565b816004811115611c7657611c76613d14565b14611cd35760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016109d1565b82611d105760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016109d1565b600086815260036020526040812054600280549091908110611d3457611d34613c6b565b60009182526020822060059091020180549092508290611d5690600190613c1f565b81548110611d6657611d66613c6b565b90600052602060002090600d0201905060005b86811015611e2c573382898984818110611d9557611d95613c6b565b9050602002013581548110611dac57611dac613c6b565b60009182526020909120600490910201546001600160a01b031614611de35760405162461bcd60e51b81526004016109d190613f36565b8582898984818110611df757611df7613c6b565b9050602002013581548110611e0e57611e0e613c6b565b60009182526020909120600160049092020181019190915501611d79565b5086869050816005016000828254611e449190613e15565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611e81908b908b908b90613f6d565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611eb957611eb9613c6b565b60009182526020822060059091020180549092508290611edb90600190613c1f565b81548110611eeb57611eeb613c6b565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611f4957602002820191906000526020600020905b815481526020019060010190808311611f35575b505050505092505050919050565b600085815260036020526040812054600280548392908110611f7b57611f7b613c6b565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611faf57611faf613c6b565b90600052602060002090600d02016000018681548110611fd157611fd1613c6b565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561202f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120539190613dd9565b506003850154919350915060ff168015612077575081836002015414806120775750805b1561208a5761271094505050505061074e565b5060009998505050505050505050565b60008060008060008060006002600360008c815260200190815260200160002054815481106120cb576120cb613c6b565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106120ff576120ff613c6b565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061217657612176613c6b565b6000918252602082206005909102018054909250829061219890600190613c1f565b815481106121a8576121a8613c6b565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612203573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122279190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612282573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122a69190613f91565b50505050509150506000816122bc5783546122c2565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146122ff5760405162461bcd60e51b81526004016109d190613ffb565b6000836001600160a01b0316838360405161231a9190613f1a565b60006040518083038185875af1925050503d8060008114612357576040519150601f19603f3d011682016040523d82523d6000602084013e61235c565b606091505b5050905080611a635760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016109d1565b6000868152600360205260409020546002805488929081106123c5576123c5613c6b565b600091825260209091206002600590920201015460ff16156123f95760405162461bcd60e51b81526004016109d190613d2a565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612443573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124679190613cad565b5090935060029250612477915050565b81600481111561248957612489613d14565b146124e45760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016109d1565b856125265760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016109d1565b60008881526003602052604081205460028054909190811061254a5761254a613c6b565b9060005260206000209060050201905080600101548611156125a55760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016109d1565b805460009082906125b890600190613c1f565b815481106125c8576125c8613c6b565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126479190613cad565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156126a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c69190613f91565b505050505091505060006126db8a8a8a61093c565b905060005b8b8110156129295733858e8e848181106126fc576126fc613c6b565b905060200201358154811061271357612713613c6b565b60009182526020909120600490910201546001600160a01b03161461274a5760405162461bcd60e51b81526004016109d190613f36565b821580612791575081858e8e8481811061276657612766613c6b565b905060200201358154811061277d5761277d613c6b565b906000526020600020906004020160010154145b6128115760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016109d1565b848d8d8381811061282457612824613c6b565b905060200201358154811061283b5761283b613c6b565b600091825260209091206003600490920201015460ff16156128945760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016109d1565b8a858e8e848181106128a8576128a8613c6b565b90506020020135815481106128bf576128bf613c6b565b60009182526020909120600260049092020101556001858e8e848181106128e8576128e8613c6b565b90506020020135815481106128ff576128ff613c6b565b60009182526020909120600490910201600301805460ff19169115159190911790556001016126e0565b508b8b90508460040160008282546129419190613e15565b909155505060008a8152600285016020526040812080548d9290612966908490613e15565b909155505060018401548a0361299557600384015460ff16156129905760038401805460ff191690555b612a0e565b60018401546000908152600285016020526040808220548c8352912054036129d757600384015460ff166129905760038401805460ff19166001179055612a0e565b60018401546000908152600285016020526040808220548c83529120541115612a0e57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612a4d9392919061403d565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612a8e5760405162461bcd60e51b81526004016109d190613ffb565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612ade57612ade613c6b565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612b1257612b12613c6b565b90600052602060002090600d02016000018781548110612b3457612b34613c6b565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612ba05760405162461bcd60e51b81526004016109d19061406d565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612c2b858783614101565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ca69190613e28565b612cb09190613c1f565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612d39908a908a908a906141c1565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612d6f57612d6f613c6b565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612da357612da3613c6b565b90600052602060002090600d02016000018481548110612dc557612dc5613c6b565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612e135760405162461bcd60e51b81526004016109d19061406d565b600083815260036020526040902054600280548592908110612e3757612e37613c6b565b600091825260209091206002600590920201015460ff1615612e6b5760405162461bcd60e51b81526004016109d190613d2a565b600084815260036020526040812054600280549091908110612e8f57612e8f613c6b565b60009182526020822060059091020180549092508290612eb190600190613c1f565b81548110612ec157612ec1613c6b565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4a91906141f7565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612f99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fbd9190613cad565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015613021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304591906141f7565b9650613052848a89613302565b156130ef57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556130f4565b600096505b50505050505092915050565b60008281526003602052604081205460028054839290811061312457613124613c6b565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061315857613158613c6b565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156131b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131db9190613dd9565b509150915082600401546000148061320a57508015801561320a57506000828152600284016020526040902054155b1561321c57600094505050505061324d565b801561323157505060040154915061324d9050565b50600090815260029091016020526040902054915061324d9050565b92915050565b6000546001600160a01b0316331461327d5760405162461bcd60e51b81526004016109d190613ffb565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6132a76135be565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132ff5760405162461bcd60e51b81526004016109d190613ffb565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133749190613cad565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156133d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f79190613e28565b6134019190613c1f565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613442573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261346a91908101906142a7565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ea91906141f7565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613541573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135659190614388565b50509150915082816135779190613e15565b60045490831015955060ff16156135b3578480156135b057506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e54600160401b900460ff1661360757604051631afcd79f60e31b815260040160405180910390fd5b565b60006020828403121561361b57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561365b5761365b613622565b60405290565b604051601f8201601f191681016001600160401b038111828210171561368957613689613622565b604052919050565b600082601f8301126136a257600080fd5b81356001600160401b038111156136bb576136bb613622565b6136ce601f8201601f1916602001613661565b8181528460208386010111156136e357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561371557600080fd5b833592506020840135915060408401356001600160401b0381111561373957600080fd5b61374586828701613691565b9150509250925092565b60008083601f84011261376157600080fd5b5081356001600160401b0381111561377857600080fd5b6020830191508360208260051b850101111561379357600080fd5b9250929050565b6000806000806000608086880312156137b257600080fd5b8535945060208601356001600160401b038111156137cf57600080fd5b6137db8882890161374f565b9699909850959660408101359660609091013595509350505050565b6001600160a01b03811681146132ff57600080fd5b6000806000806080858703121561382257600080fd5b843593506020850135613834816137f7565b93969395505050506040820135916060013590565b6000806040838503121561385c57600080fd5b8235613867816137f7565b91506020830135613877816137f7565b809150509250929050565b6000806040838503121561389557600080fd5b50508035926020909101359150565b600080604083850312156138b757600080fd5b82356138c2816137f7565b915060208301356001600160401b038111156138dd57600080fd5b6138e985828601613691565b9150509250929050565b60005b8381101561390e5781810151838201526020016138f6565b50506000910152565b6000815180845261392f8160208601602086016138f3565b601f01601f19169290920160200192915050565b6020815260006139566020830184613917565b9392505050565b838152821515602082015260606040820152600061074e6060830184613917565b6000806000806060858703121561399457600080fd5b8435935060208501356001600160401b038111156139b157600080fd5b6139bd8782880161374f565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613a08578351835292840192918401916001016139ec565b50909695505050505050565b600080600080600060a08688031215613a2c57600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613a6457600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613a9057600080fd5b8335613a9b816137f7565b92506020840135915060408401356001600160401b0381111561373957600080fd5b60008060008060008060a08789031215613ad657600080fd5b8635955060208701356001600160401b0380821115613af457600080fd5b613b008a838b0161374f565b909750955060408901359450606089013593506080890135915080821115613b2757600080fd5b50613b3489828a01613691565b9150509295509295509295565b600060208284031215613b5357600080fd5b8135613956816137f7565b600080600080600060808688031215613b7657600080fd5b853594506020860135935060408601356001600160401b0380821115613b9b57600080fd5b818801915088601f830112613baf57600080fd5b813581811115613bbe57600080fd5b896020828501011115613bd057600080fd5b96999598505060200195606001359392505050565b60008060408385031215613bf857600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561324d5761324d613c09565b808202811582820484141761324d5761324d613c09565b600082613c6657634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613c9857600080fd5b919050565b80518015158114613c9857600080fd5b600080600080600060a08688031215613cc557600080fd5b613cce86613c81565b94506020860151613cde816137f7565b604087015190945060058110613cf357600080fd5b9250613d0160608701613c9d565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613d7a57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613dad606083018587613d61565b905082604083015295945050505050565b600060208284031215613dd057600080fd5b61395682613c9d565b600080600060608486031215613dee57600080fd5b83519250613dfe60208501613c9d565b9150613e0c60408501613c9d565b90509250925092565b8082018082111561324d5761324d613c09565b600060208284031215613e3a57600080fd5b5051919050565b600181811c90821680613e5557607f821691505b602082108103613e7557634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613e9c81613e41565b8060608701526080600180841660008114613ebe5760018114613eda57613f0a565b60ff19851660808a0152608084151560051b8a01019550613f0a565b89600052602060002060005b85811015613f015781548b8201860152908301908801613ee6565b8a016080019650505b50939a9950505050505050505050565b60008251613f2c8184602087016138f3565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b604081526000613f81604083018587613d61565b9050826020830152949350505050565b600080600080600080600060e0888a031215613fac57600080fd5b613fb588613c81565b9650613fc360208901613c9d565b955060408801519450606088015193506080880151925060a08801519150613fed60c08901613c9d565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000614051604083018587613d61565b82810360208401526140638185613917565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a65576000816000526020600020601f850160051c810160208610156140da5750805b601f850160051c820191505b818110156140f9578281556001016140e6565b505050505050565b6001600160401b0383111561411857614118613622565b61412c836141268354613e41565b836140b1565b6000601f84116001811461416057600085156141485750838201355b600019600387901b1c1916600186901b1783556141ba565b600083815260209020601f19861690835b828110156141915786850135825560209485019460019092019101614171565b50868210156141ae5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561420957600080fd5b8151613956816137f7565b600082601f83011261422557600080fd5b815160206001600160401b0382111561424057614240613622565b8160051b61424f828201613661565b928352848101820192828101908785111561426957600080fd5b83870192505b84831015614291578251614282816137f7565b8252918301919083019061426f565b979650505050505050565b8051613c98816137f7565b6000602082840312156142b957600080fd5b81516001600160401b03808211156142d057600080fd5b9083019061016082860312156142e557600080fd5b6142ed613638565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561433557600080fd5b61434187828601614214565b60c08301525060e083810151908201526101008084015190820152610120915061436c82840161429c565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561439e57600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca264697066735822122065e497a857ef0d9707e217ef2b0b31f4d78d648c7c168df7b39e9cfeb52d1c0d64736f6c63430008180033", + "numDeployments": 2, + "solcInputHash": "720097f21043cca39229dbd8e433d9d2", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"CommitCastShutter\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"castCommitShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"CommitCastShutter(bytes32,bytes32,bytes)\":{\"details\":\"Emitted when a vote is cast.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castCommitShutter(uint256,uint256[],bytes32,bytes32,bytes)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash including the justification.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encoding\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":\"DisputeKitShutter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbf209306f450437b609837aab267810dcf8311442ed28abb32ad5d62ed43bd9b\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitShutter\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\n/// Added functionality: an Shutter-specific event emitted when a vote is cast.\\ncontract DisputeKitShutter is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.1\\\";\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev Emitted when a vote is cast.\\n /// @param _commit The commitment hash.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity, bytes _encryptedVote);\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize2() external reinitializer(2) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash including the justification.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n function castCommitShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit,\\n bytes32 _identity,\\n bytes calldata _encryptedVote\\n ) external notJumped(_coreDisputeID) {\\n this.castCommit(_coreDisputeID, _voteIDs, _commit);\\n emit CommitCastShutter(_commit, _identity, _encryptedVote);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure override returns (bytes32) {\\n bytes32 justificationHash = keccak256(bytes(_justification));\\n return keccak256(abi.encode(_choice, _salt, justificationHash));\\n }\\n}\\n\",\"keccak256\":\"0x94bebe1d3b5297a7130dd2c7f4bdae3af2789491bed0256d4dd1aaefecb98ab5\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161452b62000103600039600081816119150152818161193e0152611b36015261452b6000f3fe6080604052600436106101c45760003560e01c806365540b96116100f8578063b34bfaa811610090578063b34bfaa8146105c3578063b6ede540146105d9578063ba66fde7146105f9578063be46760414610619578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad3014610521578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b806365540b9614610447578063675926f61461047457806369f3f041146104945780636d4cd8ea146104e1578063751accd014610501578063796490f9146105215780637c04034e146105375780638e42646014610557578063a7cc08fe1461057757600080fd5b8063362c34791161016b578063362c34791461032a578063472abf681461034a578063485cc9551461035f5780634b2f0ea01461037f5780634f1ef2861461039257806352d1902d146103a557806354fd4d50146103ba578063564a565d146103f85780635c92e2f61461042757600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136d0565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613775565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136d0565b610879565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136d0565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136d0565b6108f0565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138df565b610a5e565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613943565b610a9b565b34801561035657600080fd5b5061021e610f21565b34801561036b57600080fd5b5061021e61037a366004613980565b610fd2565b61021e61038d3660046139b9565b61109a565b61021e6103a03660046139db565b611901565b3480156103b157600080fd5b506102a5611b29565b3480156103c657600080fd5b506103eb60405180604001604052806005815260200164302e392e3160d81b81525081565b6040516101f59190613a7a565b34801561040457600080fd5b506104186104133660046136d0565b611b87565b6040516101f593929190613a94565b34801561043357600080fd5b5061021e610442366004613ab5565b611c4d565b34801561045357600080fd5b506104676104623660046136d0565b611f52565b6040516101f59190613b07565b34801561048057600080fd5b506102a561048f366004613b4b565b612016565b3480156104a057600080fd5b506104b46104af366004613b86565b612159565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104ed57600080fd5b506101e96104fc3660046136d0565b612211565b34801561050d57600080fd5b5061021e61051c366004613bb2565b612394565b34801561052d57600080fd5b506102a561271081565b34801561054357600080fd5b5061021e610552366004613bf4565b612460565b34801561056357600080fd5b5061021e610572366004613c78565b612b23565b34801561058357600080fd5b50610597610592366004613b86565b612b6f565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105cf57600080fd5b506102a5614e2081565b3480156105e557600080fd5b5061021e6105f4366004613c95565b612c35565b34801561060557600080fd5b506101e9610614366004613b86565b612df8565b34801561062557600080fd5b506102a561138881565b34801561063b57600080fd5b5061026061064a3660046139b9565b612e93565b34801561065b57600080fd5b506102a561066a3660046139b9565b6131ad565b34801561067b57600080fd5b5061021e61068a366004613c78565b613300565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cef565b91509150600061072f85611f52565b90508051600014801561076e575061271061138861074d8585613d29565b6107579190613d3c565b6107619190613d53565b61076b8442613d29565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d75565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d8b565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610801908b908b908b908b90600401613df4565b600060405180830381600087803b15801561081b57600080fd5b505af115801561082f573d6000803e3d6000fd5b50505050847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161086793929190613e48565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061089d5761089d613d75565b600091825260208220600590910201805490925082906108bf90600190613d29565b815481106108cf576108cf613d75565b60009182526020909120600d90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061091c5761091c613d75565b6000918252602082206005909102018054909250829061093e90600190613d29565b8154811061094e5761094e613d75565b60009182526020909120600d90910201600381015460ff16945090508361097957806001015461097c565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190613e8e565b50909350600492506109ff915050565b816004811115610a1157610a11613ef5565b03610a54576000610a2188611f52565b90508051600103610a525780600081518110610a3f57610a3f613d75565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0d9190613e8e565b50935050505080610b605760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd79190613f0b565b15610c155760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610c3957610c39613d75565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c6d57610c6d613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec9190613f26565b5050600087815260078401602052604090205490915060ff16610d36576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e7b565b808603610dab576000868152600683016020526040902054610d59576000610da4565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d9a9190613d3c565b610da49190613d53565b9450610e7b565b600081815260078301602052604090205460ff16610e7b5781600601600083600a01600181548110610ddf57610ddf613d75565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610e1557610e15613d75565b9060005260206000200154815260200190815260200160002054610e399190613f62565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e6e9190613d3c565b610e789190613d53565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610f15576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60026000610f2d61334c565b8054909150600160401b900460ff1680610f54575080546001600160401b03808416911610155b15610f715760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b60016000610fde61334c565b8054909150600160401b900460ff1680611005575080546001600160401b03808416911610155b156110225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b17815561104d8484613370565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b6000828152600360205260409020546002805484929081106110be576110be613d75565b600091825260209091206002600590920201015460ff16156110f25760405162461bcd60e51b81526004016107cf90613d8b565b60008381526003602052604081205460028054909190811061111657611116613d75565b90600052602060002090600502019050806001015483111561117a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb9190613cef565b915091508142101580156111fe57508042105b6112435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a89190613f26565b505090508681036112bd57612710915061133e565b6127106113886112cd8686613d29565b6112d79190613d3c565b6112e19190613d53565b6112eb8542613d29565b106113385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061135190600190613d29565b8154811061136157611361613d75565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156113c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e49190613f75565b6113ee9190613d29565b60008a815260078401602052604090205490915060ff16156114525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190613f75565b905060006127106114d18784613d3c565b6114db9190613d53565b6114e59083613f62565b60008c8152600686016020526040812054919250908211156115965760008c8152600686016020526040902054349061151e9084613d29565b116115435760008c815260068601602052604090205461153e9083613d29565b611545565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161158d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906115c2908490613f62565b909155505060008c8152600686016020526040812080548392906115e7908490613f62565b909155505060008c815260068601602052604090205482116116b95760008c815260068601602052604081205460098701805491929091611629908490613f62565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156118c4578285600901546116d69190613d29565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117489190613f0b565b156117615760028a01805460ff19166001179055611844565b895460038b016000611774876001613f62565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016117ef91815260200190565b602060405180830381865afa15801561180c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118309190613f75565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161189193929190613fc8565b6000604051808303818588803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b50505050505b803411156118f257336108fc6118da8334613d29565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61190a826133a6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061198857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661197c6000805160206144d68339815191525490565b6001600160a01b031614155b156119a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a00575060408051601f3d908101601f191682019092526119fd91810190613f75565b60015b611a2857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b6000805160206144d68339815191528114611a5957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144d68339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611b24576000836001600160a01b031683604051611ac09190614067565b600060405180830381855af49150503d8060008114611afb576040519150601f19603f3d011682016040523d82523d6000602084013e611b00565b606091505b5050905080611b22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611b745760405163703e46dd60e11b815260040160405180910390fd5b506000805160206144d683398151915290565b60028181548110611b9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611bca90613f8e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf690613f8e565b8015611c435780601f10611c1857610100808354040283529160200191611c43565b820191906000526020600020905b815481529060010190602001808311611c2657829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611c7157611c71613d75565b600091825260209091206002600590920201015460ff1615611ca55760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d139190613e8e565b5090935060019250611d23915050565b816004811115611d3557611d35613ef5565b14611d925760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82611dcf5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110611df357611df3613d75565b60009182526020822060059091020180549092508290611e1590600190613d29565b81548110611e2557611e25613d75565b90600052602060002090600d0201905060005b86811015611eeb573382898984818110611e5457611e54613d75565b9050602002013581548110611e6b57611e6b613d75565b60009182526020909120600490910201546001600160a01b031614611ea25760405162461bcd60e51b81526004016107cf90614083565b8582898984818110611eb657611eb6613d75565b9050602002013581548110611ecd57611ecd613d75565b60009182526020909120600160049092020181019190915501611e38565b5086869050816005016000828254611f039190613f62565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611f40908b908b908b906140ba565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611f7857611f78613d75565b60009182526020822060059091020180549092508290611f9a90600190613d29565b81548110611faa57611faa613d75565b90600052602060002090600d0201905080600a0180548060200260200160405190810160405280929190818152602001828054801561200857602002820191906000526020600020905b815481526020019060010190808311611ff4575b505050505092505050919050565b60008581526003602052604081205460028054839290811061203a5761203a613d75565b6000918252602080832089845260036005909302019182019052604082205481549193508391811061206e5761206e613d75565b90600052602060002090600d0201600001868154811061209057612090613d75565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156120ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121129190613f26565b506003850154919350915060ff168015612136575081836002015414806121365750805b156121495761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c8152602001908152602001600020548154811061218a5761218a613d75565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106121be576121be613d75565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061223557612235613d75565b6000918252602082206005909102018054909250829061225790600190613d29565b8154811061226757612267613d75565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e69190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612341573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236591906140de565b505050505091505060008161237b578354612381565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146123be5760405162461bcd60e51b81526004016107cf90614148565b6000836001600160a01b031683836040516123d99190614067565b60006040518083038185875af1925050503d8060008114612416576040519150601f19603f3d011682016040523d82523d6000602084013e61241b565b606091505b5050905080611b225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b60008681526003602052604090205460028054889290811061248457612484613d75565b600091825260209091206002600590920201015460ff16156124b85760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612502573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125269190613e8e565b5090935060029250612536915050565b81600481111561254857612548613ef5565b146125a35760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b856125e55760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b60008881526003602052604081205460028054909190811061260957612609613d75565b9060005260206000209060050201905080600101548611156126645760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b8054600090829061267790600190613d29565b8154811061268757612687613d75565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156126e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127069190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278591906140de565b5050505050915050600061279a8a8a8a610a5e565b905060005b8b8110156129e85733858e8e848181106127bb576127bb613d75565b90506020020135815481106127d2576127d2613d75565b60009182526020909120600490910201546001600160a01b0316146128095760405162461bcd60e51b81526004016107cf90614083565b821580612850575081858e8e8481811061282557612825613d75565b905060200201358154811061283c5761283c613d75565b906000526020600020906004020160010154145b6128d05760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d838181106128e3576128e3613d75565b90506020020135815481106128fa576128fa613d75565b600091825260209091206003600490920201015460ff16156129535760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e8481811061296757612967613d75565b905060200201358154811061297e5761297e613d75565b60009182526020909120600260049092020101556001858e8e848181106129a7576129a7613d75565b90506020020135815481106129be576129be613d75565b60009182526020909120600490910201600301805460ff191691151591909117905560010161279f565b508b8b9050846004016000828254612a009190613f62565b909155505060008a8152600285016020526040812080548d9290612a25908490613f62565b909155505060018401548a03612a5457600384015460ff1615612a4f5760038401805460ff191690555b612acd565b60018401546000908152600285016020526040808220548c835291205403612a9657600384015460ff16612a4f5760038401805460ff19166001179055612acd565b60018401546000908152600285016020526040808220548c83529120541115612acd57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612b0c9392919061418a565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612b4d5760405162461bcd60e51b81526004016107cf90614148565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612b9d57612b9d613d75565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612bd157612bd1613d75565b90600052602060002090600d02016000018781548110612bf357612bf3613d75565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612c5f5760405162461bcd60e51b81526004016107cf906141ba565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612cea85878361424e565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d659190613f75565b612d6f9190613d29565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610867908a908a908a90613e48565b600083815260036020526040812054600280548392908110612e1c57612e1c613d75565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612e5057612e50613d75565b90600052602060002090600d02016000018481548110612e7257612e72613d75565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ec05760405162461bcd60e51b81526004016107cf906141ba565b600083815260036020526040902054600280548592908110612ee457612ee4613d75565b600091825260209091206002600590920201015460ff1615612f185760405162461bcd60e51b81526004016107cf90613d8b565b600084815260036020526040812054600280549091908110612f3c57612f3c613d75565b60009182526020822060059091020180549092508290612f5e90600190613d29565b81548110612f6e57612f6e613d75565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff7919061430e565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306a9190613e8e565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156130ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f2919061430e565b96506130ff848a896133d3565b1561319c57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556131a1565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106131d1576131d1613d75565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061320557613205613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015613264573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132889190613f26565b50915091508260040154600014806132b75750801580156132b757506000828152600284016020526040902054155b156132c95760009450505050506132fa565b80156132de5750506004015491506132fa9050565b5060009081526002909101602052604090205491506132fa9050565b92915050565b6000546001600160a01b0316331461332a5760405162461bcd60e51b81526004016107cf90614148565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b61337861368f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146133d05760405162461bcd60e51b81526004016107cf90614148565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134459190613e8e565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156134a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c89190613f75565b6134d29190613d29565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613513573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261353b91908101906143be565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613597573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135bb919061430e565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613612573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613636919061449f565b50509150915082816136489190613f62565b60045490831015955060ff16156136845784801561368157506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b6136976136b6565b6136b457604051631afcd79f60e31b815260040160405180910390fd5b565b60006136c061334c565b54600160401b900460ff16919050565b6000602082840312156136e257600080fd5b5035919050565b60008083601f8401126136fb57600080fd5b5081356001600160401b0381111561371257600080fd5b6020830191508360208260051b850101111561372d57600080fd5b9250929050565b60008083601f84011261374657600080fd5b5081356001600160401b0381111561375d57600080fd5b60208301915083602082850101111561372d57600080fd5b600080600080600080600060a0888a03121561379057600080fd5b8735965060208801356001600160401b03808211156137ae57600080fd5b6137ba8b838c016136e9565b909850965060408a0135955060608a0135945060808a01359150808211156137e157600080fd5b506137ee8a828b01613734565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561383a5761383a613801565b60405290565b604051601f8201601f191681016001600160401b038111828210171561386857613868613801565b604052919050565b600082601f83011261388157600080fd5b81356001600160401b0381111561389a5761389a613801565b6138ad601f8201601f1916602001613840565b8181528460208386010111156138c257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138f457600080fd5b833592506020840135915060408401356001600160401b0381111561391857600080fd5b61392486828701613870565b9150509250925092565b6001600160a01b03811681146133d057600080fd5b6000806000806080858703121561395957600080fd5b84359350602085013561396b8161392e565b93969395505050506040820135916060013590565b6000806040838503121561399357600080fd5b823561399e8161392e565b915060208301356139ae8161392e565b809150509250929050565b600080604083850312156139cc57600080fd5b50508035926020909101359150565b600080604083850312156139ee57600080fd5b82356139f98161392e565b915060208301356001600160401b03811115613a1457600080fd5b613a2085828601613870565b9150509250929050565b60005b83811015613a45578181015183820152602001613a2d565b50506000910152565b60008151808452613a66816020860160208601613a2a565b601f01601f19169290920160200192915050565b602081526000613a8d6020830184613a4e565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a4e565b60008060008060608587031215613acb57600080fd5b8435935060208501356001600160401b03811115613ae857600080fd5b613af4878288016136e9565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b3f57835183529284019291840191600101613b23565b50909695505050505050565b600080600080600060a08688031215613b6357600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b9b57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613bc757600080fd5b8335613bd28161392e565b92506020840135915060408401356001600160401b0381111561391857600080fd5b60008060008060008060a08789031215613c0d57600080fd5b8635955060208701356001600160401b0380821115613c2b57600080fd5b613c378a838b016136e9565b909750955060408901359450606089013593506080890135915080821115613c5e57600080fd5b50613c6b89828a01613870565b9150509295509295509295565b600060208284031215613c8a57600080fd5b8135613a8d8161392e565b600080600080600060808688031215613cad57600080fd5b853594506020860135935060408601356001600160401b03811115613cd157600080fd5b613cdd88828901613734565b96999598509660600135949350505050565b60008060408385031215613d0257600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b818103818111156132fa576132fa613d13565b80820281158282048414176132fa576132fa613d13565b600082613d7057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613ddb57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613e0e606083018587613dc2565b905082604083015295945050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613e1f565b80516001600160601b0381168114613e7957600080fd5b919050565b80518015158114613e7957600080fd5b600080600080600060a08688031215613ea657600080fd5b613eaf86613e62565b94506020860151613ebf8161392e565b604087015190945060058110613ed457600080fd5b9250613ee260608701613e7e565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613f1d57600080fd5b613a8d82613e7e565b600080600060608486031215613f3b57600080fd5b83519250613f4b60208501613e7e565b9150613f5960408501613e7e565b90509250925092565b808201808211156132fa576132fa613d13565b600060208284031215613f8757600080fd5b5051919050565b600181811c90821680613fa257607f821691505b602082108103613fc257634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613fe981613f8e565b806060870152608060018084166000811461400b576001811461402757614057565b60ff19851660808a0152608084151560051b8a01019550614057565b89600052602060002060005b8581101561404e5781548b8201860152908301908801614033565b8a016080019650505b50939a9950505050505050505050565b60008251614079818460208701613a2a565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6040815260006140ce604083018587613dc2565b9050826020830152949350505050565b600080600080600080600060e0888a0312156140f957600080fd5b61410288613e62565b965061411060208901613e7e565b955060408801519450606088015193506080880151925060a0880151915061413a60c08901613e7e565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60408152600061419e604083018587613dc2565b82810360208401526141b08185613a4e565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611b24576000816000526020600020601f850160051c810160208610156142275750805b601f850160051c820191505b8181101561424657828155600101614233565b505050505050565b6001600160401b0383111561426557614265613801565b614279836142738354613f8e565b836141fe565b6000601f8411600181146142ad57600085156142955750838201355b600019600387901b1c1916600186901b178355614307565b600083815260209020601f19861690835b828110156142de57868501358255602094850194600190920191016142be565b50868210156142fb5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561432057600080fd5b8151613a8d8161392e565b600082601f83011261433c57600080fd5b815160206001600160401b0382111561435757614357613801565b8160051b614366828201613840565b928352848101820192828101908785111561438057600080fd5b83870192505b848310156143a85782516143998161392e565b82529183019190830190614386565b979650505050505050565b8051613e798161392e565b6000602082840312156143d057600080fd5b81516001600160401b03808211156143e757600080fd5b9083019061016082860312156143fc57600080fd5b614404613817565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561444c57600080fd5b6144588782860161432b565b60c08301525060e08381015190820152610100808401519082015261012091506144838284016143b3565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156144b557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212202ec8f9386176b2ca726899fd0a6a21acb3ebb48958caaa7e6fab6be5a1dfa56f64736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106101c45760003560e01c806365540b96116100f8578063b34bfaa811610090578063b34bfaa8146105c3578063b6ede540146105d9578063ba66fde7146105f9578063be46760414610619578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad3014610521578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b806365540b9614610447578063675926f61461047457806369f3f041146104945780636d4cd8ea146104e1578063751accd014610501578063796490f9146105215780637c04034e146105375780638e42646014610557578063a7cc08fe1461057757600080fd5b8063362c34791161016b578063362c34791461032a578063472abf681461034a578063485cc9551461035f5780634b2f0ea01461037f5780634f1ef2861461039257806352d1902d146103a557806354fd4d50146103ba578063564a565d146103f85780635c92e2f61461042757600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136d0565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613775565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136d0565b610879565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136d0565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136d0565b6108f0565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138df565b610a5e565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613943565b610a9b565b34801561035657600080fd5b5061021e610f21565b34801561036b57600080fd5b5061021e61037a366004613980565b610fd2565b61021e61038d3660046139b9565b61109a565b61021e6103a03660046139db565b611901565b3480156103b157600080fd5b506102a5611b29565b3480156103c657600080fd5b506103eb60405180604001604052806005815260200164302e392e3160d81b81525081565b6040516101f59190613a7a565b34801561040457600080fd5b506104186104133660046136d0565b611b87565b6040516101f593929190613a94565b34801561043357600080fd5b5061021e610442366004613ab5565b611c4d565b34801561045357600080fd5b506104676104623660046136d0565b611f52565b6040516101f59190613b07565b34801561048057600080fd5b506102a561048f366004613b4b565b612016565b3480156104a057600080fd5b506104b46104af366004613b86565b612159565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104ed57600080fd5b506101e96104fc3660046136d0565b612211565b34801561050d57600080fd5b5061021e61051c366004613bb2565b612394565b34801561052d57600080fd5b506102a561271081565b34801561054357600080fd5b5061021e610552366004613bf4565b612460565b34801561056357600080fd5b5061021e610572366004613c78565b612b23565b34801561058357600080fd5b50610597610592366004613b86565b612b6f565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105cf57600080fd5b506102a5614e2081565b3480156105e557600080fd5b5061021e6105f4366004613c95565b612c35565b34801561060557600080fd5b506101e9610614366004613b86565b612df8565b34801561062557600080fd5b506102a561138881565b34801561063b57600080fd5b5061026061064a3660046139b9565b612e93565b34801561065b57600080fd5b506102a561066a3660046139b9565b6131ad565b34801561067b57600080fd5b5061021e61068a366004613c78565b613300565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cef565b91509150600061072f85611f52565b90508051600014801561076e575061271061138861074d8585613d29565b6107579190613d3c565b6107619190613d53565b61076b8442613d29565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d75565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d8b565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610801908b908b908b908b90600401613df4565b600060405180830381600087803b15801561081b57600080fd5b505af115801561082f573d6000803e3d6000fd5b50505050847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161086793929190613e48565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061089d5761089d613d75565b600091825260208220600590910201805490925082906108bf90600190613d29565b815481106108cf576108cf613d75565b60009182526020909120600d90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061091c5761091c613d75565b6000918252602082206005909102018054909250829061093e90600190613d29565b8154811061094e5761094e613d75565b60009182526020909120600d90910201600381015460ff16945090508361097957806001015461097c565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190613e8e565b50909350600492506109ff915050565b816004811115610a1157610a11613ef5565b03610a54576000610a2188611f52565b90508051600103610a525780600081518110610a3f57610a3f613d75565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0d9190613e8e565b50935050505080610b605760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd79190613f0b565b15610c155760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610c3957610c39613d75565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c6d57610c6d613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec9190613f26565b5050600087815260078401602052604090205490915060ff16610d36576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e7b565b808603610dab576000868152600683016020526040902054610d59576000610da4565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d9a9190613d3c565b610da49190613d53565b9450610e7b565b600081815260078301602052604090205460ff16610e7b5781600601600083600a01600181548110610ddf57610ddf613d75565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610e1557610e15613d75565b9060005260206000200154815260200190815260200160002054610e399190613f62565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e6e9190613d3c565b610e789190613d53565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610f15576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60026000610f2d61334c565b8054909150600160401b900460ff1680610f54575080546001600160401b03808416911610155b15610f715760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b60016000610fde61334c565b8054909150600160401b900460ff1680611005575080546001600160401b03808416911610155b156110225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b17815561104d8484613370565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b6000828152600360205260409020546002805484929081106110be576110be613d75565b600091825260209091206002600590920201015460ff16156110f25760405162461bcd60e51b81526004016107cf90613d8b565b60008381526003602052604081205460028054909190811061111657611116613d75565b90600052602060002090600502019050806001015483111561117a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb9190613cef565b915091508142101580156111fe57508042105b6112435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a89190613f26565b505090508681036112bd57612710915061133e565b6127106113886112cd8686613d29565b6112d79190613d3c565b6112e19190613d53565b6112eb8542613d29565b106113385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061135190600190613d29565b8154811061136157611361613d75565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156113c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e49190613f75565b6113ee9190613d29565b60008a815260078401602052604090205490915060ff16156114525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190613f75565b905060006127106114d18784613d3c565b6114db9190613d53565b6114e59083613f62565b60008c8152600686016020526040812054919250908211156115965760008c8152600686016020526040902054349061151e9084613d29565b116115435760008c815260068601602052604090205461153e9083613d29565b611545565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161158d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906115c2908490613f62565b909155505060008c8152600686016020526040812080548392906115e7908490613f62565b909155505060008c815260068601602052604090205482116116b95760008c815260068601602052604081205460098701805491929091611629908490613f62565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156118c4578285600901546116d69190613d29565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117489190613f0b565b156117615760028a01805460ff19166001179055611844565b895460038b016000611774876001613f62565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016117ef91815260200190565b602060405180830381865afa15801561180c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118309190613f75565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161189193929190613fc8565b6000604051808303818588803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b50505050505b803411156118f257336108fc6118da8334613d29565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61190a826133a6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061198857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661197c6000805160206144d68339815191525490565b6001600160a01b031614155b156119a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a00575060408051601f3d908101601f191682019092526119fd91810190613f75565b60015b611a2857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b6000805160206144d68339815191528114611a5957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144d68339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611b24576000836001600160a01b031683604051611ac09190614067565b600060405180830381855af49150503d8060008114611afb576040519150601f19603f3d011682016040523d82523d6000602084013e611b00565b606091505b5050905080611b22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611b745760405163703e46dd60e11b815260040160405180910390fd5b506000805160206144d683398151915290565b60028181548110611b9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611bca90613f8e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf690613f8e565b8015611c435780601f10611c1857610100808354040283529160200191611c43565b820191906000526020600020905b815481529060010190602001808311611c2657829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611c7157611c71613d75565b600091825260209091206002600590920201015460ff1615611ca55760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d139190613e8e565b5090935060019250611d23915050565b816004811115611d3557611d35613ef5565b14611d925760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82611dcf5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110611df357611df3613d75565b60009182526020822060059091020180549092508290611e1590600190613d29565b81548110611e2557611e25613d75565b90600052602060002090600d0201905060005b86811015611eeb573382898984818110611e5457611e54613d75565b9050602002013581548110611e6b57611e6b613d75565b60009182526020909120600490910201546001600160a01b031614611ea25760405162461bcd60e51b81526004016107cf90614083565b8582898984818110611eb657611eb6613d75565b9050602002013581548110611ecd57611ecd613d75565b60009182526020909120600160049092020181019190915501611e38565b5086869050816005016000828254611f039190613f62565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611f40908b908b908b906140ba565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611f7857611f78613d75565b60009182526020822060059091020180549092508290611f9a90600190613d29565b81548110611faa57611faa613d75565b90600052602060002090600d0201905080600a0180548060200260200160405190810160405280929190818152602001828054801561200857602002820191906000526020600020905b815481526020019060010190808311611ff4575b505050505092505050919050565b60008581526003602052604081205460028054839290811061203a5761203a613d75565b6000918252602080832089845260036005909302019182019052604082205481549193508391811061206e5761206e613d75565b90600052602060002090600d0201600001868154811061209057612090613d75565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156120ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121129190613f26565b506003850154919350915060ff168015612136575081836002015414806121365750805b156121495761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c8152602001908152602001600020548154811061218a5761218a613d75565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106121be576121be613d75565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061223557612235613d75565b6000918252602082206005909102018054909250829061225790600190613d29565b8154811061226757612267613d75565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e69190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612341573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236591906140de565b505050505091505060008161237b578354612381565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146123be5760405162461bcd60e51b81526004016107cf90614148565b6000836001600160a01b031683836040516123d99190614067565b60006040518083038185875af1925050503d8060008114612416576040519150601f19603f3d011682016040523d82523d6000602084013e61241b565b606091505b5050905080611b225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b60008681526003602052604090205460028054889290811061248457612484613d75565b600091825260209091206002600590920201015460ff16156124b85760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612502573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125269190613e8e565b5090935060029250612536915050565b81600481111561254857612548613ef5565b146125a35760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b856125e55760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b60008881526003602052604081205460028054909190811061260957612609613d75565b9060005260206000209060050201905080600101548611156126645760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b8054600090829061267790600190613d29565b8154811061268757612687613d75565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156126e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127069190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278591906140de565b5050505050915050600061279a8a8a8a610a5e565b905060005b8b8110156129e85733858e8e848181106127bb576127bb613d75565b90506020020135815481106127d2576127d2613d75565b60009182526020909120600490910201546001600160a01b0316146128095760405162461bcd60e51b81526004016107cf90614083565b821580612850575081858e8e8481811061282557612825613d75565b905060200201358154811061283c5761283c613d75565b906000526020600020906004020160010154145b6128d05760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d838181106128e3576128e3613d75565b90506020020135815481106128fa576128fa613d75565b600091825260209091206003600490920201015460ff16156129535760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e8481811061296757612967613d75565b905060200201358154811061297e5761297e613d75565b60009182526020909120600260049092020101556001858e8e848181106129a7576129a7613d75565b90506020020135815481106129be576129be613d75565b60009182526020909120600490910201600301805460ff191691151591909117905560010161279f565b508b8b9050846004016000828254612a009190613f62565b909155505060008a8152600285016020526040812080548d9290612a25908490613f62565b909155505060018401548a03612a5457600384015460ff1615612a4f5760038401805460ff191690555b612acd565b60018401546000908152600285016020526040808220548c835291205403612a9657600384015460ff16612a4f5760038401805460ff19166001179055612acd565b60018401546000908152600285016020526040808220548c83529120541115612acd57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612b0c9392919061418a565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612b4d5760405162461bcd60e51b81526004016107cf90614148565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612b9d57612b9d613d75565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612bd157612bd1613d75565b90600052602060002090600d02016000018781548110612bf357612bf3613d75565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612c5f5760405162461bcd60e51b81526004016107cf906141ba565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612cea85878361424e565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d659190613f75565b612d6f9190613d29565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610867908a908a908a90613e48565b600083815260036020526040812054600280548392908110612e1c57612e1c613d75565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612e5057612e50613d75565b90600052602060002090600d02016000018481548110612e7257612e72613d75565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ec05760405162461bcd60e51b81526004016107cf906141ba565b600083815260036020526040902054600280548592908110612ee457612ee4613d75565b600091825260209091206002600590920201015460ff1615612f185760405162461bcd60e51b81526004016107cf90613d8b565b600084815260036020526040812054600280549091908110612f3c57612f3c613d75565b60009182526020822060059091020180549092508290612f5e90600190613d29565b81548110612f6e57612f6e613d75565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff7919061430e565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306a9190613e8e565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156130ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f2919061430e565b96506130ff848a896133d3565b1561319c57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556131a1565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106131d1576131d1613d75565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061320557613205613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015613264573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132889190613f26565b50915091508260040154600014806132b75750801580156132b757506000828152600284016020526040902054155b156132c95760009450505050506132fa565b80156132de5750506004015491506132fa9050565b5060009081526002909101602052604090205491506132fa9050565b92915050565b6000546001600160a01b0316331461332a5760405162461bcd60e51b81526004016107cf90614148565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b61337861368f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146133d05760405162461bcd60e51b81526004016107cf90614148565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134459190613e8e565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156134a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c89190613f75565b6134d29190613d29565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613513573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261353b91908101906143be565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613597573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135bb919061430e565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613612573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613636919061449f565b50509150915082816136489190613f62565b60045490831015955060ff16156136845784801561368157506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b6136976136b6565b6136b457604051631afcd79f60e31b815260040160405180910390fd5b565b60006136c061334c565b54600160401b900460ff16919050565b6000602082840312156136e257600080fd5b5035919050565b60008083601f8401126136fb57600080fd5b5081356001600160401b0381111561371257600080fd5b6020830191508360208260051b850101111561372d57600080fd5b9250929050565b60008083601f84011261374657600080fd5b5081356001600160401b0381111561375d57600080fd5b60208301915083602082850101111561372d57600080fd5b600080600080600080600060a0888a03121561379057600080fd5b8735965060208801356001600160401b03808211156137ae57600080fd5b6137ba8b838c016136e9565b909850965060408a0135955060608a0135945060808a01359150808211156137e157600080fd5b506137ee8a828b01613734565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561383a5761383a613801565b60405290565b604051601f8201601f191681016001600160401b038111828210171561386857613868613801565b604052919050565b600082601f83011261388157600080fd5b81356001600160401b0381111561389a5761389a613801565b6138ad601f8201601f1916602001613840565b8181528460208386010111156138c257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138f457600080fd5b833592506020840135915060408401356001600160401b0381111561391857600080fd5b61392486828701613870565b9150509250925092565b6001600160a01b03811681146133d057600080fd5b6000806000806080858703121561395957600080fd5b84359350602085013561396b8161392e565b93969395505050506040820135916060013590565b6000806040838503121561399357600080fd5b823561399e8161392e565b915060208301356139ae8161392e565b809150509250929050565b600080604083850312156139cc57600080fd5b50508035926020909101359150565b600080604083850312156139ee57600080fd5b82356139f98161392e565b915060208301356001600160401b03811115613a1457600080fd5b613a2085828601613870565b9150509250929050565b60005b83811015613a45578181015183820152602001613a2d565b50506000910152565b60008151808452613a66816020860160208601613a2a565b601f01601f19169290920160200192915050565b602081526000613a8d6020830184613a4e565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a4e565b60008060008060608587031215613acb57600080fd5b8435935060208501356001600160401b03811115613ae857600080fd5b613af4878288016136e9565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b3f57835183529284019291840191600101613b23565b50909695505050505050565b600080600080600060a08688031215613b6357600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b9b57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613bc757600080fd5b8335613bd28161392e565b92506020840135915060408401356001600160401b0381111561391857600080fd5b60008060008060008060a08789031215613c0d57600080fd5b8635955060208701356001600160401b0380821115613c2b57600080fd5b613c378a838b016136e9565b909750955060408901359450606089013593506080890135915080821115613c5e57600080fd5b50613c6b89828a01613870565b9150509295509295509295565b600060208284031215613c8a57600080fd5b8135613a8d8161392e565b600080600080600060808688031215613cad57600080fd5b853594506020860135935060408601356001600160401b03811115613cd157600080fd5b613cdd88828901613734565b96999598509660600135949350505050565b60008060408385031215613d0257600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b818103818111156132fa576132fa613d13565b80820281158282048414176132fa576132fa613d13565b600082613d7057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613ddb57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613e0e606083018587613dc2565b905082604083015295945050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613e1f565b80516001600160601b0381168114613e7957600080fd5b919050565b80518015158114613e7957600080fd5b600080600080600060a08688031215613ea657600080fd5b613eaf86613e62565b94506020860151613ebf8161392e565b604087015190945060058110613ed457600080fd5b9250613ee260608701613e7e565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613f1d57600080fd5b613a8d82613e7e565b600080600060608486031215613f3b57600080fd5b83519250613f4b60208501613e7e565b9150613f5960408501613e7e565b90509250925092565b808201808211156132fa576132fa613d13565b600060208284031215613f8757600080fd5b5051919050565b600181811c90821680613fa257607f821691505b602082108103613fc257634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613fe981613f8e565b806060870152608060018084166000811461400b576001811461402757614057565b60ff19851660808a0152608084151560051b8a01019550614057565b89600052602060002060005b8581101561404e5781548b8201860152908301908801614033565b8a016080019650505b50939a9950505050505050505050565b60008251614079818460208701613a2a565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6040815260006140ce604083018587613dc2565b9050826020830152949350505050565b600080600080600080600060e0888a0312156140f957600080fd5b61410288613e62565b965061411060208901613e7e565b955060408801519450606088015193506080880151925060a0880151915061413a60c08901613e7e565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60408152600061419e604083018587613dc2565b82810360208401526141b08185613a4e565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611b24576000816000526020600020601f850160051c810160208610156142275750805b601f850160051c820191505b8181101561424657828155600101614233565b505050505050565b6001600160401b0383111561426557614265613801565b614279836142738354613f8e565b836141fe565b6000601f8411600181146142ad57600085156142955750838201355b600019600387901b1c1916600186901b178355614307565b600083815260209020601f19861690835b828110156142de57868501358255602094850194600190920191016142be565b50868210156142fb5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561432057600080fd5b8151613a8d8161392e565b600082601f83011261433c57600080fd5b815160206001600160401b0382111561435757614357613801565b8160051b614366828201613840565b928352848101820192828101908785111561438057600080fd5b83870192505b848310156143a85782516143998161392e565b82529183019190830190614386565b979650505050505050565b8051613e798161392e565b6000602082840312156143d057600080fd5b81516001600160401b03808211156143e757600080fd5b9083019061016082860312156143fc57600080fd5b614404613817565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561444c57600080fd5b6144588782860161432b565b60c08301525060e08381015190820152610100808401519082015261012091506144838284016143b3565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156144b557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212202ec8f9386176b2ca726899fd0a6a21acb3ebb48958caaa7e6fab6be5a1dfa56f64736f6c63430008180033", "devdoc": { "errors": { "AlreadyInitialized()": [ @@ -1129,10 +1147,11 @@ "_voteIDs": "The identifiers of the votes in the dispute." } }, - "CommitCastShutter(bytes32,bytes32)": { + "CommitCastShutter(bytes32,bytes32,bytes)": { "details": "Emitted when a vote is cast.", "params": { "_commit": "The commitment hash.", + "_encryptedVote": "The Shutter encrypted vote.", "_identity": "The Shutter identity used for encryption." } }, @@ -1212,11 +1231,12 @@ "_voteIDs": "The IDs of the votes." } }, - "castCommitShutter(uint256,uint256[],bytes32,bytes32)": { + "castCommitShutter(uint256,uint256[],bytes32,bytes32,bytes)": { "details": "Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.", "params": { "_commit": "The commitment hash including the justification.", "_coreDisputeID": "The ID of the dispute in Kleros Core.", + "_encryptedVote": "The Shutter encrypted vote.", "_identity": "The Shutter identity used for encryption.", "_voteIDs": "The IDs of the votes." } diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol index 2f2a292c4..844e85614 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol @@ -12,7 +12,7 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol"; /// - an appeal system: fund 2 choices only, vote on any choice. /// Added functionality: an Shutter-specific event emitted when a vote is cast. contract DisputeKitShutter is DisputeKitClassicBase { - string public constant override version = "0.9.0"; + string public constant override version = "0.9.1"; // ************************************* // // * Events * // @@ -21,7 +21,8 @@ contract DisputeKitShutter is DisputeKitClassicBase { /// @dev Emitted when a vote is cast. /// @param _commit The commitment hash. /// @param _identity The Shutter identity used for encryption. - event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity); + /// @param _encryptedVote The Shutter encrypted vote. + event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity, bytes _encryptedVote); // ************************************* // // * Constructor * // @@ -39,6 +40,10 @@ contract DisputeKitShutter is DisputeKitClassicBase { __DisputeKitClassicBase_initialize(_governor, _core); } + function initialize2() external reinitializer(2) { + // NOP + } + // ************************ // // * Governance * // // ************************ // @@ -61,14 +66,16 @@ contract DisputeKitShutter is DisputeKitClassicBase { /// @param _voteIDs The IDs of the votes. /// @param _commit The commitment hash including the justification. /// @param _identity The Shutter identity used for encryption. + /// @param _encryptedVote The Shutter encrypted vote. function castCommitShutter( uint256 _coreDisputeID, uint256[] calldata _voteIDs, bytes32 _commit, - bytes32 _identity + bytes32 _identity, + bytes calldata _encryptedVote ) external notJumped(_coreDisputeID) { this.castCommit(_coreDisputeID, _voteIDs, _commit); - emit CommitCastShutter(_commit, _identity); + emit CommitCastShutter(_commit, _identity, _encryptedVote); } // ************************************* // From b40abc28271de8e3fdce54921e7cfe3a3d3c1559 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 1 May 2025 00:41:07 +0100 Subject: [PATCH 15/26] chore: upgraded DisputeKitClassic --- contracts/README.md | 2 +- ...0.8.0.ts => upgrade-dispute-kit-v0.9.0.ts} | 2 +- .../DisputeKitClassic.json | 69 ++++-- .../DisputeKitClassic_Implementation.json | 198 ++++++++++++------ .../dispute-kits/DisputeKitClassic.sol | 2 +- 5 files changed, 193 insertions(+), 80 deletions(-) rename contracts/deploy/{upgrade-dispute-kit-v0.8.0.ts => upgrade-dispute-kit-v0.9.0.ts} (98%) diff --git a/contracts/README.md b/contracts/README.md index ea2576e4d..56751df04 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -77,7 +77,7 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [ChainlinkRNG](https://sepolia.arbiscan.io/address/0x6c40D7F5d5bE3492fe9EF70e4eCb2BD773c12AF8) - [DAI](https://sepolia.arbiscan.io/address/0x593e89704D285B0c3fbF157c7CF2537456CE64b5) - [DAIFaucet](https://sepolia.arbiscan.io/address/0xB5b39A1bcD2D7097A8824B3cC18Ebd2dFb0D9B5E) -- [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x2246821E1313A93e2F8CdF7a3422d078f560b457), [implementation](https://sepolia.arbiscan.io/address/0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24) +- [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x2246821E1313A93e2F8CdF7a3422d078f560b457), [implementation](https://sepolia.arbiscan.io/address/0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F) - [DisputeKitClassicUniversity: proxy](https://sepolia.arbiscan.io/address/0xd6E96b7c993763B5CDDa1139C7387B82A7c8B8B5), [implementation](https://sepolia.arbiscan.io/address/0x87e863b94d2CB79A8aB53bD87Dc4A10E11C0918B) - [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1) - [DisputeResolver](https://sepolia.arbiscan.io/address/0x524C5541f440204E0B4577334c439277018F971f) diff --git a/contracts/deploy/upgrade-dispute-kit-v0.8.0.ts b/contracts/deploy/upgrade-dispute-kit-v0.9.0.ts similarity index 98% rename from contracts/deploy/upgrade-dispute-kit-v0.8.0.ts rename to contracts/deploy/upgrade-dispute-kit-v0.9.0.ts index fcfc1035e..4d1f8c690 100644 --- a/contracts/deploy/upgrade-dispute-kit-v0.8.0.ts +++ b/contracts/deploy/upgrade-dispute-kit-v0.9.0.ts @@ -33,7 +33,7 @@ const deployUpgradeDisputeKit: DeployFunction = async (hre: HardhatRuntimeEnviro print.info(`Upgrading ${contractName}...`); await deployUpgradable(deployments, contractName, { contract: contractName, - initializer: "initialize2", + initializer: "initialize3", from: deployer, // Warning: do not reinitialize everything, only the new variables args: [], diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json index 3f5f41e1a..afdca97a7 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json @@ -817,6 +817,35 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "hashVote", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { @@ -837,11 +866,30 @@ }, { "inputs": [], - "name": "initialize2", + "name": "initialize3", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "isAppealFunded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1012,19 +1060,16 @@ "0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24", "0x485cc955000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c590000000000000000000000000000000000000000000000000000000000000000" ], - "numDeployments": 1, - "solcInputHash": "c66a072bc17d18807b6e81f338ff0fab", - "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitClassicProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x8edb830825d7fe8ef85d445b087fac3b41f626cd7d5b40ea583c3cba21528687\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122094a1c38a583896452ce447160bc2955480b6ba6592457d7be641c34e4339d47264736f6c63430008180033", - "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122094a1c38a583896452ce447160bc2955480b6ba6592457d7be641c34e4339d47264736f6c63430008180033", + "numDeployments": 2, + "solcInputHash": "96b8e3f55478438b6784f67c1730309e", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitClassicProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitShutterProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x209228b56d42a8444ca70919e1ded5711fba434a746f26d426e230f57526fc6c\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122031995e44df4f8c0f7e14fc8c92fe3e63c4fcc994a0505b92eecf1c3a7b742d8964736f6c63430008180033", + "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122031995e44df4f8c0f7e14fc8c92fe3e63c4fcc994a0505b92eecf1c3a7b742d8964736f6c63430008180033", "execute": { - "methodName": "initialize", - "args": [ - "0xf1C7c037891525E360C59f708739Ac09A7670c59", - "0x0000000000000000000000000000000000000000" - ] + "methodName": "initialize3", + "args": [] }, - "implementation": "0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24", + "implementation": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", "devdoc": { "kind": "dev", "methods": {}, diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json index 9c5cb24b1..c2fe8da64 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24", + "address": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", "abi": [ { "inputs": [], @@ -814,6 +814,35 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "hashVote", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [ { @@ -834,11 +863,30 @@ }, { "inputs": [], - "name": "initialize2", + "name": "initialize3", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + } + ], + "name": "isAppealFunded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -960,41 +1008,41 @@ "type": "function" } ], - "transactionHash": "0xe45fa05818d355ae6ad89738239de573ebf34a442c9873df404dc551ce604e90", + "transactionHash": "0x872759bf7163de8e17b5902b8d4eac663bad5c2382ce1fe2e0b50b2253edc8e6", "receipt": { "to": null, "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", - "contractAddress": "0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24", - "transactionIndex": 4, - "gasUsed": "3660965", - "logsBloom": "0x00000000000020000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7f693b63edf7f862dfb3edb3d02a7d358160f298fc28d41d55c34ae5b1376cf3", - "transactionHash": "0xe45fa05818d355ae6ad89738239de573ebf34a442c9873df404dc551ce604e90", + "contractAddress": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", + "transactionIndex": 1, + "gasUsed": "3987213", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000020000000000000000000000000000000004000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xfc72feaadd04b77c141f55e20764b997e1151bce222a8ab03093a06d74fd06c4", + "transactionHash": "0x872759bf7163de8e17b5902b8d4eac663bad5c2382ce1fe2e0b50b2253edc8e6", "logs": [ { - "transactionIndex": 4, - "blockNumber": 141215186, - "transactionHash": "0xe45fa05818d355ae6ad89738239de573ebf34a442c9873df404dc551ce604e90", - "address": "0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24", + "transactionIndex": 1, + "blockNumber": 148207322, + "transactionHash": "0x872759bf7163de8e17b5902b8d4eac663bad5c2382ce1fe2e0b50b2253edc8e6", + "address": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", "topics": [ "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" ], "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", - "logIndex": 5, - "blockHash": "0x7f693b63edf7f862dfb3edb3d02a7d358160f298fc28d41d55c34ae5b1376cf3" + "logIndex": 0, + "blockHash": "0xfc72feaadd04b77c141f55e20764b997e1151bce222a8ab03093a06d74fd06c4" } ], - "blockNumber": 141215186, - "cumulativeGasUsed": "4325610", + "blockNumber": 148207322, + "cumulativeGasUsed": "3987213", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "c66a072bc17d18807b6e81f338ff0fab", - "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commit. Note that justification string is a part of the commit.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitClassic Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":\"DisputeKitClassic\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibeInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibeInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xa96404e3fe4eb072d50b36dca51f8073f992fa25ae59307a1f20f2d5c6855dea\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitClassic\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\ncontract DisputeKitClassic is DisputeKitClassicBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize2() external reinitializer(2) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0xa3633f78ef652659c2ef88fd20a5565e4d0148e20a61c4ccca9e37204df7dadf\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commit. Note that justification string is a part of the commit.\\n function castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == keccak256(abi.encodePacked(_choice, _salt)),\\n \\\"The commit must match the choice in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalVoted == round.votes.length;\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0x243af54007e2a208797bb56f6b576f68bdb5c0b932cd6df22375d646491318e1\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xc36f008d867157da6317ba4c685e791033b18074c27bb35f691bf3eebe65deca\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6080516140c96200010360003960008181611692015281816116bb01526118b301526140c96000f3fe6080604052600436106101a35760003560e01c806369f3f041116100e2578063b6ede54011610085578063b6ede54014610558578063ba66fde714610578578063be46760414610598578063d2b8035a146105ae578063da3beb8c146105ce578063e349ad30146104a0578063e4c0aaf4146105ee578063f2f4eb261461060e57600080fd5b806369f3f041146104135780636d4cd8ea14610460578063751accd014610480578063796490f9146104a05780637c04034e146104b65780638e426460146104d6578063a7cc08fe146104f6578063b34bfaa81461054257600080fd5b80634b2f0ea01161014a5780634b2f0ea0146102fe5780634f1ef2861461031157806352d1902d1461032457806354fd4d5014610339578063564a565d146103775780635c92e2f6146103a657806365540b96146103c6578063675926f6146103f357600080fd5b80630baa64d1146101a85780630c340a24146101dd5780631200aabc146102155780631c3db16d146102505780632621b9a21461028d578063362c3479146102a7578063472abf68146102c7578063485cc955146102de575b600080fd5b3480156101b457600080fd5b506101c86101c3366004613363565b61062e565b60405190151581526020015b60405180910390f35b3480156101e957600080fd5b506000546101fd906001600160a01b031681565b6040516001600160a01b0390911681526020016101d4565b34801561022157600080fd5b50610242610230366004613363565b60036020526000908152604090205481565b6040519081526020016101d4565b34801561025c57600080fd5b5061027061026b366004613363565b6106a5565b6040805193845291151560208401521515908201526060016101d4565b34801561029957600080fd5b506004546101c89060ff1681565b3480156102b357600080fd5b506102426102c2366004613391565b610813565b3480156102d357600080fd5b506102dc610c9e565b005b3480156102ea57600080fd5b506102dc6102f93660046133ce565b610d4f565b6102dc61030c366004613407565b610e17565b6102dc61031f366004613516565b61167e565b34801561033057600080fd5b506102426118a6565b34801561034557600080fd5b5061036a604051806040016040528060058152602001640302e382e360dc1b81525081565b6040516101d491906135b5565b34801561038357600080fd5b50610397610392366004613363565b611904565b6040516101d4939291906135c8565b3480156103b257600080fd5b506102dc6103c1366004613634565b6119ca565b3480156103d257600080fd5b506103e66103e1366004613363565b611ccf565b6040516101d49190613686565b3480156103ff57600080fd5b5061024261040e3660046136ca565b611d93565b34801561041f57600080fd5b5061043361042e366004613705565b611ed8565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101d4565b34801561046c57600080fd5b506101c861047b366004613363565b611f90565b34801561048c57600080fd5b506102dc61049b366004613731565b612007565b3480156104ac57600080fd5b5061024261271081565b3480156104c257600080fd5b506102dc6104d1366004613789565b6120d3565b3480156104e257600080fd5b506102dc6104f1366004613821565b6127a4565b34801561050257600080fd5b50610516610511366004613705565b6127f0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101d4565b34801561054e57600080fd5b50610242614e2081565b34801561056457600080fd5b506102dc61057336600461383e565b6128b6565b34801561058457600080fd5b506101c8610593366004613705565b612a8b565b3480156105a457600080fd5b5061024261138881565b3480156105ba57600080fd5b506101fd6105c9366004613407565b612b26565b3480156105da57600080fd5b506102426105e9366004613407565b612e40565b3480156105fa57600080fd5b506102dc610609366004613821565b612f93565b34801561061a57600080fd5b506001546101fd906001600160a01b031681565b600081815260036020526040812054600280548392908110610652576106526138c5565b60009182526020822060059091020180549092508290610674906001906138f1565b81548110610684576106846138c5565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106106d1576106d16138c5565b600091825260208220600590910201805490925082906106f3906001906138f1565b81548110610703576107036138c5565b60009182526020909120600d90910201600381015460ff16945090508361072e578060010154610731565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610780573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a49190613930565b50909350600492506107b4915050565b8160048111156107c6576107c6613997565b036108095760006107d688611ccf565b9050805160010361080757806000815181106107f4576107f46138c5565b6020026020010151965060009550600194505b505b5050509193909250565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190613930565b509350505050806108dd5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610930573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095491906139ad565b156109925760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016108d4565b6000868152600360205260408120546002805490919081106109b6576109b66138c5565b600091825260208083208884526003600590930201918201905260408220548154919350839181106109ea576109ea6138c5565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610a45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6991906139c8565b5050600087815260078401602052604090205490915060ff16610ab3576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610bf8565b808603610b28576000868152600683016020526040902054610ad6576000610b21565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610b179190613a04565b610b219190613a1b565b9450610bf8565b600081815260078301602052604090205460ff16610bf85781600601600083600a01600181548110610b5c57610b5c6138c5565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610b9257610b926138c5565b9060005260206000200154815260200190815260200160002054610bb69190613a3d565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610beb9190613a04565b610bf59190613a1b565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610c92576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60026000610caa612fdf565b8054909150600160401b900460ff1680610cd1575080546001600160401b03808416911610155b15610cee5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b60016000610d5b612fdf565b8054909150600160401b900460ff1680610d82575080546001600160401b03808416911610155b15610d9f5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610dca8484613003565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610e3b57610e3b6138c5565b600091825260209091206002600590920201015460ff1615610e6f5760405162461bcd60e51b81526004016108d490613a50565b600083815260036020526040812054600280549091908110610e9357610e936138c5565b906000526020600020906005020190508060010154831115610ef75760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016108d4565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f689190613a87565b91509150814210158015610f7b57508042105b610fc05760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016108d4565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102591906139c8565b5050905086810361103a5761271091506110bb565b61271061138861104a86866138f1565b6110549190613a04565b61105e9190613a1b565b61106885426138f1565b106110b55760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016108d4565b614e2091505b845460009086906110ce906001906138f1565b815481106110de576110de6138c5565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561113d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111619190613aab565b61116b91906138f1565b60008a815260078401602052604090205490915060ff16156111cf5760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016108d4565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d9190613aab565b9050600061271061124e8784613a04565b6112589190613a1b565b6112629083613a3d565b60008c8152600686016020526040812054919250908211156113135760008c8152600686016020526040902054349061129b90846138f1565b116112c05760008c81526006860160205260409020546112bb90836138f1565b6112c2565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161130a929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f84529091528120805483929061133f908490613a3d565b909155505060008c815260068601602052604081208054839290611364908490613a3d565b909155505060008c815260068601602052604090205482116114365760008c8152600686016020526040812054600987018054919290916113a6908490613a3d565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116415782856009015461145391906138f1565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa1580156114a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c591906139ad565b156114de5760028a01805460ff191660011790556115c1565b895460038b0160006114f1876001613a3d565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161156c91815260200190565b602060405180830381865afa158015611589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ad9190613aab565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161160e93929190613afe565b6000604051808303818588803b15801561162757600080fd5b505af115801561163b573d6000803e3d6000fd5b50505050505b8034111561166f57336108fc61165783346138f1565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61168782613039565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061170557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166116f96000805160206140748339815191525490565b6001600160a01b031614155b156117235760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561177d575060408051601f3d908101601f1916820190925261177a91810190613aab565b60015b6117a557604051630c76093760e01b81526001600160a01b03831660048201526024016108d4565b60008051602061407483398151915281146117d657604051632a87526960e21b8152600481018290526024016108d4565b6000805160206140748339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28151156118a1576000836001600160a01b03168360405161183d9190613b9d565b600060405180830381855af49150503d8060008114611878576040519150601f19603f3d011682016040523d82523d6000602084013e61187d565b606091505b505090508061189f576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146118f15760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061407483398151915290565b6002818154811061191457600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff909116929161194790613ac4565b80601f016020809104026020016040519081016040528092919081815260200182805461197390613ac4565b80156119c05780601f10611995576101008083540402835291602001916119c0565b820191906000526020600020905b8154815290600101906020018083116119a357829003601f168201915b5050505050905083565b6000848152600360205260409020546002805486929081106119ee576119ee6138c5565b600091825260209091206002600590920201015460ff1615611a225760405162461bcd60e51b81526004016108d490613a50565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190613930565b5090935060019250611aa0915050565b816004811115611ab257611ab2613997565b14611b0f5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016108d4565b82611b4c5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016108d4565b600086815260036020526040812054600280549091908110611b7057611b706138c5565b60009182526020822060059091020180549092508290611b92906001906138f1565b81548110611ba257611ba26138c5565b90600052602060002090600d0201905060005b86811015611c68573382898984818110611bd157611bd16138c5565b9050602002013581548110611be857611be86138c5565b60009182526020909120600490910201546001600160a01b031614611c1f5760405162461bcd60e51b81526004016108d490613bb9565b8582898984818110611c3357611c336138c5565b9050602002013581548110611c4a57611c4a6138c5565b60009182526020909120600160049092020181019190915501611bb5565b5086869050816005016000828254611c809190613a3d565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611cbd908b908b908b90613c22565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611cf557611cf56138c5565b60009182526020822060059091020180549092508290611d17906001906138f1565b81548110611d2757611d276138c5565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611d8557602002820191906000526020600020905b815481526020019060010190808311611d71575b505050505092505050919050565b600085815260036020526040812054600280548392908110611db757611db76138c5565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611deb57611deb6138c5565b90600052602060002090600d02016000018681548110611e0d57611e0d6138c5565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611e6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8f91906139c8565b506003850154919350915060ff168015611eb357508183600201541480611eb35750805b15611ec657612710945050505050611ecf565b60009450505050505b95945050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611f0957611f096138c5565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611f3d57611f3d6138c5565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611fb457611fb46138c5565b60009182526020822060059091020180549092508290611fd6906001906138f1565b81548110611fe657611fe66138c5565b60009182526020909120600d90910201805460049091015414949350505050565b6000546001600160a01b031633146120315760405162461bcd60e51b81526004016108d490613c46565b6000836001600160a01b0316838360405161204c9190613b9d565b60006040518083038185875af1925050503d8060008114612089576040519150601f19603f3d011682016040523d82523d6000602084013e61208e565b606091505b505090508061189f5760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016108d4565b6000868152600360205260409020546002805488929081106120f7576120f76138c5565b600091825260209091206002600590920201015460ff161561212b5760405162461bcd60e51b81526004016108d490613a50565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121999190613930565b50909350600292506121a9915050565b8160048111156121bb576121bb613997565b146122165760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016108d4565b856122585760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016108d4565b60008881526003602052604081205460028054909190811061227c5761227c6138c5565b9060005260206000209060050201905080600101548611156122d75760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016108d4565b805460009082906122ea906001906138f1565b815481106122fa576122fa6138c5565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123799190613930565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156123d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f89190613c88565b505050505091505060005b8a81101561266a5733848d8d8481811061241f5761241f6138c5565b9050602002013581548110612436576124366138c5565b60009182526020909120600490910201546001600160a01b03161461246d5760405162461bcd60e51b81526004016108d490613bb9565b8115806124e0575060408051602081018c90529081018a905260600160405160208183030381529060405280519060200120846000018d8d848181106124b5576124b56138c5565b90506020020135815481106124cc576124cc6138c5565b906000526020600020906004020160010154145b6125525760405162461bcd60e51b815260206004820152603d60248201527f54686520636f6d6d6974206d757374206d61746368207468652063686f69636560448201527f20696e20636f7572747320776974682068696464656e20766f7465732e00000060648201526084016108d4565b838c8c83818110612565576125656138c5565b905060200201358154811061257c5761257c6138c5565b600091825260209091206003600490920201015460ff16156125d55760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016108d4565b89848d8d848181106125e9576125e96138c5565b9050602002013581548110612600576126006138c5565b60009182526020909120600260049092020101556001848d8d84818110612629576126296138c5565b9050602002013581548110612640576126406138c5565b60009182526020909120600490910201600301805460ff1916911515919091179055600101612403565b508a8a90508360040160008282546126829190613a3d565b90915550506000898152600284016020526040812080548c92906126a7908490613a3d565b9091555050600183015489036126d657600383015460ff16156126d15760038301805460ff191690555b61274f565b60018301546000908152600284016020526040808220548b83529120540361271857600383015460ff166126d15760038301805460ff1916600117905561274f565b60018301546000908152600284016020526040808220548b8352912054111561274f576001830189905560038301805460ff191690555b88336001600160a01b03168d7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48e8e8c60405161278e93929190613cf2565b60405180910390a4505050505050505050505050565b6000546001600160a01b031633146127ce5760405162461bcd60e51b81526004016108d490613c46565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a8152602001908152602001600020548154811061281e5761281e6138c5565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612852576128526138c5565b90600052602060002090600d02016000018781548110612874576128746138c5565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146128e05760405162461bcd60e51b81526004016108d490613d22565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad20161296b858783613db6565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156129c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e69190613aab565b6129f091906138f1565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612a79908a908a908a90613e76565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612aaf57612aaf6138c5565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612ae357612ae36138c5565b90600052602060002090600d02016000018481548110612b0557612b056138c5565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612b535760405162461bcd60e51b81526004016108d490613d22565b600083815260036020526040902054600280548592908110612b7757612b776138c5565b600091825260209091206002600590920201015460ff1615612bab5760405162461bcd60e51b81526004016108d490613a50565b600084815260036020526040812054600280549091908110612bcf57612bcf6138c5565b60009182526020822060059091020180549092508290612bf1906001906138f1565b81548110612c0157612c016138c5565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8a9190613eac565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfd9190613930565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d859190613eac565b9650612d92848a89613066565b15612e2f57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c8901909152929092208054909216179055612e34565b600096505b50505050505092915050565b600082815260036020526040812054600280548392908110612e6457612e646138c5565b60009182526020808320868452600360059093020191820190526040822054815491935083918110612e9857612e986138c5565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b91906139c8565b5091509150826004015460001480612f4a575080158015612f4a57506000828152600284016020526040902054155b15612f5c576000945050505050612f8d565b8015612f71575050600401549150612f8d9050565b506000908152600290910160205260409020549150612f8d9050565b92915050565b6000546001600160a01b03163314612fbd5760405162461bcd60e51b81526004016108d490613c46565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b61300b613322565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146130635760405162461bcd60e51b81526004016108d490613c46565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156130b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d89190613930565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015613137573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315b9190613aab565b61316591906138f1565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156131a6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526131ce9190810190613f5c565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561322a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324e9190613eac565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156132a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c9919061403d565b50509150915082816132db9190613a3d565b60045490831015955060ff16156133175784801561331457506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b61332a613349565b61334757604051631afcd79f60e31b815260040160405180910390fd5b565b6000613353612fdf565b54600160401b900460ff16919050565b60006020828403121561337557600080fd5b5035919050565b6001600160a01b038116811461306357600080fd5b600080600080608085870312156133a757600080fd5b8435935060208501356133b98161337c565b93969395505050506040820135916060013590565b600080604083850312156133e157600080fd5b82356133ec8161337c565b915060208301356133fc8161337c565b809150509250929050565b6000806040838503121561341a57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561346257613462613429565b60405290565b604051601f8201601f191681016001600160401b038111828210171561349057613490613429565b604052919050565b60006001600160401b038311156134b1576134b1613429565b6134c4601f8401601f1916602001613468565b90508281528383830111156134d857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261350057600080fd5b61350f83833560208501613498565b9392505050565b6000806040838503121561352957600080fd5b82356135348161337c565b915060208301356001600160401b0381111561354f57600080fd5b61355b858286016134ef565b9150509250929050565b60005b83811015613580578181015183820152602001613568565b50506000910152565b600081518084526135a1816020860160208601613565565b601f01601f19169290920160200192915050565b60208152600061350f6020830184613589565b8381528215156020820152606060408201526000611ecf6060830184613589565b60008083601f8401126135fb57600080fd5b5081356001600160401b0381111561361257600080fd5b6020830191508360208260051b850101111561362d57600080fd5b9250929050565b6000806000806060858703121561364a57600080fd5b8435935060208501356001600160401b0381111561366757600080fd5b613673878288016135e9565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b818110156136be578351835292840192918401916001016136a2565b50909695505050505050565b600080600080600060a086880312156136e257600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006060848603121561371a57600080fd5b505081359360208301359350604090920135919050565b60008060006060848603121561374657600080fd5b83356137518161337c565b92506020840135915060408401356001600160401b0381111561377357600080fd5b61377f868287016134ef565b9150509250925092565b60008060008060008060a087890312156137a257600080fd5b8635955060208701356001600160401b03808211156137c057600080fd5b6137cc8a838b016135e9565b9097509550604089013594506060890135935060808901359150808211156137f357600080fd5b508701601f8101891361380557600080fd5b61381489823560208401613498565b9150509295509295509295565b60006020828403121561383357600080fd5b813561350f8161337c565b60008060008060006080868803121561385657600080fd5b853594506020860135935060408601356001600160401b038082111561387b57600080fd5b818801915088601f83011261388f57600080fd5b81358181111561389e57600080fd5b8960208285010111156138b057600080fd5b96999598505060200195606001359392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612f8d57612f8d6138db565b80516001600160601b038116811461391b57600080fd5b919050565b8051801515811461391b57600080fd5b600080600080600060a0868803121561394857600080fd5b61395186613904565b945060208601516139618161337c565b60408701519094506005811061397657600080fd5b925061398460608701613920565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156139bf57600080fd5b61350f82613920565b6000806000606084860312156139dd57600080fd5b835192506139ed60208501613920565b91506139fb60408501613920565b90509250925092565b8082028115828204841417612f8d57612f8d6138db565b600082613a3857634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115612f8d57612f8d6138db565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b60008060408385031215613a9a57600080fd5b505080516020909101519092909150565b600060208284031215613abd57600080fd5b5051919050565b600181811c90821680613ad857607f821691505b602082108103613af857634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613b1f81613ac4565b8060608701526080600180841660008114613b415760018114613b5d57613b8d565b60ff19851660808a0152608084151560051b8a01019550613b8d565b89600052602060002060005b85811015613b845781548b8201860152908301908801613b69565b8a016080019650505b50939a9950505050505050505050565b60008251613baf818460208701613565565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b03831115613c0957600080fd5b8260051b80836020870137939093016020019392505050565b604081526000613c36604083018587613bf0565b9050826020830152949350505050565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b600080600080600080600060e0888a031215613ca357600080fd5b613cac88613904565b9650613cba60208901613920565b955060408801519450606088015193506080880151925060a08801519150613ce460c08901613920565b905092959891949750929550565b604081526000613d06604083018587613bf0565b8281036020840152613d188185613589565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f8211156118a1576000816000526020600020601f850160051c81016020861015613d8f5750805b601f850160051c820191505b81811015613dae57828155600101613d9b565b505050505050565b6001600160401b03831115613dcd57613dcd613429565b613de183613ddb8354613ac4565b83613d66565b6000601f841160018114613e155760008515613dfd5750838201355b600019600387901b1c1916600186901b178355613e6f565b600083815260209020601f19861690835b82811015613e465786850135825560209485019460019092019101613e26565b5086821015613e635760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215613ebe57600080fd5b815161350f8161337c565b600082601f830112613eda57600080fd5b815160206001600160401b03821115613ef557613ef5613429565b8160051b613f04828201613468565b9283528481018201928281019087851115613f1e57600080fd5b83870192505b84831015613f46578251613f378161337c565b82529183019190830190613f24565b979650505050505050565b805161391b8161337c565b600060208284031215613f6e57600080fd5b81516001600160401b0380821115613f8557600080fd5b908301906101608286031215613f9a57600080fd5b613fa261343f565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015182811115613fea57600080fd5b613ff687828601613ec9565b60c08301525060e0838101519082015261010080840151908201526101209150614021828401613f51565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561405357600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220dbc0f07975f24862ef29107d65fe042a587199d6ad1f6756f0fbf8ad88bad54664736f6c63430008180033", - "deployedBytecode": "0x6080604052600436106101a35760003560e01c806369f3f041116100e2578063b6ede54011610085578063b6ede54014610558578063ba66fde714610578578063be46760414610598578063d2b8035a146105ae578063da3beb8c146105ce578063e349ad30146104a0578063e4c0aaf4146105ee578063f2f4eb261461060e57600080fd5b806369f3f041146104135780636d4cd8ea14610460578063751accd014610480578063796490f9146104a05780637c04034e146104b65780638e426460146104d6578063a7cc08fe146104f6578063b34bfaa81461054257600080fd5b80634b2f0ea01161014a5780634b2f0ea0146102fe5780634f1ef2861461031157806352d1902d1461032457806354fd4d5014610339578063564a565d146103775780635c92e2f6146103a657806365540b96146103c6578063675926f6146103f357600080fd5b80630baa64d1146101a85780630c340a24146101dd5780631200aabc146102155780631c3db16d146102505780632621b9a21461028d578063362c3479146102a7578063472abf68146102c7578063485cc955146102de575b600080fd5b3480156101b457600080fd5b506101c86101c3366004613363565b61062e565b60405190151581526020015b60405180910390f35b3480156101e957600080fd5b506000546101fd906001600160a01b031681565b6040516001600160a01b0390911681526020016101d4565b34801561022157600080fd5b50610242610230366004613363565b60036020526000908152604090205481565b6040519081526020016101d4565b34801561025c57600080fd5b5061027061026b366004613363565b6106a5565b6040805193845291151560208401521515908201526060016101d4565b34801561029957600080fd5b506004546101c89060ff1681565b3480156102b357600080fd5b506102426102c2366004613391565b610813565b3480156102d357600080fd5b506102dc610c9e565b005b3480156102ea57600080fd5b506102dc6102f93660046133ce565b610d4f565b6102dc61030c366004613407565b610e17565b6102dc61031f366004613516565b61167e565b34801561033057600080fd5b506102426118a6565b34801561034557600080fd5b5061036a604051806040016040528060058152602001640302e382e360dc1b81525081565b6040516101d491906135b5565b34801561038357600080fd5b50610397610392366004613363565b611904565b6040516101d4939291906135c8565b3480156103b257600080fd5b506102dc6103c1366004613634565b6119ca565b3480156103d257600080fd5b506103e66103e1366004613363565b611ccf565b6040516101d49190613686565b3480156103ff57600080fd5b5061024261040e3660046136ca565b611d93565b34801561041f57600080fd5b5061043361042e366004613705565b611ed8565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101d4565b34801561046c57600080fd5b506101c861047b366004613363565b611f90565b34801561048c57600080fd5b506102dc61049b366004613731565b612007565b3480156104ac57600080fd5b5061024261271081565b3480156104c257600080fd5b506102dc6104d1366004613789565b6120d3565b3480156104e257600080fd5b506102dc6104f1366004613821565b6127a4565b34801561050257600080fd5b50610516610511366004613705565b6127f0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101d4565b34801561054e57600080fd5b50610242614e2081565b34801561056457600080fd5b506102dc61057336600461383e565b6128b6565b34801561058457600080fd5b506101c8610593366004613705565b612a8b565b3480156105a457600080fd5b5061024261138881565b3480156105ba57600080fd5b506101fd6105c9366004613407565b612b26565b3480156105da57600080fd5b506102426105e9366004613407565b612e40565b3480156105fa57600080fd5b506102dc610609366004613821565b612f93565b34801561061a57600080fd5b506001546101fd906001600160a01b031681565b600081815260036020526040812054600280548392908110610652576106526138c5565b60009182526020822060059091020180549092508290610674906001906138f1565b81548110610684576106846138c5565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106106d1576106d16138c5565b600091825260208220600590910201805490925082906106f3906001906138f1565b81548110610703576107036138c5565b60009182526020909120600d90910201600381015460ff16945090508361072e578060010154610731565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610780573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a49190613930565b50909350600492506107b4915050565b8160048111156107c6576107c6613997565b036108095760006107d688611ccf565b9050805160010361080757806000815181106107f4576107f46138c5565b6020026020010151965060009550600194505b505b5050509193909250565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108859190613930565b509350505050806108dd5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610930573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095491906139ad565b156109925760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016108d4565b6000868152600360205260408120546002805490919081106109b6576109b66138c5565b600091825260208083208884526003600590930201918201905260408220548154919350839181106109ea576109ea6138c5565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610a45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6991906139c8565b5050600087815260078401602052604090205490915060ff16610ab3576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610bf8565b808603610b28576000868152600683016020526040902054610ad6576000610b21565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610b179190613a04565b610b219190613a1b565b9450610bf8565b600081815260078301602052604090205460ff16610bf85781600601600083600a01600181548110610b5c57610b5c6138c5565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610b9257610b926138c5565b9060005260206000200154815260200190815260200160002054610bb69190613a3d565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610beb9190613a04565b610bf59190613a1b565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610c92576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60026000610caa612fdf565b8054909150600160401b900460ff1680610cd1575080546001600160401b03808416911610155b15610cee5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b60016000610d5b612fdf565b8054909150600160401b900460ff1680610d82575080546001600160401b03808416911610155b15610d9f5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610dca8484613003565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610e3b57610e3b6138c5565b600091825260209091206002600590920201015460ff1615610e6f5760405162461bcd60e51b81526004016108d490613a50565b600083815260036020526040812054600280549091908110610e9357610e936138c5565b906000526020600020906005020190508060010154831115610ef75760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016108d4565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f689190613a87565b91509150814210158015610f7b57508042105b610fc05760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016108d4565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102591906139c8565b5050905086810361103a5761271091506110bb565b61271061138861104a86866138f1565b6110549190613a04565b61105e9190613a1b565b61106885426138f1565b106110b55760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016108d4565b614e2091505b845460009086906110ce906001906138f1565b815481106110de576110de6138c5565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561113d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111619190613aab565b61116b91906138f1565b60008a815260078401602052604090205490915060ff16156111cf5760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016108d4565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa158015611219573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123d9190613aab565b9050600061271061124e8784613a04565b6112589190613a1b565b6112629083613a3d565b60008c8152600686016020526040812054919250908211156113135760008c8152600686016020526040902054349061129b90846138f1565b116112c05760008c81526006860160205260409020546112bb90836138f1565b6112c2565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161130a929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f84529091528120805483929061133f908490613a3d565b909155505060008c815260068601602052604081208054839290611364908490613a3d565b909155505060008c815260068601602052604090205482116114365760008c8152600686016020526040812054600987018054919290916113a6908490613a3d565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116415782856009015461145391906138f1565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa1580156114a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c591906139ad565b156114de5760028a01805460ff191660011790556115c1565b895460038b0160006114f1876001613a3d565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161156c91815260200190565b602060405180830381865afa158015611589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ad9190613aab565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161160e93929190613afe565b6000604051808303818588803b15801561162757600080fd5b505af115801561163b573d6000803e3d6000fd5b50505050505b8034111561166f57336108fc61165783346138f1565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61168782613039565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061170557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166116f96000805160206140748339815191525490565b6001600160a01b031614155b156117235760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561177d575060408051601f3d908101601f1916820190925261177a91810190613aab565b60015b6117a557604051630c76093760e01b81526001600160a01b03831660048201526024016108d4565b60008051602061407483398151915281146117d657604051632a87526960e21b8152600481018290526024016108d4565b6000805160206140748339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28151156118a1576000836001600160a01b03168360405161183d9190613b9d565b600060405180830381855af49150503d8060008114611878576040519150601f19603f3d011682016040523d82523d6000602084013e61187d565b606091505b505090508061189f576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146118f15760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061407483398151915290565b6002818154811061191457600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff909116929161194790613ac4565b80601f016020809104026020016040519081016040528092919081815260200182805461197390613ac4565b80156119c05780601f10611995576101008083540402835291602001916119c0565b820191906000526020600020905b8154815290600101906020018083116119a357829003601f168201915b5050505050905083565b6000848152600360205260409020546002805486929081106119ee576119ee6138c5565b600091825260209091206002600590920201015460ff1615611a225760405162461bcd60e51b81526004016108d490613a50565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a909190613930565b5090935060019250611aa0915050565b816004811115611ab257611ab2613997565b14611b0f5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016108d4565b82611b4c5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016108d4565b600086815260036020526040812054600280549091908110611b7057611b706138c5565b60009182526020822060059091020180549092508290611b92906001906138f1565b81548110611ba257611ba26138c5565b90600052602060002090600d0201905060005b86811015611c68573382898984818110611bd157611bd16138c5565b9050602002013581548110611be857611be86138c5565b60009182526020909120600490910201546001600160a01b031614611c1f5760405162461bcd60e51b81526004016108d490613bb9565b8582898984818110611c3357611c336138c5565b9050602002013581548110611c4a57611c4a6138c5565b60009182526020909120600160049092020181019190915501611bb5565b5086869050816005016000828254611c809190613a3d565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611cbd908b908b908b90613c22565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611cf557611cf56138c5565b60009182526020822060059091020180549092508290611d17906001906138f1565b81548110611d2757611d276138c5565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611d8557602002820191906000526020600020905b815481526020019060010190808311611d71575b505050505092505050919050565b600085815260036020526040812054600280548392908110611db757611db76138c5565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611deb57611deb6138c5565b90600052602060002090600d02016000018681548110611e0d57611e0d6138c5565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611e6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8f91906139c8565b506003850154919350915060ff168015611eb357508183600201541480611eb35750805b15611ec657612710945050505050611ecf565b60009450505050505b95945050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611f0957611f096138c5565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611f3d57611f3d6138c5565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611fb457611fb46138c5565b60009182526020822060059091020180549092508290611fd6906001906138f1565b81548110611fe657611fe66138c5565b60009182526020909120600d90910201805460049091015414949350505050565b6000546001600160a01b031633146120315760405162461bcd60e51b81526004016108d490613c46565b6000836001600160a01b0316838360405161204c9190613b9d565b60006040518083038185875af1925050503d8060008114612089576040519150601f19603f3d011682016040523d82523d6000602084013e61208e565b606091505b505090508061189f5760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016108d4565b6000868152600360205260409020546002805488929081106120f7576120f76138c5565b600091825260209091206002600590920201015460ff161561212b5760405162461bcd60e51b81526004016108d490613a50565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121999190613930565b50909350600292506121a9915050565b8160048111156121bb576121bb613997565b146122165760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016108d4565b856122585760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016108d4565b60008881526003602052604081205460028054909190811061227c5761227c6138c5565b9060005260206000209060050201905080600101548611156122d75760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016108d4565b805460009082906122ea906001906138f1565b815481106122fa576122fa6138c5565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612355573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123799190613930565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156123d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f89190613c88565b505050505091505060005b8a81101561266a5733848d8d8481811061241f5761241f6138c5565b9050602002013581548110612436576124366138c5565b60009182526020909120600490910201546001600160a01b03161461246d5760405162461bcd60e51b81526004016108d490613bb9565b8115806124e0575060408051602081018c90529081018a905260600160405160208183030381529060405280519060200120846000018d8d848181106124b5576124b56138c5565b90506020020135815481106124cc576124cc6138c5565b906000526020600020906004020160010154145b6125525760405162461bcd60e51b815260206004820152603d60248201527f54686520636f6d6d6974206d757374206d61746368207468652063686f69636560448201527f20696e20636f7572747320776974682068696464656e20766f7465732e00000060648201526084016108d4565b838c8c83818110612565576125656138c5565b905060200201358154811061257c5761257c6138c5565b600091825260209091206003600490920201015460ff16156125d55760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016108d4565b89848d8d848181106125e9576125e96138c5565b9050602002013581548110612600576126006138c5565b60009182526020909120600260049092020101556001848d8d84818110612629576126296138c5565b9050602002013581548110612640576126406138c5565b60009182526020909120600490910201600301805460ff1916911515919091179055600101612403565b508a8a90508360040160008282546126829190613a3d565b90915550506000898152600284016020526040812080548c92906126a7908490613a3d565b9091555050600183015489036126d657600383015460ff16156126d15760038301805460ff191690555b61274f565b60018301546000908152600284016020526040808220548b83529120540361271857600383015460ff166126d15760038301805460ff1916600117905561274f565b60018301546000908152600284016020526040808220548b8352912054111561274f576001830189905560038301805460ff191690555b88336001600160a01b03168d7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48e8e8c60405161278e93929190613cf2565b60405180910390a4505050505050505050505050565b6000546001600160a01b031633146127ce5760405162461bcd60e51b81526004016108d490613c46565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a8152602001908152602001600020548154811061281e5761281e6138c5565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612852576128526138c5565b90600052602060002090600d02016000018781548110612874576128746138c5565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146128e05760405162461bcd60e51b81526004016108d490613d22565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad20161296b858783613db6565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156129c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e69190613aab565b6129f091906138f1565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612a79908a908a908a90613e76565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612aaf57612aaf6138c5565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612ae357612ae36138c5565b90600052602060002090600d02016000018481548110612b0557612b056138c5565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612b535760405162461bcd60e51b81526004016108d490613d22565b600083815260036020526040902054600280548592908110612b7757612b776138c5565b600091825260209091206002600590920201015460ff1615612bab5760405162461bcd60e51b81526004016108d490613a50565b600084815260036020526040812054600280549091908110612bcf57612bcf6138c5565b60009182526020822060059091020180549092508290612bf1906001906138f1565b81548110612c0157612c016138c5565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8a9190613eac565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfd9190613930565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612d61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d859190613eac565b9650612d92848a89613066565b15612e2f57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c8901909152929092208054909216179055612e34565b600096505b50505050505092915050565b600082815260036020526040812054600280548392908110612e6457612e646138c5565b60009182526020808320868452600360059093020191820190526040822054815491935083918110612e9857612e986138c5565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b91906139c8565b5091509150826004015460001480612f4a575080158015612f4a57506000828152600284016020526040902054155b15612f5c576000945050505050612f8d565b8015612f71575050600401549150612f8d9050565b506000908152600290910160205260409020549150612f8d9050565b92915050565b6000546001600160a01b03163314612fbd5760405162461bcd60e51b81526004016108d490613c46565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b61300b613322565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146130635760405162461bcd60e51b81526004016108d490613c46565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156130b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d89190613930565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015613137573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315b9190613aab565b61316591906138f1565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156131a6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526131ce9190810190613f5c565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561322a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324e9190613eac565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156132a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c9919061403d565b50509150915082816132db9190613a3d565b60045490831015955060ff16156133175784801561331457506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b61332a613349565b61334757604051631afcd79f60e31b815260040160405180910390fd5b565b6000613353612fdf565b54600160401b900460ff16919050565b60006020828403121561337557600080fd5b5035919050565b6001600160a01b038116811461306357600080fd5b600080600080608085870312156133a757600080fd5b8435935060208501356133b98161337c565b93969395505050506040820135916060013590565b600080604083850312156133e157600080fd5b82356133ec8161337c565b915060208301356133fc8161337c565b809150509250929050565b6000806040838503121561341a57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561346257613462613429565b60405290565b604051601f8201601f191681016001600160401b038111828210171561349057613490613429565b604052919050565b60006001600160401b038311156134b1576134b1613429565b6134c4601f8401601f1916602001613468565b90508281528383830111156134d857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261350057600080fd5b61350f83833560208501613498565b9392505050565b6000806040838503121561352957600080fd5b82356135348161337c565b915060208301356001600160401b0381111561354f57600080fd5b61355b858286016134ef565b9150509250929050565b60005b83811015613580578181015183820152602001613568565b50506000910152565b600081518084526135a1816020860160208601613565565b601f01601f19169290920160200192915050565b60208152600061350f6020830184613589565b8381528215156020820152606060408201526000611ecf6060830184613589565b60008083601f8401126135fb57600080fd5b5081356001600160401b0381111561361257600080fd5b6020830191508360208260051b850101111561362d57600080fd5b9250929050565b6000806000806060858703121561364a57600080fd5b8435935060208501356001600160401b0381111561366757600080fd5b613673878288016135e9565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b818110156136be578351835292840192918401916001016136a2565b50909695505050505050565b600080600080600060a086880312156136e257600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006060848603121561371a57600080fd5b505081359360208301359350604090920135919050565b60008060006060848603121561374657600080fd5b83356137518161337c565b92506020840135915060408401356001600160401b0381111561377357600080fd5b61377f868287016134ef565b9150509250925092565b60008060008060008060a087890312156137a257600080fd5b8635955060208701356001600160401b03808211156137c057600080fd5b6137cc8a838b016135e9565b9097509550604089013594506060890135935060808901359150808211156137f357600080fd5b508701601f8101891361380557600080fd5b61381489823560208401613498565b9150509295509295509295565b60006020828403121561383357600080fd5b813561350f8161337c565b60008060008060006080868803121561385657600080fd5b853594506020860135935060408601356001600160401b038082111561387b57600080fd5b818801915088601f83011261388f57600080fd5b81358181111561389e57600080fd5b8960208285010111156138b057600080fd5b96999598505060200195606001359392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115612f8d57612f8d6138db565b80516001600160601b038116811461391b57600080fd5b919050565b8051801515811461391b57600080fd5b600080600080600060a0868803121561394857600080fd5b61395186613904565b945060208601516139618161337c565b60408701519094506005811061397657600080fd5b925061398460608701613920565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156139bf57600080fd5b61350f82613920565b6000806000606084860312156139dd57600080fd5b835192506139ed60208501613920565b91506139fb60408501613920565b90509250925092565b8082028115828204841417612f8d57612f8d6138db565b600082613a3857634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115612f8d57612f8d6138db565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b60008060408385031215613a9a57600080fd5b505080516020909101519092909150565b600060208284031215613abd57600080fd5b5051919050565b600181811c90821680613ad857607f821691505b602082108103613af857634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613b1f81613ac4565b8060608701526080600180841660008114613b415760018114613b5d57613b8d565b60ff19851660808a0152608084151560051b8a01019550613b8d565b89600052602060002060005b85811015613b845781548b8201860152908301908801613b69565b8a016080019650505b50939a9950505050505050505050565b60008251613baf818460208701613565565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b03831115613c0957600080fd5b8260051b80836020870137939093016020019392505050565b604081526000613c36604083018587613bf0565b9050826020830152949350505050565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b600080600080600080600060e0888a031215613ca357600080fd5b613cac88613904565b9650613cba60208901613920565b955060408801519450606088015193506080880151925060a08801519150613ce460c08901613920565b905092959891949750929550565b604081526000613d06604083018587613bf0565b8281036020840152613d188185613589565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f8211156118a1576000816000526020600020601f850160051c81016020861015613d8f5750805b601f850160051c820191505b81811015613dae57828155600101613d9b565b505050505050565b6001600160401b03831115613dcd57613dcd613429565b613de183613ddb8354613ac4565b83613d66565b6000601f841160018114613e155760008515613dfd5750838201355b600019600387901b1c1916600186901b178355613e6f565b600083815260209020601f19861690835b82811015613e465786850135825560209485019460019092019101613e26565b5086821015613e635760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b600060208284031215613ebe57600080fd5b815161350f8161337c565b600082601f830112613eda57600080fd5b815160206001600160401b03821115613ef557613ef5613429565b8160051b613f04828201613468565b9283528481018201928281019087851115613f1e57600080fd5b83870192505b84831015613f46578251613f378161337c565b82529183019190830190613f24565b979650505050505050565b805161391b8161337c565b600060208284031215613f6e57600080fd5b81516001600160401b0380821115613f8557600080fd5b908301906101608286031215613f9a57600080fd5b613fa261343f565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015182811115613fea57600080fd5b613ff687828601613ec9565b60c08301525060e0838101519082015261010080840151908201526101209150614021828401613f51565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561405357600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220dbc0f07975f24862ef29107d65fe042a587199d6ad1f6756f0fbf8ad88bad54664736f6c63430008180033", + "numDeployments": 2, + "solcInputHash": "1476c8f3428345b8e6ba7181b9df7adb", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize3\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encodingThe unused parameters may be used by overriding contracts.\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitClassic Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":\"DisputeKitClassic\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitClassic\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\ncontract DisputeKitClassic is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0xcd903598b64f06e569320faf8548c240fe182b68a46515327bfea4d9fc662e6d\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbf209306f450437b609837aab267810dcf8311442ed28abb32ad5d62ed43bd9b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161432d620001036000396000818161172c01528181611755015261194d015261432d6000f3fe6080604052600436106101b95760003560e01c806369f3f041116100ed578063b6ede54011610090578063b6ede54014610599578063ba66fde7146105b9578063be467604146105d9578063d2b8035a146105ef578063da3beb8c1461060f578063e349ad30146104e1578063e4c0aaf41461062f578063ec918b651461064f578063f2f4eb261461066457600080fd5b806369f3f041146104545780636d4cd8ea146104a1578063751accd0146104c1578063796490f9146104e15780637c04034e146104f75780638e42646014610517578063a7cc08fe14610537578063b34bfaa81461058357600080fd5b8063485cc95511610160578063485cc9551461031d5780634b2f0ea01461033f5780634f1ef2861461035257806352d1902d1461036557806354fd4d501461037a578063564a565d146103b85780635c92e2f6146103e757806365540b9614610407578063675926f61461043457600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e3578063362c3479146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d93660046135aa565b610684565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e3660046135aa565b61074c565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b506102786102663660046135aa565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a13660046135aa565b6107c3565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de3660046136a1565b610931565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b50610278610318366004613705565b61095e565b34801561032957600080fd5b5061033d610338366004613742565b610de9565b005b61033d61034d36600461377b565b610eb1565b61033d61036036600461379d565b611718565b34801561037157600080fd5b50610278611940565b34801561038657600080fd5b506103ab604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea919061383c565b3480156103c457600080fd5b506103d86103d33660046135aa565b61199e565b6040516101ea93929190613856565b3480156103f357600080fd5b5061033d6104023660046138c2565b611a64565b34801561041357600080fd5b506104276104223660046135aa565b611d69565b6040516101ea9190613914565b34801561044057600080fd5b5061027861044f366004613958565b611e2d565b34801561046057600080fd5b5061047461046f366004613993565b611f70565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104ad57600080fd5b506101de6104bc3660046135aa565b612028565b3480156104cd57600080fd5b5061033d6104dc3660046139bf565b6121ab565b3480156104ed57600080fd5b5061027861271081565b34801561050357600080fd5b5061033d610512366004613a01565b612277565b34801561052357600080fd5b5061033d610532366004613a85565b61293a565b34801561054357600080fd5b50610557610552366004613993565b612986565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b34801561058f57600080fd5b50610278614e2081565b3480156105a557600080fd5b5061033d6105b4366004613aa2565b612a4c565b3480156105c557600080fd5b506101de6105d4366004613993565b612c21565b3480156105e557600080fd5b5061027861138881565b3480156105fb57600080fd5b5061023361060a36600461377b565b612cbc565b34801561061b57600080fd5b5061027861062a36600461377b565b612fd6565b34801561063b57600080fd5b5061033d61064a366004613a85565b613129565b34801561065b57600080fd5b5061033d613175565b34801561067057600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f59190613b29565b91509150600061070485611d69565b90508051600014801561074357506127106113886107228585613b63565b61072c9190613b76565b6107369190613b8d565b6107408442613b63565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077057610770613baf565b6000918252602082206005909102018054909250829061079290600190613b63565b815481106107a2576107a2613baf565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107ef576107ef613baf565b6000918252602082206005909102018054909250829061081190600190613b63565b8154811061082157610821613baf565b60009182526020909120600d90910201600381015460ff16945090508361084c57806001015461084f565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c29190613bf1565b50909350600492506108d2915050565b8160048111156108e4576108e4613c58565b036109275760006108f488611d69565b90508051600103610925578060008151811061091257610912613baf565b6020026020010151965060009550600194505b505b5050509193909250565b50604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d09190613bf1565b50935050505080610a285760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190613c6e565b15610add5760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b6044820152606401610a1f565b600086815260036020526040812054600280549091908110610b0157610b01613baf565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610b3557610b35613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190613c89565b5050600087815260078401602052604090205490915060ff16610bfe576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610d43565b808603610c73576000868152600683016020526040902054610c21576000610c6c565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610c629190613b76565b610c6c9190613b8d565b9450610d43565b600081815260078301602052604090205460ff16610d435781600601600083600a01600181548110610ca757610ca7613baf565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610cdd57610cdd613baf565b9060005260206000200154815260200190815260200160002054610d019190613cc5565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610d369190613b76565b610d409190613b8d565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ddd576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610df5613226565b8054909150600160401b900460ff1680610e1c575080546001600160401b03808416911610155b15610e395760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610e64848461324a565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610ed557610ed5613baf565b600091825260209091206002600590920201015460ff1615610f095760405162461bcd60e51b8152600401610a1f90613cd8565b600083815260036020526040812054600280549091908110610f2d57610f2d613baf565b906000526020600020906005020190508060010154831115610f915760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610a1f565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110029190613b29565b9150915081421015801561101557508042105b61105a5760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610a1f565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613c89565b505090508681036110d4576127109150611155565b6127106113886110e48686613b63565b6110ee9190613b76565b6110f89190613b8d565b6111028542613b63565b1061114f5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610a1f565b614e2091505b8454600090869061116890600190613b63565b8154811061117857611178613baf565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190613d0f565b6112059190613b63565b60008a815260078401602052604090205490915060ff16156112695760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610a1f565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d79190613d0f565b905060006127106112e88784613b76565b6112f29190613b8d565b6112fc9083613cc5565b60008c8152600686016020526040812054919250908211156113ad5760008c815260068601602052604090205434906113359084613b63565b1161135a5760008c81526006860160205260409020546113559083613b63565b61135c565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516113a4929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906113d9908490613cc5565b909155505060008c8152600686016020526040812080548392906113fe908490613cc5565b909155505060008c815260068601602052604090205482116114d05760008c815260068601602052604081205460098701805491929091611440908490613cc5565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116db578285600901546114ed9190613b63565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190613c6e565b156115785760028a01805460ff1916600117905561165b565b895460038b01600061158b876001613cc5565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161160691815260200190565b602060405180830381865afa158015611623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116479190613d0f565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016116a893929190613d62565b6000604051808303818588803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b50505050505b8034111561170957336108fc6116f18334613b63565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61172182613280565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061179f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166117936000805160206142d88339815191525490565b6001600160a01b031614155b156117bd5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611817575060408051601f3d908101601f1916820190925261181491810190613d0f565b60015b61183f57604051630c76093760e01b81526001600160a01b0383166004820152602401610a1f565b6000805160206142d8833981519152811461187057604051632a87526960e21b815260048101829052602401610a1f565b6000805160206142d88339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a281511561193b576000836001600160a01b0316836040516118d79190613e01565b600060405180830381855af49150503d8060008114611912576040519150601f19603f3d011682016040523d82523d6000602084013e611917565b606091505b5050905080611939576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461198b5760405163703e46dd60e11b815260040160405180910390fd5b506000805160206142d883398151915290565b600281815481106119ae57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916119e190613d28565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0d90613d28565b8015611a5a5780601f10611a2f57610100808354040283529160200191611a5a565b820191906000526020600020905b815481529060010190602001808311611a3d57829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611a8857611a88613baf565b600091825260209091206002600590920201015460ff1615611abc5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611b06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2a9190613bf1565b5090935060019250611b3a915050565b816004811115611b4c57611b4c613c58565b14611ba95760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610a1f565b82611be65760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610a1f565b600086815260036020526040812054600280549091908110611c0a57611c0a613baf565b60009182526020822060059091020180549092508290611c2c90600190613b63565b81548110611c3c57611c3c613baf565b90600052602060002090600d0201905060005b86811015611d02573382898984818110611c6b57611c6b613baf565b9050602002013581548110611c8257611c82613baf565b60009182526020909120600490910201546001600160a01b031614611cb95760405162461bcd60e51b8152600401610a1f90613e1d565b8582898984818110611ccd57611ccd613baf565b9050602002013581548110611ce457611ce4613baf565b60009182526020909120600160049092020181019190915501611c4f565b5086869050816005016000828254611d1a9190613cc5565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611d57908b908b908b90613e86565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611d8f57611d8f613baf565b60009182526020822060059091020180549092508290611db190600190613b63565b81548110611dc157611dc1613baf565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611e1f57602002820191906000526020600020905b815481526020019060010190808311611e0b575b505050505092505050919050565b600085815260036020526040812054600280548392908110611e5157611e51613baf565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611e8557611e85613baf565b90600052602060002090600d02016000018681548110611ea757611ea7613baf565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190613c89565b506003850154919350915060ff168015611f4d57508183600201541480611f4d5750805b15611f6057612710945050505050610743565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611fa157611fa1613baf565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611fd557611fd5613baf565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061204c5761204c613baf565b6000918252602082206005909102018054909250829061206e90600190613b63565b8154811061207e5761207e613baf565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fd9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c9190613eaa565b5050505050915050600081612192578354612198565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146121d55760405162461bcd60e51b8152600401610a1f90613f14565b6000836001600160a01b031683836040516121f09190613e01565b60006040518083038185875af1925050503d806000811461222d576040519150601f19603f3d011682016040523d82523d6000602084013e612232565b606091505b50509050806119395760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610a1f565b60008681526003602052604090205460028054889290811061229b5761229b613baf565b600091825260209091206002600590920201015460ff16156122cf5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613bf1565b509093506002925061234d915050565b81600481111561235f5761235f613c58565b146123ba5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610a1f565b856123fc5760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610a1f565b60008881526003602052604081205460028054909190811061242057612420613baf565b90600052602060002090600502019050806001015486111561247b5760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610a1f565b8054600090829061248e90600190613b63565b8154811061249e5761249e613baf565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612578573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259c9190613eaa565b505050505091505060006125b18a8a8a610931565b905060005b8b8110156127ff5733858e8e848181106125d2576125d2613baf565b90506020020135815481106125e9576125e9613baf565b60009182526020909120600490910201546001600160a01b0316146126205760405162461bcd60e51b8152600401610a1f90613e1d565b821580612667575081858e8e8481811061263c5761263c613baf565b905060200201358154811061265357612653613baf565b906000526020600020906004020160010154145b6126e75760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a401610a1f565b848d8d838181106126fa576126fa613baf565b905060200201358154811061271157612711613baf565b600091825260209091206003600490920201015460ff161561276a5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610a1f565b8a858e8e8481811061277e5761277e613baf565b905060200201358154811061279557612795613baf565b60009182526020909120600260049092020101556001858e8e848181106127be576127be613baf565b90506020020135815481106127d5576127d5613baf565b60009182526020909120600490910201600301805460ff19169115159190911790556001016125b6565b508b8b90508460040160008282546128179190613cc5565b909155505060008a8152600285016020526040812080548d929061283c908490613cc5565b909155505060018401548a0361286b57600384015460ff16156128665760038401805460ff191690555b6128e4565b60018401546000908152600285016020526040808220548c8352912054036128ad57600384015460ff166128665760038401805460ff191660011790556128e4565b60018401546000908152600285016020526040808220548c835291205411156128e457600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161292393929190613f56565b60405180910390a450505050505050505050505050565b6000546001600160a01b031633146129645760405162461bcd60e51b8152600401610a1f90613f14565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106129b4576129b4613baf565b600091825260208083208a84526003600590930201918201905260408220548154919350839181106129e8576129e8613baf565b90600052602060002090600d02016000018781548110612a0a57612a0a613baf565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612a765760405162461bcd60e51b8152600401610a1f90613f86565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612b0185878361401a565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612b58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7c9190613d0f565b612b869190613b63565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612c0f908a908a908a906140da565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612c4557612c45613baf565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612c7957612c79613baf565b90600052602060002090600d02016000018481548110612c9b57612c9b613baf565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ce95760405162461bcd60e51b8152600401610a1f90613f86565b600083815260036020526040902054600280548592908110612d0d57612d0d613baf565b600091825260209091206002600590920201015460ff1615612d415760405162461bcd60e51b8152600401610a1f90613cd8565b600084815260036020526040812054600280549091908110612d6557612d65613baf565b60009182526020822060059091020180549092508290612d8790600190613b63565b81548110612d9757612d97613baf565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190614110565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612e6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e939190613bf1565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b9190614110565b9650612f28848a896132ad565b15612fc557604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c8901909152929092208054909216179055612fca565b600096505b50505050505092915050565b600082815260036020526040812054600280548392908110612ffa57612ffa613baf565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061302e5761302e613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561308d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b19190613c89565b50915091508260040154600014806130e05750801580156130e057506000828152600284016020526040902054155b156130f2576000945050505050613123565b80156131075750506004015491506131239050565b5060009081526002909101602052604090205491506131239050565b92915050565b6000546001600160a01b031633146131535760405162461bcd60e51b8152600401610a1f90613f14565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60036000613181613226565b8054909150600160401b900460ff16806131a8575080546001600160401b03808416911610155b156131c55760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b613252613569565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132aa5760405162461bcd60e51b8152600401610a1f90613f14565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156132fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331f9190613bf1565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa15801561337e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a29190613d0f565b6133ac9190613b63565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156133ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261341591908101906141c0565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134959190614110565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156134ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351091906142a1565b50509150915082816135229190613cc5565b60045490831015955060ff161561355e5784801561355b57506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b613571613590565b61358e57604051631afcd79f60e31b815260040160405180910390fd5b565b600061359a613226565b54600160401b900460ff16919050565b6000602082840312156135bc57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156135fc576135fc6135c3565b60405290565b604051601f8201601f191681016001600160401b038111828210171561362a5761362a6135c3565b604052919050565b600082601f83011261364357600080fd5b81356001600160401b0381111561365c5761365c6135c3565b61366f601f8201601f1916602001613602565b81815284602083860101111561368457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156136b657600080fd5b833592506020840135915060408401356001600160401b038111156136da57600080fd5b6136e686828701613632565b9150509250925092565b6001600160a01b03811681146132aa57600080fd5b6000806000806080858703121561371b57600080fd5b84359350602085013561372d816136f0565b93969395505050506040820135916060013590565b6000806040838503121561375557600080fd5b8235613760816136f0565b91506020830135613770816136f0565b809150509250929050565b6000806040838503121561378e57600080fd5b50508035926020909101359150565b600080604083850312156137b057600080fd5b82356137bb816136f0565b915060208301356001600160401b038111156137d657600080fd5b6137e285828601613632565b9150509250929050565b60005b838110156138075781810151838201526020016137ef565b50506000910152565b600081518084526138288160208601602086016137ec565b601f01601f19169290920160200192915050565b60208152600061384f6020830184613810565b9392505050565b83815282151560208201526060604082015260006107436060830184613810565b60008083601f84011261388957600080fd5b5081356001600160401b038111156138a057600080fd5b6020830191508360208260051b85010111156138bb57600080fd5b9250929050565b600080600080606085870312156138d857600080fd5b8435935060208501356001600160401b038111156138f557600080fd5b61390187828801613877565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561394c57835183529284019291840191600101613930565b50909695505050505050565b600080600080600060a0868803121561397057600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806000606084860312156139a857600080fd5b505081359360208301359350604090920135919050565b6000806000606084860312156139d457600080fd5b83356139df816136f0565b92506020840135915060408401356001600160401b038111156136da57600080fd5b60008060008060008060a08789031215613a1a57600080fd5b8635955060208701356001600160401b0380821115613a3857600080fd5b613a448a838b01613877565b909750955060408901359450606089013593506080890135915080821115613a6b57600080fd5b50613a7889828a01613632565b9150509295509295509295565b600060208284031215613a9757600080fd5b813561384f816136f0565b600080600080600060808688031215613aba57600080fd5b853594506020860135935060408601356001600160401b0380821115613adf57600080fd5b818801915088601f830112613af357600080fd5b813581811115613b0257600080fd5b896020828501011115613b1457600080fd5b96999598505060200195606001359392505050565b60008060408385031215613b3c57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561312357613123613b4d565b808202811582820484141761312357613123613b4d565b600082613baa57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613bdc57600080fd5b919050565b80518015158114613bdc57600080fd5b600080600080600060a08688031215613c0957600080fd5b613c1286613bc5565b94506020860151613c22816136f0565b604087015190945060058110613c3757600080fd5b9250613c4560608701613be1565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613c8057600080fd5b61384f82613be1565b600080600060608486031215613c9e57600080fd5b83519250613cae60208501613be1565b9150613cbc60408501613be1565b90509250925092565b8082018082111561312357613123613b4d565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b600060208284031215613d2157600080fd5b5051919050565b600181811c90821680613d3c57607f821691505b602082108103613d5c57634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613d8381613d28565b8060608701526080600180841660008114613da55760018114613dc157613df1565b60ff19851660808a0152608084151560051b8a01019550613df1565b89600052602060002060005b85811015613de85781548b8201860152908301908801613dcd565b8a016080019650505b50939a9950505050505050505050565b60008251613e138184602087016137ec565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b03831115613e6d57600080fd5b8260051b80836020870137939093016020019392505050565b604081526000613e9a604083018587613e54565b9050826020830152949350505050565b600080600080600080600060e0888a031215613ec557600080fd5b613ece88613bc5565b9650613edc60208901613be1565b955060408801519450606088015193506080880151925060a08801519150613f0660c08901613be1565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000613f6a604083018587613e54565b8281036020840152613f7c8185613810565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f82111561193b576000816000526020600020601f850160051c81016020861015613ff35750805b601f850160051c820191505b8181101561401257828155600101613fff565b505050505050565b6001600160401b03831115614031576140316135c3565b6140458361403f8354613d28565b83613fca565b6000601f84116001811461407957600085156140615750838201355b600019600387901b1c1916600186901b1783556140d3565b600083815260209020601f19861690835b828110156140aa578685013582556020948501946001909201910161408a565b50868210156140c75760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561412257600080fd5b815161384f816136f0565b600082601f83011261413e57600080fd5b815160206001600160401b03821115614159576141596135c3565b8160051b614168828201613602565b928352848101820192828101908785111561418257600080fd5b83870192505b848310156141aa57825161419b816136f0565b82529183019190830190614188565b979650505050505050565b8051613bdc816136f0565b6000602082840312156141d257600080fd5b81516001600160401b03808211156141e957600080fd5b9083019061016082860312156141fe57600080fd5b6142066135d9565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561424e57600080fd5b61425a8782860161412d565b60c08301525060e08381015190820152610100808401519082015261012091506142858284016141b5565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156142b757600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220ebfec9af244a625ba29b828f8582149fa1b92ced62e2f25183243cbccf37668d64736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106101b95760003560e01c806369f3f041116100ed578063b6ede54011610090578063b6ede54014610599578063ba66fde7146105b9578063be467604146105d9578063d2b8035a146105ef578063da3beb8c1461060f578063e349ad30146104e1578063e4c0aaf41461062f578063ec918b651461064f578063f2f4eb261461066457600080fd5b806369f3f041146104545780636d4cd8ea146104a1578063751accd0146104c1578063796490f9146104e15780637c04034e146104f75780638e42646014610517578063a7cc08fe14610537578063b34bfaa81461058357600080fd5b8063485cc95511610160578063485cc9551461031d5780634b2f0ea01461033f5780634f1ef2861461035257806352d1902d1461036557806354fd4d501461037a578063564a565d146103b85780635c92e2f6146103e757806365540b9614610407578063675926f61461043457600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e3578063362c3479146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d93660046135aa565b610684565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e3660046135aa565b61074c565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b506102786102663660046135aa565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a13660046135aa565b6107c3565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de3660046136a1565b610931565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b50610278610318366004613705565b61095e565b34801561032957600080fd5b5061033d610338366004613742565b610de9565b005b61033d61034d36600461377b565b610eb1565b61033d61036036600461379d565b611718565b34801561037157600080fd5b50610278611940565b34801561038657600080fd5b506103ab604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea919061383c565b3480156103c457600080fd5b506103d86103d33660046135aa565b61199e565b6040516101ea93929190613856565b3480156103f357600080fd5b5061033d6104023660046138c2565b611a64565b34801561041357600080fd5b506104276104223660046135aa565b611d69565b6040516101ea9190613914565b34801561044057600080fd5b5061027861044f366004613958565b611e2d565b34801561046057600080fd5b5061047461046f366004613993565b611f70565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104ad57600080fd5b506101de6104bc3660046135aa565b612028565b3480156104cd57600080fd5b5061033d6104dc3660046139bf565b6121ab565b3480156104ed57600080fd5b5061027861271081565b34801561050357600080fd5b5061033d610512366004613a01565b612277565b34801561052357600080fd5b5061033d610532366004613a85565b61293a565b34801561054357600080fd5b50610557610552366004613993565b612986565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b34801561058f57600080fd5b50610278614e2081565b3480156105a557600080fd5b5061033d6105b4366004613aa2565b612a4c565b3480156105c557600080fd5b506101de6105d4366004613993565b612c21565b3480156105e557600080fd5b5061027861138881565b3480156105fb57600080fd5b5061023361060a36600461377b565b612cbc565b34801561061b57600080fd5b5061027861062a36600461377b565b612fd6565b34801561063b57600080fd5b5061033d61064a366004613a85565b613129565b34801561065b57600080fd5b5061033d613175565b34801561067057600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f59190613b29565b91509150600061070485611d69565b90508051600014801561074357506127106113886107228585613b63565b61072c9190613b76565b6107369190613b8d565b6107408442613b63565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077057610770613baf565b6000918252602082206005909102018054909250829061079290600190613b63565b815481106107a2576107a2613baf565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107ef576107ef613baf565b6000918252602082206005909102018054909250829061081190600190613b63565b8154811061082157610821613baf565b60009182526020909120600d90910201600381015460ff16945090508361084c57806001015461084f565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c29190613bf1565b50909350600492506108d2915050565b8160048111156108e4576108e4613c58565b036109275760006108f488611d69565b90508051600103610925578060008151811061091257610912613baf565b6020026020010151965060009550600194505b505b5050509193909250565b50604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d09190613bf1565b50935050505080610a285760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190613c6e565b15610add5760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b6044820152606401610a1f565b600086815260036020526040812054600280549091908110610b0157610b01613baf565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610b3557610b35613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190613c89565b5050600087815260078401602052604090205490915060ff16610bfe576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610d43565b808603610c73576000868152600683016020526040902054610c21576000610c6c565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610c629190613b76565b610c6c9190613b8d565b9450610d43565b600081815260078301602052604090205460ff16610d435781600601600083600a01600181548110610ca757610ca7613baf565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610cdd57610cdd613baf565b9060005260206000200154815260200190815260200160002054610d019190613cc5565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610d369190613b76565b610d409190613b8d565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ddd576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610df5613226565b8054909150600160401b900460ff1680610e1c575080546001600160401b03808416911610155b15610e395760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610e64848461324a565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610ed557610ed5613baf565b600091825260209091206002600590920201015460ff1615610f095760405162461bcd60e51b8152600401610a1f90613cd8565b600083815260036020526040812054600280549091908110610f2d57610f2d613baf565b906000526020600020906005020190508060010154831115610f915760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610a1f565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110029190613b29565b9150915081421015801561101557508042105b61105a5760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610a1f565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613c89565b505090508681036110d4576127109150611155565b6127106113886110e48686613b63565b6110ee9190613b76565b6110f89190613b8d565b6111028542613b63565b1061114f5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610a1f565b614e2091505b8454600090869061116890600190613b63565b8154811061117857611178613baf565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190613d0f565b6112059190613b63565b60008a815260078401602052604090205490915060ff16156112695760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610a1f565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d79190613d0f565b905060006127106112e88784613b76565b6112f29190613b8d565b6112fc9083613cc5565b60008c8152600686016020526040812054919250908211156113ad5760008c815260068601602052604090205434906113359084613b63565b1161135a5760008c81526006860160205260409020546113559083613b63565b61135c565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516113a4929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906113d9908490613cc5565b909155505060008c8152600686016020526040812080548392906113fe908490613cc5565b909155505060008c815260068601602052604090205482116114d05760008c815260068601602052604081205460098701805491929091611440908490613cc5565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116db578285600901546114ed9190613b63565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190613c6e565b156115785760028a01805460ff1916600117905561165b565b895460038b01600061158b876001613cc5565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161160691815260200190565b602060405180830381865afa158015611623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116479190613d0f565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016116a893929190613d62565b6000604051808303818588803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b50505050505b8034111561170957336108fc6116f18334613b63565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61172182613280565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061179f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166117936000805160206142d88339815191525490565b6001600160a01b031614155b156117bd5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611817575060408051601f3d908101601f1916820190925261181491810190613d0f565b60015b61183f57604051630c76093760e01b81526001600160a01b0383166004820152602401610a1f565b6000805160206142d8833981519152811461187057604051632a87526960e21b815260048101829052602401610a1f565b6000805160206142d88339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a281511561193b576000836001600160a01b0316836040516118d79190613e01565b600060405180830381855af49150503d8060008114611912576040519150601f19603f3d011682016040523d82523d6000602084013e611917565b606091505b5050905080611939576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461198b5760405163703e46dd60e11b815260040160405180910390fd5b506000805160206142d883398151915290565b600281815481106119ae57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916119e190613d28565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0d90613d28565b8015611a5a5780601f10611a2f57610100808354040283529160200191611a5a565b820191906000526020600020905b815481529060010190602001808311611a3d57829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611a8857611a88613baf565b600091825260209091206002600590920201015460ff1615611abc5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611b06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2a9190613bf1565b5090935060019250611b3a915050565b816004811115611b4c57611b4c613c58565b14611ba95760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610a1f565b82611be65760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610a1f565b600086815260036020526040812054600280549091908110611c0a57611c0a613baf565b60009182526020822060059091020180549092508290611c2c90600190613b63565b81548110611c3c57611c3c613baf565b90600052602060002090600d0201905060005b86811015611d02573382898984818110611c6b57611c6b613baf565b9050602002013581548110611c8257611c82613baf565b60009182526020909120600490910201546001600160a01b031614611cb95760405162461bcd60e51b8152600401610a1f90613e1d565b8582898984818110611ccd57611ccd613baf565b9050602002013581548110611ce457611ce4613baf565b60009182526020909120600160049092020181019190915501611c4f565b5086869050816005016000828254611d1a9190613cc5565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611d57908b908b908b90613e86565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611d8f57611d8f613baf565b60009182526020822060059091020180549092508290611db190600190613b63565b81548110611dc157611dc1613baf565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611e1f57602002820191906000526020600020905b815481526020019060010190808311611e0b575b505050505092505050919050565b600085815260036020526040812054600280548392908110611e5157611e51613baf565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611e8557611e85613baf565b90600052602060002090600d02016000018681548110611ea757611ea7613baf565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190613c89565b506003850154919350915060ff168015611f4d57508183600201541480611f4d5750805b15611f6057612710945050505050610743565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611fa157611fa1613baf565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611fd557611fd5613baf565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061204c5761204c613baf565b6000918252602082206005909102018054909250829061206e90600190613b63565b8154811061207e5761207e613baf565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fd9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c9190613eaa565b5050505050915050600081612192578354612198565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146121d55760405162461bcd60e51b8152600401610a1f90613f14565b6000836001600160a01b031683836040516121f09190613e01565b60006040518083038185875af1925050503d806000811461222d576040519150601f19603f3d011682016040523d82523d6000602084013e612232565b606091505b50509050806119395760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610a1f565b60008681526003602052604090205460028054889290811061229b5761229b613baf565b600091825260209091206002600590920201015460ff16156122cf5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613bf1565b509093506002925061234d915050565b81600481111561235f5761235f613c58565b146123ba5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610a1f565b856123fc5760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610a1f565b60008881526003602052604081205460028054909190811061242057612420613baf565b90600052602060002090600502019050806001015486111561247b5760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610a1f565b8054600090829061248e90600190613b63565b8154811061249e5761249e613baf565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612578573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259c9190613eaa565b505050505091505060006125b18a8a8a610931565b905060005b8b8110156127ff5733858e8e848181106125d2576125d2613baf565b90506020020135815481106125e9576125e9613baf565b60009182526020909120600490910201546001600160a01b0316146126205760405162461bcd60e51b8152600401610a1f90613e1d565b821580612667575081858e8e8481811061263c5761263c613baf565b905060200201358154811061265357612653613baf565b906000526020600020906004020160010154145b6126e75760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a401610a1f565b848d8d838181106126fa576126fa613baf565b905060200201358154811061271157612711613baf565b600091825260209091206003600490920201015460ff161561276a5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610a1f565b8a858e8e8481811061277e5761277e613baf565b905060200201358154811061279557612795613baf565b60009182526020909120600260049092020101556001858e8e848181106127be576127be613baf565b90506020020135815481106127d5576127d5613baf565b60009182526020909120600490910201600301805460ff19169115159190911790556001016125b6565b508b8b90508460040160008282546128179190613cc5565b909155505060008a8152600285016020526040812080548d929061283c908490613cc5565b909155505060018401548a0361286b57600384015460ff16156128665760038401805460ff191690555b6128e4565b60018401546000908152600285016020526040808220548c8352912054036128ad57600384015460ff166128665760038401805460ff191660011790556128e4565b60018401546000908152600285016020526040808220548c835291205411156128e457600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161292393929190613f56565b60405180910390a450505050505050505050505050565b6000546001600160a01b031633146129645760405162461bcd60e51b8152600401610a1f90613f14565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106129b4576129b4613baf565b600091825260208083208a84526003600590930201918201905260408220548154919350839181106129e8576129e8613baf565b90600052602060002090600d02016000018781548110612a0a57612a0a613baf565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612a765760405162461bcd60e51b8152600401610a1f90613f86565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612b0185878361401a565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612b58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7c9190613d0f565b612b869190613b63565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612c0f908a908a908a906140da565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612c4557612c45613baf565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612c7957612c79613baf565b90600052602060002090600d02016000018481548110612c9b57612c9b613baf565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ce95760405162461bcd60e51b8152600401610a1f90613f86565b600083815260036020526040902054600280548592908110612d0d57612d0d613baf565b600091825260209091206002600590920201015460ff1615612d415760405162461bcd60e51b8152600401610a1f90613cd8565b600084815260036020526040812054600280549091908110612d6557612d65613baf565b60009182526020822060059091020180549092508290612d8790600190613b63565b81548110612d9757612d97613baf565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190614110565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612e6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e939190613bf1565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b9190614110565b9650612f28848a896132ad565b15612fc557604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c8901909152929092208054909216179055612fca565b600096505b50505050505092915050565b600082815260036020526040812054600280548392908110612ffa57612ffa613baf565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061302e5761302e613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561308d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b19190613c89565b50915091508260040154600014806130e05750801580156130e057506000828152600284016020526040902054155b156130f2576000945050505050613123565b80156131075750506004015491506131239050565b5060009081526002909101602052604090205491506131239050565b92915050565b6000546001600160a01b031633146131535760405162461bcd60e51b8152600401610a1f90613f14565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60036000613181613226565b8054909150600160401b900460ff16806131a8575080546001600160401b03808416911610155b156131c55760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b613252613569565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132aa5760405162461bcd60e51b8152600401610a1f90613f14565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156132fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331f9190613bf1565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa15801561337e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a29190613d0f565b6133ac9190613b63565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156133ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261341591908101906141c0565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134959190614110565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156134ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351091906142a1565b50509150915082816135229190613cc5565b60045490831015955060ff161561355e5784801561355b57506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b613571613590565b61358e57604051631afcd79f60e31b815260040160405180910390fd5b565b600061359a613226565b54600160401b900460ff16919050565b6000602082840312156135bc57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156135fc576135fc6135c3565b60405290565b604051601f8201601f191681016001600160401b038111828210171561362a5761362a6135c3565b604052919050565b600082601f83011261364357600080fd5b81356001600160401b0381111561365c5761365c6135c3565b61366f601f8201601f1916602001613602565b81815284602083860101111561368457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156136b657600080fd5b833592506020840135915060408401356001600160401b038111156136da57600080fd5b6136e686828701613632565b9150509250925092565b6001600160a01b03811681146132aa57600080fd5b6000806000806080858703121561371b57600080fd5b84359350602085013561372d816136f0565b93969395505050506040820135916060013590565b6000806040838503121561375557600080fd5b8235613760816136f0565b91506020830135613770816136f0565b809150509250929050565b6000806040838503121561378e57600080fd5b50508035926020909101359150565b600080604083850312156137b057600080fd5b82356137bb816136f0565b915060208301356001600160401b038111156137d657600080fd5b6137e285828601613632565b9150509250929050565b60005b838110156138075781810151838201526020016137ef565b50506000910152565b600081518084526138288160208601602086016137ec565b601f01601f19169290920160200192915050565b60208152600061384f6020830184613810565b9392505050565b83815282151560208201526060604082015260006107436060830184613810565b60008083601f84011261388957600080fd5b5081356001600160401b038111156138a057600080fd5b6020830191508360208260051b85010111156138bb57600080fd5b9250929050565b600080600080606085870312156138d857600080fd5b8435935060208501356001600160401b038111156138f557600080fd5b61390187828801613877565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561394c57835183529284019291840191600101613930565b50909695505050505050565b600080600080600060a0868803121561397057600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806000606084860312156139a857600080fd5b505081359360208301359350604090920135919050565b6000806000606084860312156139d457600080fd5b83356139df816136f0565b92506020840135915060408401356001600160401b038111156136da57600080fd5b60008060008060008060a08789031215613a1a57600080fd5b8635955060208701356001600160401b0380821115613a3857600080fd5b613a448a838b01613877565b909750955060408901359450606089013593506080890135915080821115613a6b57600080fd5b50613a7889828a01613632565b9150509295509295509295565b600060208284031215613a9757600080fd5b813561384f816136f0565b600080600080600060808688031215613aba57600080fd5b853594506020860135935060408601356001600160401b0380821115613adf57600080fd5b818801915088601f830112613af357600080fd5b813581811115613b0257600080fd5b896020828501011115613b1457600080fd5b96999598505060200195606001359392505050565b60008060408385031215613b3c57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561312357613123613b4d565b808202811582820484141761312357613123613b4d565b600082613baa57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613bdc57600080fd5b919050565b80518015158114613bdc57600080fd5b600080600080600060a08688031215613c0957600080fd5b613c1286613bc5565b94506020860151613c22816136f0565b604087015190945060058110613c3757600080fd5b9250613c4560608701613be1565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613c8057600080fd5b61384f82613be1565b600080600060608486031215613c9e57600080fd5b83519250613cae60208501613be1565b9150613cbc60408501613be1565b90509250925092565b8082018082111561312357613123613b4d565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b600060208284031215613d2157600080fd5b5051919050565b600181811c90821680613d3c57607f821691505b602082108103613d5c57634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613d8381613d28565b8060608701526080600180841660008114613da55760018114613dc157613df1565b60ff19851660808a0152608084151560051b8a01019550613df1565b89600052602060002060005b85811015613de85781548b8201860152908301908801613dcd565b8a016080019650505b50939a9950505050505050505050565b60008251613e138184602087016137ec565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b03831115613e6d57600080fd5b8260051b80836020870137939093016020019392505050565b604081526000613e9a604083018587613e54565b9050826020830152949350505050565b600080600080600080600060e0888a031215613ec557600080fd5b613ece88613bc5565b9650613edc60208901613be1565b955060408801519450606088015193506080880151925060a08801519150613f0660c08901613be1565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000613f6a604083018587613e54565b8281036020840152613f7c8185613810565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f82111561193b576000816000526020600020601f850160051c81016020861015613ff35750805b601f850160051c820191505b8181101561401257828155600101613fff565b505050505050565b6001600160401b03831115614031576140316135c3565b6140458361403f8354613d28565b83613fca565b6000601f84116001811461407957600085156140615750838201355b600019600387901b1c1916600186901b1783556140d3565b600083815260209020601f19861690835b828110156140aa578685013582556020948501946001909201910161408a565b50868210156140c75760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561412257600080fd5b815161384f816136f0565b600082601f83011261413e57600080fd5b815160206001600160401b03821115614159576141596135c3565b8160051b614168828201613602565b928352848101820192828101908785111561418257600080fd5b83870192505b848310156141aa57825161419b816136f0565b82529183019190830190614188565b979650505050505050565b8051613bdc816136f0565b6000602082840312156141d257600080fd5b81516001600160401b03808211156141e957600080fd5b9083019061016082860312156141fe57600080fd5b6142066135d9565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561424e57600080fd5b61425a8782860161412d565b60c08301525060e08381015190820152610100808401519082015261012091506142858284016141b5565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156142b757600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220ebfec9af244a625ba29b828f8582149fa1b92ced62e2f25183243cbccf37668d64736f6c63430008180033", "devdoc": { "errors": { "AlreadyInitialized()": [ @@ -1101,7 +1149,7 @@ } }, "areVotesAllCast(uint256)": { - "details": "Returns true if all of the jurors have cast their votes for the last round.", + "details": "Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.", "params": { "_coreDisputeID": "The ID of the dispute in Kleros Core." }, @@ -1112,7 +1160,7 @@ "castCommit(uint256,uint256[],bytes32)": { "details": "Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.", "params": { - "_commit": "The commit. Note that justification string is a part of the commit.", + "_commit": "The commitment hash.", "_coreDisputeID": "The ID of the dispute in Kleros Core.", "_voteIDs": "The IDs of the votes." } @@ -1208,6 +1256,17 @@ "_0": "The degree of coherence in basis points." } }, + "hashVote(uint256,uint256,string)": { + "details": "Computes the hash of a vote using ABI encodingThe unused parameters may be used by overriding contracts.", + "params": { + "_choice": "The choice being voted for", + "_justification": "The justification for the vote", + "_salt": "A random salt for commitment" + }, + "returns": { + "_0": "bytes32 The hash of the encoded vote parameters" + } + }, "initialize(address,address)": { "details": "Initializer.", "params": { @@ -1215,6 +1274,15 @@ "_governor": "The governor's address." } }, + "isAppealFunded(uint256)": { + "details": "Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.", + "params": { + "_coreDisputeID": "The ID of the dispute in Kleros Core, not in the Dispute Kit." + }, + "returns": { + "_0": "Whether the appeal funding is finished." + } + }, "isVoteActive(uint256,uint256,uint256)": { "details": "Returns true if the specified voter was active in this round.", "params": { @@ -1276,7 +1344,7 @@ "storageLayout": { "storage": [ { - "astId": 19069, + "astId": 3945, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "governor", "offset": 0, @@ -1284,23 +1352,23 @@ "type": "t_address" }, { - "astId": 19072, + "astId": 3948, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "core", "offset": 0, "slot": "1", - "type": "t_contract(KlerosCore)8475" + "type": "t_contract(KlerosCore)165" }, { - "astId": 19076, + "astId": 3952, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "disputes", "offset": 0, "slot": "2", - "type": "t_array(t_struct(Dispute)19004_storage)dyn_storage" + "type": "t_array(t_struct(Dispute)3880_storage)dyn_storage" }, { - "astId": 19080, + "astId": 3956, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "coreDisputeIDToLocal", "offset": 0, @@ -1308,7 +1376,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 19082, + "astId": 3958, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "singleDrawPerJuror", "offset": 0, @@ -1322,20 +1390,20 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_struct(Dispute)19004_storage)dyn_storage": { - "base": "t_struct(Dispute)19004_storage", + "t_array(t_struct(Dispute)3880_storage)dyn_storage": { + "base": "t_struct(Dispute)3880_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Dispute[]", "numberOfBytes": "32" }, - "t_array(t_struct(Round)19046_storage)dyn_storage": { - "base": "t_struct(Round)19046_storage", + "t_array(t_struct(Round)3922_storage)dyn_storage": { + "base": "t_struct(Round)3922_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Round[]", "numberOfBytes": "32" }, - "t_array(t_struct(Vote)19055_storage)dyn_storage": { - "base": "t_struct(Vote)19055_storage", + "t_array(t_struct(Vote)3931_storage)dyn_storage": { + "base": "t_struct(Vote)3931_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Vote[]", "numberOfBytes": "32" @@ -1361,7 +1429,7 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_contract(KlerosCore)8475": { + "t_contract(KlerosCore)165": { "encoding": "inplace", "label": "contract KlerosCore", "numberOfBytes": "20" @@ -1394,20 +1462,20 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Dispute)19004_storage": { + "t_struct(Dispute)3880_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Dispute", "members": [ { - "astId": 18993, + "astId": 3869, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "rounds", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Round)19046_storage)dyn_storage" + "type": "t_array(t_struct(Round)3922_storage)dyn_storage" }, { - "astId": 18995, + "astId": 3871, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "numberOfChoices", "offset": 0, @@ -1415,7 +1483,7 @@ "type": "t_uint256" }, { - "astId": 18997, + "astId": 3873, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "jumped", "offset": 0, @@ -1423,7 +1491,7 @@ "type": "t_bool" }, { - "astId": 19001, + "astId": 3877, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "coreRoundIDToLocal", "offset": 0, @@ -1431,7 +1499,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 19003, + "astId": 3879, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "extraData", "offset": 0, @@ -1441,20 +1509,20 @@ ], "numberOfBytes": "160" }, - "t_struct(Round)19046_storage": { + "t_struct(Round)3922_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Round", "members": [ { - "astId": 19008, + "astId": 3884, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "votes", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Vote)19055_storage)dyn_storage" + "type": "t_array(t_struct(Vote)3931_storage)dyn_storage" }, { - "astId": 19010, + "astId": 3886, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "winningChoice", "offset": 0, @@ -1462,7 +1530,7 @@ "type": "t_uint256" }, { - "astId": 19014, + "astId": 3890, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "counts", "offset": 0, @@ -1470,7 +1538,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 19016, + "astId": 3892, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "tied", "offset": 0, @@ -1478,7 +1546,7 @@ "type": "t_bool" }, { - "astId": 19018, + "astId": 3894, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "totalVoted", "offset": 0, @@ -1486,7 +1554,7 @@ "type": "t_uint256" }, { - "astId": 19020, + "astId": 3896, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "totalCommitted", "offset": 0, @@ -1494,7 +1562,7 @@ "type": "t_uint256" }, { - "astId": 19024, + "astId": 3900, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "paidFees", "offset": 0, @@ -1502,7 +1570,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 19028, + "astId": 3904, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "hasPaid", "offset": 0, @@ -1510,7 +1578,7 @@ "type": "t_mapping(t_uint256,t_bool)" }, { - "astId": 19034, + "astId": 3910, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "contributions", "offset": 0, @@ -1518,7 +1586,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 19036, + "astId": 3912, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "feeRewards", "offset": 0, @@ -1526,7 +1594,7 @@ "type": "t_uint256" }, { - "astId": 19039, + "astId": 3915, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "fundedChoices", "offset": 0, @@ -1534,7 +1602,7 @@ "type": "t_array(t_uint256)dyn_storage" }, { - "astId": 19041, + "astId": 3917, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "nbVotes", "offset": 0, @@ -1542,7 +1610,7 @@ "type": "t_uint256" }, { - "astId": 19045, + "astId": 3921, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "alreadyDrawn", "offset": 0, @@ -1552,12 +1620,12 @@ ], "numberOfBytes": "416" }, - "t_struct(Vote)19055_storage": { + "t_struct(Vote)3931_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Vote", "members": [ { - "astId": 19048, + "astId": 3924, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "account", "offset": 0, @@ -1565,7 +1633,7 @@ "type": "t_address" }, { - "astId": 19050, + "astId": 3926, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "commit", "offset": 0, @@ -1573,7 +1641,7 @@ "type": "t_bytes32" }, { - "astId": 19052, + "astId": 3928, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "choice", "offset": 0, @@ -1581,7 +1649,7 @@ "type": "t_uint256" }, { - "astId": 19054, + "astId": 3930, "contract": "src/arbitration/dispute-kits/DisputeKitClassic.sol:DisputeKitClassic", "label": "voted", "offset": 0, diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol index 97dfcd2ba..6bfb26467 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol @@ -29,7 +29,7 @@ contract DisputeKitClassic is DisputeKitClassicBase { __DisputeKitClassicBase_initialize(_governor, _core); } - function initialize2() external reinitializer(2) { + function initialize3() external reinitializer(3) { // NOP } From cb7997f2debfb1bfb6509bde2d613f1f684ebae2 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 1 May 2025 02:05:38 +0100 Subject: [PATCH 16/26] fix: external call to castCommit() changes msg.sender, fixed by extracting an internal function --- contracts/README.md | 4 +- ...0.9.0.ts => upgrade-dispute-kit-v0.9.2.ts} | 2 +- .../DisputeKitClassic.json | 8 +- .../DisputeKitClassic_Implementation.json | 44 +++---- .../DisputeKitShutter.json | 8 +- .../DisputeKitShutter_Implementation.json | 116 +++++++++--------- .../dispute-kits/DisputeKitClassic.sol | 4 +- .../dispute-kits/DisputeKitClassicBase.sol | 20 ++- .../dispute-kits/DisputeKitGated.sol | 2 +- .../dispute-kits/DisputeKitShutter.sol | 6 +- .../dispute-kits/DisputeKitSybilResistant.sol | 2 +- 11 files changed, 115 insertions(+), 101 deletions(-) rename contracts/deploy/{upgrade-dispute-kit-v0.9.0.ts => upgrade-dispute-kit-v0.9.2.ts} (98%) diff --git a/contracts/README.md b/contracts/README.md index 56751df04..496e7d769 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -77,9 +77,9 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [ChainlinkRNG](https://sepolia.arbiscan.io/address/0x6c40D7F5d5bE3492fe9EF70e4eCb2BD773c12AF8) - [DAI](https://sepolia.arbiscan.io/address/0x593e89704D285B0c3fbF157c7CF2537456CE64b5) - [DAIFaucet](https://sepolia.arbiscan.io/address/0xB5b39A1bcD2D7097A8824B3cC18Ebd2dFb0D9B5E) -- [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x2246821E1313A93e2F8CdF7a3422d078f560b457), [implementation](https://sepolia.arbiscan.io/address/0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F) +- [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x2246821E1313A93e2F8CdF7a3422d078f560b457), [implementation](https://sepolia.arbiscan.io/address/0x0B3E35C1b5E1C33b3A8722F3B697dF8ff8c1068a) - [DisputeKitClassicUniversity: proxy](https://sepolia.arbiscan.io/address/0xd6E96b7c993763B5CDDa1139C7387B82A7c8B8B5), [implementation](https://sepolia.arbiscan.io/address/0x87e863b94d2CB79A8aB53bD87Dc4A10E11C0918B) -- [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1) +- [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD) - [DisputeResolver](https://sepolia.arbiscan.io/address/0x524C5541f440204E0B4577334c439277018F971f) - [DisputeResolverRuler](https://sepolia.arbiscan.io/address/0x199893232ECC74cC7898B24b5Ff58d613029f6B7) - [DisputeResolverUniversity](https://sepolia.arbiscan.io/address/0x2Aa1a94307E772BeE42E9EfbD137b1053F1fCfd4) diff --git a/contracts/deploy/upgrade-dispute-kit-v0.9.0.ts b/contracts/deploy/upgrade-dispute-kit-v0.9.2.ts similarity index 98% rename from contracts/deploy/upgrade-dispute-kit-v0.9.0.ts rename to contracts/deploy/upgrade-dispute-kit-v0.9.2.ts index 4d1f8c690..a2e994b1b 100644 --- a/contracts/deploy/upgrade-dispute-kit-v0.9.0.ts +++ b/contracts/deploy/upgrade-dispute-kit-v0.9.2.ts @@ -33,7 +33,7 @@ const deployUpgradeDisputeKit: DeployFunction = async (hre: HardhatRuntimeEnviro print.info(`Upgrading ${contractName}...`); await deployUpgradable(deployments, contractName, { contract: contractName, - initializer: "initialize3", + initializer: "initialize4", from: deployer, // Warning: do not reinitialize everything, only the new variables args: [], diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json index afdca97a7..1c242d81a 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json @@ -866,7 +866,7 @@ }, { "inputs": [], - "name": "initialize3", + "name": "initialize4", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1060,16 +1060,16 @@ "0xc51Ac08b07832Cf9b51Ff9E9dd3E85a3D205ff24", "0x485cc955000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c590000000000000000000000000000000000000000000000000000000000000000" ], - "numDeployments": 2, + "numDeployments": 3, "solcInputHash": "96b8e3f55478438b6784f67c1730309e", "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitClassicProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitShutterProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x209228b56d42a8444ca70919e1ded5711fba434a746f26d426e230f57526fc6c\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122031995e44df4f8c0f7e14fc8c92fe3e63c4fcc994a0505b92eecf1c3a7b742d8964736f6c63430008180033", "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122031995e44df4f8c0f7e14fc8c92fe3e63c4fcc994a0505b92eecf1c3a7b742d8964736f6c63430008180033", "execute": { - "methodName": "initialize3", + "methodName": "initialize4", "args": [] }, - "implementation": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", + "implementation": "0x0B3E35C1b5E1C33b3A8722F3B697dF8ff8c1068a", "devdoc": { "kind": "dev", "methods": {}, diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json index c2fe8da64..910c9c669 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", + "address": "0x0B3E35C1b5E1C33b3A8722F3B697dF8ff8c1068a", "abi": [ { "inputs": [], @@ -863,7 +863,7 @@ }, { "inputs": [], - "name": "initialize3", + "name": "initialize4", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1008,41 +1008,41 @@ "type": "function" } ], - "transactionHash": "0x872759bf7163de8e17b5902b8d4eac663bad5c2382ce1fe2e0b50b2253edc8e6", + "transactionHash": "0x27249b52eadf9c3c403bd4b19ed256c89b81ab04fc1ef38f8ca2c11c664e44aa", "receipt": { "to": null, "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", - "contractAddress": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", - "transactionIndex": 1, - "gasUsed": "3987213", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000020000000000000000000000000000000004000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xfc72feaadd04b77c141f55e20764b997e1151bce222a8ab03093a06d74fd06c4", - "transactionHash": "0x872759bf7163de8e17b5902b8d4eac663bad5c2382ce1fe2e0b50b2253edc8e6", + "contractAddress": "0x0B3E35C1b5E1C33b3A8722F3B697dF8ff8c1068a", + "transactionIndex": 3, + "gasUsed": "3822753", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000040000000000000000000000", + "blockHash": "0x7c355273102c312de8ccd775377cc0e27b8e50dfa01ce5a0278df7f1ad17f10e", + "transactionHash": "0x27249b52eadf9c3c403bd4b19ed256c89b81ab04fc1ef38f8ca2c11c664e44aa", "logs": [ { - "transactionIndex": 1, - "blockNumber": 148207322, - "transactionHash": "0x872759bf7163de8e17b5902b8d4eac663bad5c2382ce1fe2e0b50b2253edc8e6", - "address": "0x6dE044A2967BfD1786f1919fD6442639Ef5cc86F", + "transactionIndex": 3, + "blockNumber": 148225879, + "transactionHash": "0x27249b52eadf9c3c403bd4b19ed256c89b81ab04fc1ef38f8ca2c11c664e44aa", + "address": "0x0B3E35C1b5E1C33b3A8722F3B697dF8ff8c1068a", "topics": [ "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" ], "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", - "logIndex": 0, - "blockHash": "0xfc72feaadd04b77c141f55e20764b997e1151bce222a8ab03093a06d74fd06c4" + "logIndex": 16, + "blockHash": "0x7c355273102c312de8ccd775377cc0e27b8e50dfa01ce5a0278df7f1ad17f10e" } ], - "blockNumber": 148207322, - "cumulativeGasUsed": "3987213", + "blockNumber": 148225879, + "cumulativeGasUsed": "4342817", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "1476c8f3428345b8e6ba7181b9df7adb", - "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize3\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encodingThe unused parameters may be used by overriding contracts.\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitClassic Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":\"DisputeKitClassic\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitClassic\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\ncontract DisputeKitClassic is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0xcd903598b64f06e569320faf8548c240fe182b68a46515327bfea4d9fc662e6d\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbf209306f450437b609837aab267810dcf8311442ed28abb32ad5d62ed43bd9b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161432d620001036000396000818161172c01528181611755015261194d015261432d6000f3fe6080604052600436106101b95760003560e01c806369f3f041116100ed578063b6ede54011610090578063b6ede54014610599578063ba66fde7146105b9578063be467604146105d9578063d2b8035a146105ef578063da3beb8c1461060f578063e349ad30146104e1578063e4c0aaf41461062f578063ec918b651461064f578063f2f4eb261461066457600080fd5b806369f3f041146104545780636d4cd8ea146104a1578063751accd0146104c1578063796490f9146104e15780637c04034e146104f75780638e42646014610517578063a7cc08fe14610537578063b34bfaa81461058357600080fd5b8063485cc95511610160578063485cc9551461031d5780634b2f0ea01461033f5780634f1ef2861461035257806352d1902d1461036557806354fd4d501461037a578063564a565d146103b85780635c92e2f6146103e757806365540b9614610407578063675926f61461043457600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e3578063362c3479146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d93660046135aa565b610684565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e3660046135aa565b61074c565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b506102786102663660046135aa565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a13660046135aa565b6107c3565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de3660046136a1565b610931565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b50610278610318366004613705565b61095e565b34801561032957600080fd5b5061033d610338366004613742565b610de9565b005b61033d61034d36600461377b565b610eb1565b61033d61036036600461379d565b611718565b34801561037157600080fd5b50610278611940565b34801561038657600080fd5b506103ab604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea919061383c565b3480156103c457600080fd5b506103d86103d33660046135aa565b61199e565b6040516101ea93929190613856565b3480156103f357600080fd5b5061033d6104023660046138c2565b611a64565b34801561041357600080fd5b506104276104223660046135aa565b611d69565b6040516101ea9190613914565b34801561044057600080fd5b5061027861044f366004613958565b611e2d565b34801561046057600080fd5b5061047461046f366004613993565b611f70565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104ad57600080fd5b506101de6104bc3660046135aa565b612028565b3480156104cd57600080fd5b5061033d6104dc3660046139bf565b6121ab565b3480156104ed57600080fd5b5061027861271081565b34801561050357600080fd5b5061033d610512366004613a01565b612277565b34801561052357600080fd5b5061033d610532366004613a85565b61293a565b34801561054357600080fd5b50610557610552366004613993565b612986565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b34801561058f57600080fd5b50610278614e2081565b3480156105a557600080fd5b5061033d6105b4366004613aa2565b612a4c565b3480156105c557600080fd5b506101de6105d4366004613993565b612c21565b3480156105e557600080fd5b5061027861138881565b3480156105fb57600080fd5b5061023361060a36600461377b565b612cbc565b34801561061b57600080fd5b5061027861062a36600461377b565b612fd6565b34801561063b57600080fd5b5061033d61064a366004613a85565b613129565b34801561065b57600080fd5b5061033d613175565b34801561067057600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f59190613b29565b91509150600061070485611d69565b90508051600014801561074357506127106113886107228585613b63565b61072c9190613b76565b6107369190613b8d565b6107408442613b63565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077057610770613baf565b6000918252602082206005909102018054909250829061079290600190613b63565b815481106107a2576107a2613baf565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107ef576107ef613baf565b6000918252602082206005909102018054909250829061081190600190613b63565b8154811061082157610821613baf565b60009182526020909120600d90910201600381015460ff16945090508361084c57806001015461084f565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c29190613bf1565b50909350600492506108d2915050565b8160048111156108e4576108e4613c58565b036109275760006108f488611d69565b90508051600103610925578060008151811061091257610912613baf565b6020026020010151965060009550600194505b505b5050509193909250565b50604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d09190613bf1565b50935050505080610a285760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190613c6e565b15610add5760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b6044820152606401610a1f565b600086815260036020526040812054600280549091908110610b0157610b01613baf565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610b3557610b35613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190613c89565b5050600087815260078401602052604090205490915060ff16610bfe576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610d43565b808603610c73576000868152600683016020526040902054610c21576000610c6c565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610c629190613b76565b610c6c9190613b8d565b9450610d43565b600081815260078301602052604090205460ff16610d435781600601600083600a01600181548110610ca757610ca7613baf565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610cdd57610cdd613baf565b9060005260206000200154815260200190815260200160002054610d019190613cc5565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610d369190613b76565b610d409190613b8d565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ddd576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610df5613226565b8054909150600160401b900460ff1680610e1c575080546001600160401b03808416911610155b15610e395760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610e64848461324a565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610ed557610ed5613baf565b600091825260209091206002600590920201015460ff1615610f095760405162461bcd60e51b8152600401610a1f90613cd8565b600083815260036020526040812054600280549091908110610f2d57610f2d613baf565b906000526020600020906005020190508060010154831115610f915760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610a1f565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110029190613b29565b9150915081421015801561101557508042105b61105a5760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610a1f565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613c89565b505090508681036110d4576127109150611155565b6127106113886110e48686613b63565b6110ee9190613b76565b6110f89190613b8d565b6111028542613b63565b1061114f5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610a1f565b614e2091505b8454600090869061116890600190613b63565b8154811061117857611178613baf565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190613d0f565b6112059190613b63565b60008a815260078401602052604090205490915060ff16156112695760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610a1f565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d79190613d0f565b905060006127106112e88784613b76565b6112f29190613b8d565b6112fc9083613cc5565b60008c8152600686016020526040812054919250908211156113ad5760008c815260068601602052604090205434906113359084613b63565b1161135a5760008c81526006860160205260409020546113559083613b63565b61135c565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516113a4929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906113d9908490613cc5565b909155505060008c8152600686016020526040812080548392906113fe908490613cc5565b909155505060008c815260068601602052604090205482116114d05760008c815260068601602052604081205460098701805491929091611440908490613cc5565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116db578285600901546114ed9190613b63565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190613c6e565b156115785760028a01805460ff1916600117905561165b565b895460038b01600061158b876001613cc5565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161160691815260200190565b602060405180830381865afa158015611623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116479190613d0f565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016116a893929190613d62565b6000604051808303818588803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b50505050505b8034111561170957336108fc6116f18334613b63565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61172182613280565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061179f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166117936000805160206142d88339815191525490565b6001600160a01b031614155b156117bd5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611817575060408051601f3d908101601f1916820190925261181491810190613d0f565b60015b61183f57604051630c76093760e01b81526001600160a01b0383166004820152602401610a1f565b6000805160206142d8833981519152811461187057604051632a87526960e21b815260048101829052602401610a1f565b6000805160206142d88339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a281511561193b576000836001600160a01b0316836040516118d79190613e01565b600060405180830381855af49150503d8060008114611912576040519150601f19603f3d011682016040523d82523d6000602084013e611917565b606091505b5050905080611939576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461198b5760405163703e46dd60e11b815260040160405180910390fd5b506000805160206142d883398151915290565b600281815481106119ae57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916119e190613d28565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0d90613d28565b8015611a5a5780601f10611a2f57610100808354040283529160200191611a5a565b820191906000526020600020905b815481529060010190602001808311611a3d57829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611a8857611a88613baf565b600091825260209091206002600590920201015460ff1615611abc5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611b06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2a9190613bf1565b5090935060019250611b3a915050565b816004811115611b4c57611b4c613c58565b14611ba95760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610a1f565b82611be65760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610a1f565b600086815260036020526040812054600280549091908110611c0a57611c0a613baf565b60009182526020822060059091020180549092508290611c2c90600190613b63565b81548110611c3c57611c3c613baf565b90600052602060002090600d0201905060005b86811015611d02573382898984818110611c6b57611c6b613baf565b9050602002013581548110611c8257611c82613baf565b60009182526020909120600490910201546001600160a01b031614611cb95760405162461bcd60e51b8152600401610a1f90613e1d565b8582898984818110611ccd57611ccd613baf565b9050602002013581548110611ce457611ce4613baf565b60009182526020909120600160049092020181019190915501611c4f565b5086869050816005016000828254611d1a9190613cc5565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611d57908b908b908b90613e86565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611d8f57611d8f613baf565b60009182526020822060059091020180549092508290611db190600190613b63565b81548110611dc157611dc1613baf565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611e1f57602002820191906000526020600020905b815481526020019060010190808311611e0b575b505050505092505050919050565b600085815260036020526040812054600280548392908110611e5157611e51613baf565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611e8557611e85613baf565b90600052602060002090600d02016000018681548110611ea757611ea7613baf565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190613c89565b506003850154919350915060ff168015611f4d57508183600201541480611f4d5750805b15611f6057612710945050505050610743565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611fa157611fa1613baf565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611fd557611fd5613baf565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061204c5761204c613baf565b6000918252602082206005909102018054909250829061206e90600190613b63565b8154811061207e5761207e613baf565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fd9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c9190613eaa565b5050505050915050600081612192578354612198565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146121d55760405162461bcd60e51b8152600401610a1f90613f14565b6000836001600160a01b031683836040516121f09190613e01565b60006040518083038185875af1925050503d806000811461222d576040519150601f19603f3d011682016040523d82523d6000602084013e612232565b606091505b50509050806119395760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610a1f565b60008681526003602052604090205460028054889290811061229b5761229b613baf565b600091825260209091206002600590920201015460ff16156122cf5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613bf1565b509093506002925061234d915050565b81600481111561235f5761235f613c58565b146123ba5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610a1f565b856123fc5760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610a1f565b60008881526003602052604081205460028054909190811061242057612420613baf565b90600052602060002090600502019050806001015486111561247b5760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610a1f565b8054600090829061248e90600190613b63565b8154811061249e5761249e613baf565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612578573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259c9190613eaa565b505050505091505060006125b18a8a8a610931565b905060005b8b8110156127ff5733858e8e848181106125d2576125d2613baf565b90506020020135815481106125e9576125e9613baf565b60009182526020909120600490910201546001600160a01b0316146126205760405162461bcd60e51b8152600401610a1f90613e1d565b821580612667575081858e8e8481811061263c5761263c613baf565b905060200201358154811061265357612653613baf565b906000526020600020906004020160010154145b6126e75760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a401610a1f565b848d8d838181106126fa576126fa613baf565b905060200201358154811061271157612711613baf565b600091825260209091206003600490920201015460ff161561276a5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610a1f565b8a858e8e8481811061277e5761277e613baf565b905060200201358154811061279557612795613baf565b60009182526020909120600260049092020101556001858e8e848181106127be576127be613baf565b90506020020135815481106127d5576127d5613baf565b60009182526020909120600490910201600301805460ff19169115159190911790556001016125b6565b508b8b90508460040160008282546128179190613cc5565b909155505060008a8152600285016020526040812080548d929061283c908490613cc5565b909155505060018401548a0361286b57600384015460ff16156128665760038401805460ff191690555b6128e4565b60018401546000908152600285016020526040808220548c8352912054036128ad57600384015460ff166128665760038401805460ff191660011790556128e4565b60018401546000908152600285016020526040808220548c835291205411156128e457600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161292393929190613f56565b60405180910390a450505050505050505050505050565b6000546001600160a01b031633146129645760405162461bcd60e51b8152600401610a1f90613f14565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106129b4576129b4613baf565b600091825260208083208a84526003600590930201918201905260408220548154919350839181106129e8576129e8613baf565b90600052602060002090600d02016000018781548110612a0a57612a0a613baf565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612a765760405162461bcd60e51b8152600401610a1f90613f86565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612b0185878361401a565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612b58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7c9190613d0f565b612b869190613b63565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612c0f908a908a908a906140da565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612c4557612c45613baf565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612c7957612c79613baf565b90600052602060002090600d02016000018481548110612c9b57612c9b613baf565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ce95760405162461bcd60e51b8152600401610a1f90613f86565b600083815260036020526040902054600280548592908110612d0d57612d0d613baf565b600091825260209091206002600590920201015460ff1615612d415760405162461bcd60e51b8152600401610a1f90613cd8565b600084815260036020526040812054600280549091908110612d6557612d65613baf565b60009182526020822060059091020180549092508290612d8790600190613b63565b81548110612d9757612d97613baf565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190614110565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612e6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e939190613bf1565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b9190614110565b9650612f28848a896132ad565b15612fc557604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c8901909152929092208054909216179055612fca565b600096505b50505050505092915050565b600082815260036020526040812054600280548392908110612ffa57612ffa613baf565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061302e5761302e613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561308d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b19190613c89565b50915091508260040154600014806130e05750801580156130e057506000828152600284016020526040902054155b156130f2576000945050505050613123565b80156131075750506004015491506131239050565b5060009081526002909101602052604090205491506131239050565b92915050565b6000546001600160a01b031633146131535760405162461bcd60e51b8152600401610a1f90613f14565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60036000613181613226565b8054909150600160401b900460ff16806131a8575080546001600160401b03808416911610155b156131c55760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b613252613569565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132aa5760405162461bcd60e51b8152600401610a1f90613f14565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156132fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331f9190613bf1565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa15801561337e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a29190613d0f565b6133ac9190613b63565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156133ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261341591908101906141c0565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134959190614110565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156134ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351091906142a1565b50509150915082816135229190613cc5565b60045490831015955060ff161561355e5784801561355b57506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b613571613590565b61358e57604051631afcd79f60e31b815260040160405180910390fd5b565b600061359a613226565b54600160401b900460ff16919050565b6000602082840312156135bc57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156135fc576135fc6135c3565b60405290565b604051601f8201601f191681016001600160401b038111828210171561362a5761362a6135c3565b604052919050565b600082601f83011261364357600080fd5b81356001600160401b0381111561365c5761365c6135c3565b61366f601f8201601f1916602001613602565b81815284602083860101111561368457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156136b657600080fd5b833592506020840135915060408401356001600160401b038111156136da57600080fd5b6136e686828701613632565b9150509250925092565b6001600160a01b03811681146132aa57600080fd5b6000806000806080858703121561371b57600080fd5b84359350602085013561372d816136f0565b93969395505050506040820135916060013590565b6000806040838503121561375557600080fd5b8235613760816136f0565b91506020830135613770816136f0565b809150509250929050565b6000806040838503121561378e57600080fd5b50508035926020909101359150565b600080604083850312156137b057600080fd5b82356137bb816136f0565b915060208301356001600160401b038111156137d657600080fd5b6137e285828601613632565b9150509250929050565b60005b838110156138075781810151838201526020016137ef565b50506000910152565b600081518084526138288160208601602086016137ec565b601f01601f19169290920160200192915050565b60208152600061384f6020830184613810565b9392505050565b83815282151560208201526060604082015260006107436060830184613810565b60008083601f84011261388957600080fd5b5081356001600160401b038111156138a057600080fd5b6020830191508360208260051b85010111156138bb57600080fd5b9250929050565b600080600080606085870312156138d857600080fd5b8435935060208501356001600160401b038111156138f557600080fd5b61390187828801613877565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561394c57835183529284019291840191600101613930565b50909695505050505050565b600080600080600060a0868803121561397057600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806000606084860312156139a857600080fd5b505081359360208301359350604090920135919050565b6000806000606084860312156139d457600080fd5b83356139df816136f0565b92506020840135915060408401356001600160401b038111156136da57600080fd5b60008060008060008060a08789031215613a1a57600080fd5b8635955060208701356001600160401b0380821115613a3857600080fd5b613a448a838b01613877565b909750955060408901359450606089013593506080890135915080821115613a6b57600080fd5b50613a7889828a01613632565b9150509295509295509295565b600060208284031215613a9757600080fd5b813561384f816136f0565b600080600080600060808688031215613aba57600080fd5b853594506020860135935060408601356001600160401b0380821115613adf57600080fd5b818801915088601f830112613af357600080fd5b813581811115613b0257600080fd5b896020828501011115613b1457600080fd5b96999598505060200195606001359392505050565b60008060408385031215613b3c57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561312357613123613b4d565b808202811582820484141761312357613123613b4d565b600082613baa57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613bdc57600080fd5b919050565b80518015158114613bdc57600080fd5b600080600080600060a08688031215613c0957600080fd5b613c1286613bc5565b94506020860151613c22816136f0565b604087015190945060058110613c3757600080fd5b9250613c4560608701613be1565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613c8057600080fd5b61384f82613be1565b600080600060608486031215613c9e57600080fd5b83519250613cae60208501613be1565b9150613cbc60408501613be1565b90509250925092565b8082018082111561312357613123613b4d565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b600060208284031215613d2157600080fd5b5051919050565b600181811c90821680613d3c57607f821691505b602082108103613d5c57634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613d8381613d28565b8060608701526080600180841660008114613da55760018114613dc157613df1565b60ff19851660808a0152608084151560051b8a01019550613df1565b89600052602060002060005b85811015613de85781548b8201860152908301908801613dcd565b8a016080019650505b50939a9950505050505050505050565b60008251613e138184602087016137ec565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b03831115613e6d57600080fd5b8260051b80836020870137939093016020019392505050565b604081526000613e9a604083018587613e54565b9050826020830152949350505050565b600080600080600080600060e0888a031215613ec557600080fd5b613ece88613bc5565b9650613edc60208901613be1565b955060408801519450606088015193506080880151925060a08801519150613f0660c08901613be1565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000613f6a604083018587613e54565b8281036020840152613f7c8185613810565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f82111561193b576000816000526020600020601f850160051c81016020861015613ff35750805b601f850160051c820191505b8181101561401257828155600101613fff565b505050505050565b6001600160401b03831115614031576140316135c3565b6140458361403f8354613d28565b83613fca565b6000601f84116001811461407957600085156140615750838201355b600019600387901b1c1916600186901b1783556140d3565b600083815260209020601f19861690835b828110156140aa578685013582556020948501946001909201910161408a565b50868210156140c75760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561412257600080fd5b815161384f816136f0565b600082601f83011261413e57600080fd5b815160206001600160401b03821115614159576141596135c3565b8160051b614168828201613602565b928352848101820192828101908785111561418257600080fd5b83870192505b848310156141aa57825161419b816136f0565b82529183019190830190614188565b979650505050505050565b8051613bdc816136f0565b6000602082840312156141d257600080fd5b81516001600160401b03808211156141e957600080fd5b9083019061016082860312156141fe57600080fd5b6142066135d9565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561424e57600080fd5b61425a8782860161412d565b60c08301525060e08381015190820152610100808401519082015261012091506142858284016141b5565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156142b757600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220ebfec9af244a625ba29b828f8582149fa1b92ced62e2f25183243cbccf37668d64736f6c63430008180033", - "deployedBytecode": "0x6080604052600436106101b95760003560e01c806369f3f041116100ed578063b6ede54011610090578063b6ede54014610599578063ba66fde7146105b9578063be467604146105d9578063d2b8035a146105ef578063da3beb8c1461060f578063e349ad30146104e1578063e4c0aaf41461062f578063ec918b651461064f578063f2f4eb261461066457600080fd5b806369f3f041146104545780636d4cd8ea146104a1578063751accd0146104c1578063796490f9146104e15780637c04034e146104f75780638e42646014610517578063a7cc08fe14610537578063b34bfaa81461058357600080fd5b8063485cc95511610160578063485cc9551461031d5780634b2f0ea01461033f5780634f1ef2861461035257806352d1902d1461036557806354fd4d501461037a578063564a565d146103b85780635c92e2f6146103e757806365540b9614610407578063675926f61461043457600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e3578063362c3479146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d93660046135aa565b610684565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e3660046135aa565b61074c565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b506102786102663660046135aa565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a13660046135aa565b6107c3565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de3660046136a1565b610931565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b50610278610318366004613705565b61095e565b34801561032957600080fd5b5061033d610338366004613742565b610de9565b005b61033d61034d36600461377b565b610eb1565b61033d61036036600461379d565b611718565b34801561037157600080fd5b50610278611940565b34801561038657600080fd5b506103ab604051806040016040528060058152602001640302e392e360dc1b81525081565b6040516101ea919061383c565b3480156103c457600080fd5b506103d86103d33660046135aa565b61199e565b6040516101ea93929190613856565b3480156103f357600080fd5b5061033d6104023660046138c2565b611a64565b34801561041357600080fd5b506104276104223660046135aa565b611d69565b6040516101ea9190613914565b34801561044057600080fd5b5061027861044f366004613958565b611e2d565b34801561046057600080fd5b5061047461046f366004613993565b611f70565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104ad57600080fd5b506101de6104bc3660046135aa565b612028565b3480156104cd57600080fd5b5061033d6104dc3660046139bf565b6121ab565b3480156104ed57600080fd5b5061027861271081565b34801561050357600080fd5b5061033d610512366004613a01565b612277565b34801561052357600080fd5b5061033d610532366004613a85565b61293a565b34801561054357600080fd5b50610557610552366004613993565b612986565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b34801561058f57600080fd5b50610278614e2081565b3480156105a557600080fd5b5061033d6105b4366004613aa2565b612a4c565b3480156105c557600080fd5b506101de6105d4366004613993565b612c21565b3480156105e557600080fd5b5061027861138881565b3480156105fb57600080fd5b5061023361060a36600461377b565b612cbc565b34801561061b57600080fd5b5061027861062a36600461377b565b612fd6565b34801561063b57600080fd5b5061033d61064a366004613a85565b613129565b34801561065b57600080fd5b5061033d613175565b34801561067057600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f59190613b29565b91509150600061070485611d69565b90508051600014801561074357506127106113886107228585613b63565b61072c9190613b76565b6107369190613b8d565b6107408442613b63565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077057610770613baf565b6000918252602082206005909102018054909250829061079290600190613b63565b815481106107a2576107a2613baf565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107ef576107ef613baf565b6000918252602082206005909102018054909250829061081190600190613b63565b8154811061082157610821613baf565b60009182526020909120600d90910201600381015460ff16945090508361084c57806001015461084f565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c29190613bf1565b50909350600492506108d2915050565b8160048111156108e4576108e4613c58565b036109275760006108f488611d69565b90508051600103610925578060008151811061091257610912613baf565b6020026020010151965060009550600194505b505b5050509193909250565b50604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d09190613bf1565b50935050505080610a285760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190613c6e565b15610add5760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b6044820152606401610a1f565b600086815260036020526040812054600280549091908110610b0157610b01613baf565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610b3557610b35613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190613c89565b5050600087815260078401602052604090205490915060ff16610bfe576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610d43565b808603610c73576000868152600683016020526040902054610c21576000610c6c565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610c629190613b76565b610c6c9190613b8d565b9450610d43565b600081815260078301602052604090205460ff16610d435781600601600083600a01600181548110610ca757610ca7613baf565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610cdd57610cdd613baf565b9060005260206000200154815260200190815260200160002054610d019190613cc5565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610d369190613b76565b610d409190613b8d565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ddd576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610df5613226565b8054909150600160401b900460ff1680610e1c575080546001600160401b03808416911610155b15610e395760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610e64848461324a565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610ed557610ed5613baf565b600091825260209091206002600590920201015460ff1615610f095760405162461bcd60e51b8152600401610a1f90613cd8565b600083815260036020526040812054600280549091908110610f2d57610f2d613baf565b906000526020600020906005020190508060010154831115610f915760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610a1f565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110029190613b29565b9150915081421015801561101557508042105b61105a5760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610a1f565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613c89565b505090508681036110d4576127109150611155565b6127106113886110e48686613b63565b6110ee9190613b76565b6110f89190613b8d565b6111028542613b63565b1061114f5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610a1f565b614e2091505b8454600090869061116890600190613b63565b8154811061117857611178613baf565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190613d0f565b6112059190613b63565b60008a815260078401602052604090205490915060ff16156112695760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610a1f565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d79190613d0f565b905060006127106112e88784613b76565b6112f29190613b8d565b6112fc9083613cc5565b60008c8152600686016020526040812054919250908211156113ad5760008c815260068601602052604090205434906113359084613b63565b1161135a5760008c81526006860160205260409020546113559083613b63565b61135c565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516113a4929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906113d9908490613cc5565b909155505060008c8152600686016020526040812080548392906113fe908490613cc5565b909155505060008c815260068601602052604090205482116114d05760008c815260068601602052604081205460098701805491929091611440908490613cc5565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116db578285600901546114ed9190613b63565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190613c6e565b156115785760028a01805460ff1916600117905561165b565b895460038b01600061158b876001613cc5565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161160691815260200190565b602060405180830381865afa158015611623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116479190613d0f565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016116a893929190613d62565b6000604051808303818588803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b50505050505b8034111561170957336108fc6116f18334613b63565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61172182613280565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061179f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166117936000805160206142d88339815191525490565b6001600160a01b031614155b156117bd5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611817575060408051601f3d908101601f1916820190925261181491810190613d0f565b60015b61183f57604051630c76093760e01b81526001600160a01b0383166004820152602401610a1f565b6000805160206142d8833981519152811461187057604051632a87526960e21b815260048101829052602401610a1f565b6000805160206142d88339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a281511561193b576000836001600160a01b0316836040516118d79190613e01565b600060405180830381855af49150503d8060008114611912576040519150601f19603f3d011682016040523d82523d6000602084013e611917565b606091505b5050905080611939576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461198b5760405163703e46dd60e11b815260040160405180910390fd5b506000805160206142d883398151915290565b600281815481106119ae57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916119e190613d28565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0d90613d28565b8015611a5a5780601f10611a2f57610100808354040283529160200191611a5a565b820191906000526020600020905b815481529060010190602001808311611a3d57829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611a8857611a88613baf565b600091825260209091206002600590920201015460ff1615611abc5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611b06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2a9190613bf1565b5090935060019250611b3a915050565b816004811115611b4c57611b4c613c58565b14611ba95760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610a1f565b82611be65760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610a1f565b600086815260036020526040812054600280549091908110611c0a57611c0a613baf565b60009182526020822060059091020180549092508290611c2c90600190613b63565b81548110611c3c57611c3c613baf565b90600052602060002090600d0201905060005b86811015611d02573382898984818110611c6b57611c6b613baf565b9050602002013581548110611c8257611c82613baf565b60009182526020909120600490910201546001600160a01b031614611cb95760405162461bcd60e51b8152600401610a1f90613e1d565b8582898984818110611ccd57611ccd613baf565b9050602002013581548110611ce457611ce4613baf565b60009182526020909120600160049092020181019190915501611c4f565b5086869050816005016000828254611d1a9190613cc5565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611d57908b908b908b90613e86565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611d8f57611d8f613baf565b60009182526020822060059091020180549092508290611db190600190613b63565b81548110611dc157611dc1613baf565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611e1f57602002820191906000526020600020905b815481526020019060010190808311611e0b575b505050505092505050919050565b600085815260036020526040812054600280548392908110611e5157611e51613baf565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611e8557611e85613baf565b90600052602060002090600d02016000018681548110611ea757611ea7613baf565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190613c89565b506003850154919350915060ff168015611f4d57508183600201541480611f4d5750805b15611f6057612710945050505050610743565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611fa157611fa1613baf565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611fd557611fd5613baf565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061204c5761204c613baf565b6000918252602082206005909102018054909250829061206e90600190613b63565b8154811061207e5761207e613baf565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156120d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fd9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612158573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217c9190613eaa565b5050505050915050600081612192578354612198565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146121d55760405162461bcd60e51b8152600401610a1f90613f14565b6000836001600160a01b031683836040516121f09190613e01565b60006040518083038185875af1925050503d806000811461222d576040519150601f19603f3d011682016040523d82523d6000602084013e612232565b606091505b50509050806119395760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610a1f565b60008681526003602052604090205460028054889290811061229b5761229b613baf565b600091825260209091206002600590920201015460ff16156122cf5760405162461bcd60e51b8152600401610a1f90613cd8565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613bf1565b509093506002925061234d915050565b81600481111561235f5761235f613c58565b146123ba5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610a1f565b856123fc5760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610a1f565b60008881526003602052604081205460028054909190811061242057612420613baf565b90600052602060002090600502019050806001015486111561247b5760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610a1f565b8054600090829061248e90600190613b63565b8154811061249e5761249e613baf565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156124f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061251d9190613bf1565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612578573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259c9190613eaa565b505050505091505060006125b18a8a8a610931565b905060005b8b8110156127ff5733858e8e848181106125d2576125d2613baf565b90506020020135815481106125e9576125e9613baf565b60009182526020909120600490910201546001600160a01b0316146126205760405162461bcd60e51b8152600401610a1f90613e1d565b821580612667575081858e8e8481811061263c5761263c613baf565b905060200201358154811061265357612653613baf565b906000526020600020906004020160010154145b6126e75760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a401610a1f565b848d8d838181106126fa576126fa613baf565b905060200201358154811061271157612711613baf565b600091825260209091206003600490920201015460ff161561276a5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610a1f565b8a858e8e8481811061277e5761277e613baf565b905060200201358154811061279557612795613baf565b60009182526020909120600260049092020101556001858e8e848181106127be576127be613baf565b90506020020135815481106127d5576127d5613baf565b60009182526020909120600490910201600301805460ff19169115159190911790556001016125b6565b508b8b90508460040160008282546128179190613cc5565b909155505060008a8152600285016020526040812080548d929061283c908490613cc5565b909155505060018401548a0361286b57600384015460ff16156128665760038401805460ff191690555b6128e4565b60018401546000908152600285016020526040808220548c8352912054036128ad57600384015460ff166128665760038401805460ff191660011790556128e4565b60018401546000908152600285016020526040808220548c835291205411156128e457600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161292393929190613f56565b60405180910390a450505050505050505050505050565b6000546001600160a01b031633146129645760405162461bcd60e51b8152600401610a1f90613f14565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106129b4576129b4613baf565b600091825260208083208a84526003600590930201918201905260408220548154919350839181106129e8576129e8613baf565b90600052602060002090600d02016000018781548110612a0a57612a0a613baf565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612a765760405162461bcd60e51b8152600401610a1f90613f86565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612b0185878361401a565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612b58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b7c9190613d0f565b612b869190613b63565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612c0f908a908a908a906140da565b60405180910390a25050505050505050565b600083815260036020526040812054600280548392908110612c4557612c45613baf565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612c7957612c79613baf565b90600052602060002090600d02016000018481548110612c9b57612c9b613baf565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ce95760405162461bcd60e51b8152600401610a1f90613f86565b600083815260036020526040902054600280548592908110612d0d57612d0d613baf565b600091825260209091206002600590920201015460ff1615612d415760405162461bcd60e51b8152600401610a1f90613cd8565b600084815260036020526040812054600280549091908110612d6557612d65613baf565b60009182526020822060059091020180549092508290612d8790600190613b63565b81548110612d9757612d97613baf565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190614110565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612e6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e939190613bf1565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f1b9190614110565b9650612f28848a896132ad565b15612fc557604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c8901909152929092208054909216179055612fca565b600096505b50505050505092915050565b600082815260036020526040812054600280548392908110612ffa57612ffa613baf565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061302e5761302e613baf565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561308d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130b19190613c89565b50915091508260040154600014806130e05750801580156130e057506000828152600284016020526040902054155b156130f2576000945050505050613123565b80156131075750506004015491506131239050565b5060009081526002909101602052604090205491506131239050565b92915050565b6000546001600160a01b031633146131535760405162461bcd60e51b8152600401610a1f90613f14565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60036000613181613226565b8054909150600160401b900460ff16806131a8575080546001600160401b03808416911610155b156131c55760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b613252613569565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146132aa5760405162461bcd60e51b8152600401610a1f90613f14565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156132fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331f9190613bf1565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa15801561337e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a29190613d0f565b6133ac9190613b63565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156133ed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261341591908101906141c0565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613471573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134959190614110565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156134ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351091906142a1565b50509150915082816135229190613cc5565b60045490831015955060ff161561355e5784801561355b57506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b613571613590565b61358e57604051631afcd79f60e31b815260040160405180910390fd5b565b600061359a613226565b54600160401b900460ff16919050565b6000602082840312156135bc57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156135fc576135fc6135c3565b60405290565b604051601f8201601f191681016001600160401b038111828210171561362a5761362a6135c3565b604052919050565b600082601f83011261364357600080fd5b81356001600160401b0381111561365c5761365c6135c3565b61366f601f8201601f1916602001613602565b81815284602083860101111561368457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156136b657600080fd5b833592506020840135915060408401356001600160401b038111156136da57600080fd5b6136e686828701613632565b9150509250925092565b6001600160a01b03811681146132aa57600080fd5b6000806000806080858703121561371b57600080fd5b84359350602085013561372d816136f0565b93969395505050506040820135916060013590565b6000806040838503121561375557600080fd5b8235613760816136f0565b91506020830135613770816136f0565b809150509250929050565b6000806040838503121561378e57600080fd5b50508035926020909101359150565b600080604083850312156137b057600080fd5b82356137bb816136f0565b915060208301356001600160401b038111156137d657600080fd5b6137e285828601613632565b9150509250929050565b60005b838110156138075781810151838201526020016137ef565b50506000910152565b600081518084526138288160208601602086016137ec565b601f01601f19169290920160200192915050565b60208152600061384f6020830184613810565b9392505050565b83815282151560208201526060604082015260006107436060830184613810565b60008083601f84011261388957600080fd5b5081356001600160401b038111156138a057600080fd5b6020830191508360208260051b85010111156138bb57600080fd5b9250929050565b600080600080606085870312156138d857600080fd5b8435935060208501356001600160401b038111156138f557600080fd5b61390187828801613877565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561394c57835183529284019291840191600101613930565b50909695505050505050565b600080600080600060a0868803121561397057600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806000606084860312156139a857600080fd5b505081359360208301359350604090920135919050565b6000806000606084860312156139d457600080fd5b83356139df816136f0565b92506020840135915060408401356001600160401b038111156136da57600080fd5b60008060008060008060a08789031215613a1a57600080fd5b8635955060208701356001600160401b0380821115613a3857600080fd5b613a448a838b01613877565b909750955060408901359450606089013593506080890135915080821115613a6b57600080fd5b50613a7889828a01613632565b9150509295509295509295565b600060208284031215613a9757600080fd5b813561384f816136f0565b600080600080600060808688031215613aba57600080fd5b853594506020860135935060408601356001600160401b0380821115613adf57600080fd5b818801915088601f830112613af357600080fd5b813581811115613b0257600080fd5b896020828501011115613b1457600080fd5b96999598505060200195606001359392505050565b60008060408385031215613b3c57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561312357613123613b4d565b808202811582820484141761312357613123613b4d565b600082613baa57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613bdc57600080fd5b919050565b80518015158114613bdc57600080fd5b600080600080600060a08688031215613c0957600080fd5b613c1286613bc5565b94506020860151613c22816136f0565b604087015190945060058110613c3757600080fd5b9250613c4560608701613be1565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613c8057600080fd5b61384f82613be1565b600080600060608486031215613c9e57600080fd5b83519250613cae60208501613be1565b9150613cbc60408501613be1565b90509250925092565b8082018082111561312357613123613b4d565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b600060208284031215613d2157600080fd5b5051919050565b600181811c90821680613d3c57607f821691505b602082108103613d5c57634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613d8381613d28565b8060608701526080600180841660008114613da55760018114613dc157613df1565b60ff19851660808a0152608084151560051b8a01019550613df1565b89600052602060002060005b85811015613de85781548b8201860152908301908801613dcd565b8a016080019650505b50939a9950505050505050505050565b60008251613e138184602087016137ec565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b03831115613e6d57600080fd5b8260051b80836020870137939093016020019392505050565b604081526000613e9a604083018587613e54565b9050826020830152949350505050565b600080600080600080600060e0888a031215613ec557600080fd5b613ece88613bc5565b9650613edc60208901613be1565b955060408801519450606088015193506080880151925060a08801519150613f0660c08901613be1565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b604081526000613f6a604083018587613e54565b8281036020840152613f7c8185613810565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f82111561193b576000816000526020600020601f850160051c81016020861015613ff35750805b601f850160051c820191505b8181101561401257828155600101613fff565b505050505050565b6001600160401b03831115614031576140316135c3565b6140458361403f8354613d28565b83613fca565b6000601f84116001811461407957600085156140615750838201355b600019600387901b1c1916600186901b1783556140d3565b600083815260209020601f19861690835b828110156140aa578685013582556020948501946001909201910161408a565b50868210156140c75760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561412257600080fd5b815161384f816136f0565b600082601f83011261413e57600080fd5b815160206001600160401b03821115614159576141596135c3565b8160051b614168828201613602565b928352848101820192828101908785111561418257600080fd5b83870192505b848310156141aa57825161419b816136f0565b82529183019190830190614188565b979650505050505050565b8051613bdc816136f0565b6000602082840312156141d257600080fd5b81516001600160401b03808211156141e957600080fd5b9083019061016082860312156141fe57600080fd5b6142066135d9565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561424e57600080fd5b61425a8782860161412d565b60c08301525060e08381015190820152610100808401519082015261012091506142858284016141b5565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156142b757600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220ebfec9af244a625ba29b828f8582149fa1b92ced62e2f25183243cbccf37668d64736f6c63430008180033", + "numDeployments": 3, + "solcInputHash": "525260efd109be98dd6a976c1b7235d3", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize4\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encodingThe unused parameters may be used by overriding contracts.\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitClassic Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":\"DisputeKitClassic\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitClassic\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\ncontract DisputeKitClassic is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.2\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize4() external reinitializer(4) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x09e907f0488fa890002d2657036684b76aa706a15a9bc4edc7c7a9050a5f7f4d\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(uint256 _coreDisputeID, uint256[] calldata _voteIDs, bytes32 _commit) external {\\n _castCommit(_coreDisputeID, _voteIDs, _commit);\\n }\\n\\n function _castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external {\\n _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification);\\n }\\n\\n function _castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf11760d6d9407a37f0d0fc7adc7ec1a5056c167bffc1c1c785247909fcf64cc4\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051614347620001036000396000818161172c01528181611755015261194d01526143476000f3fe6080604052600436106101b95760003560e01c806369f3f041116100ed578063b6ede54011610090578063b6ede54014610599578063ba66fde7146105b9578063be467604146105d9578063caeb50ed146105ef578063d2b8035a14610604578063da3beb8c14610624578063e349ad30146104e1578063e4c0aaf414610644578063f2f4eb261461066457600080fd5b806369f3f041146104545780636d4cd8ea146104a1578063751accd0146104c1578063796490f9146104e15780637c04034e146104f75780638e42646014610517578063a7cc08fe14610537578063b34bfaa81461058357600080fd5b8063485cc95511610160578063485cc9551461031d5780634b2f0ea01461033f5780634f1ef2861461035257806352d1902d1461036557806354fd4d501461037a578063564a565d146103b85780635c92e2f6146103e757806365540b9614610407578063675926f61461043457600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e3578063362c3479146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d93660046135cc565b610684565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e3660046135cc565b61074c565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b506102786102663660046135cc565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a13660046135cc565b6107c3565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de3660046136c3565b610931565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b50610278610318366004613727565b61095e565b34801561032957600080fd5b5061033d610338366004613764565b610de9565b005b61033d61034d36600461379d565b610eb1565b61033d6103603660046137bf565b611718565b34801561037157600080fd5b50610278611940565b34801561038657600080fd5b506103ab6040518060400160405280600581526020016418171c971960d91b81525081565b6040516101ea919061385e565b3480156103c457600080fd5b506103d86103d33660046135cc565b61199e565b6040516101ea93929190613878565b3480156103f357600080fd5b5061033d6104023660046138e4565b611a64565b34801561041357600080fd5b506104276104223660046135cc565b611a70565b6040516101ea9190613936565b34801561044057600080fd5b5061027861044f36600461397a565b611b34565b34801561046057600080fd5b5061047461046f3660046139b5565b611c77565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104ad57600080fd5b506101de6104bc3660046135cc565b611d2f565b3480156104cd57600080fd5b5061033d6104dc3660046139e1565b611eb2565b3480156104ed57600080fd5b5061027861271081565b34801561050357600080fd5b5061033d610512366004613a23565b611f7e565b34801561052357600080fd5b5061033d610532366004613aa7565b611f94565b34801561054357600080fd5b506105576105523660046139b5565b611fe0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b34801561058f57600080fd5b50610278614e2081565b3480156105a557600080fd5b5061033d6105b4366004613ac4565b6120a6565b3480156105c557600080fd5b506101de6105d43660046139b5565b61227b565b3480156105e557600080fd5b5061027861138881565b3480156105fb57600080fd5b5061033d612316565b34801561061057600080fd5b5061023361061f36600461379d565b6123c7565b34801561063057600080fd5b5061027861063f36600461379d565b6126e1565b34801561065057600080fd5b5061033d61065f366004613aa7565b612834565b34801561067057600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f59190613b4b565b91509150600061070485611a70565b90508051600014801561074357506127106113886107228585613b85565b61072c9190613b98565b6107369190613baf565b6107408442613b85565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077057610770613bd1565b6000918252602082206005909102018054909250829061079290600190613b85565b815481106107a2576107a2613bd1565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107ef576107ef613bd1565b6000918252602082206005909102018054909250829061081190600190613b85565b8154811061082157610821613bd1565b60009182526020909120600d90910201600381015460ff16945090508361084c57806001015461084f565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c29190613c13565b50909350600492506108d2915050565b8160048111156108e4576108e4613c7a565b036109275760006108f488611a70565b90508051600103610925578060008151811061091257610912613bd1565b6020026020010151965060009550600194505b505b5050509193909250565b50604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d09190613c13565b50935050505080610a285760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190613c90565b15610add5760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b6044820152606401610a1f565b600086815260036020526040812054600280549091908110610b0157610b01613bd1565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610b3557610b35613bd1565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190613cab565b5050600087815260078401602052604090205490915060ff16610bfe576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610d43565b808603610c73576000868152600683016020526040902054610c21576000610c6c565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610c629190613b98565b610c6c9190613baf565b9450610d43565b600081815260078301602052604090205460ff16610d435781600601600083600a01600181548110610ca757610ca7613bd1565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610cdd57610cdd613bd1565b9060005260206000200154815260200190815260200160002054610d019190613ce7565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610d369190613b98565b610d409190613baf565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ddd576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610df5612880565b8054909150600160401b900460ff1680610e1c575080546001600160401b03808416911610155b15610e395760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610e6484846128a4565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610ed557610ed5613bd1565b600091825260209091206002600590920201015460ff1615610f095760405162461bcd60e51b8152600401610a1f90613cfa565b600083815260036020526040812054600280549091908110610f2d57610f2d613bd1565b906000526020600020906005020190508060010154831115610f915760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610a1f565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110029190613b4b565b9150915081421015801561101557508042105b61105a5760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610a1f565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613cab565b505090508681036110d4576127109150611155565b6127106113886110e48686613b85565b6110ee9190613b98565b6110f89190613baf565b6111028542613b85565b1061114f5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610a1f565b614e2091505b8454600090869061116890600190613b85565b8154811061117857611178613bd1565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190613d31565b6112059190613b85565b60008a815260078401602052604090205490915060ff16156112695760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610a1f565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d79190613d31565b905060006127106112e88784613b98565b6112f29190613baf565b6112fc9083613ce7565b60008c8152600686016020526040812054919250908211156113ad5760008c815260068601602052604090205434906113359084613b85565b1161135a5760008c81526006860160205260409020546113559083613b85565b61135c565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516113a4929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906113d9908490613ce7565b909155505060008c8152600686016020526040812080548392906113fe908490613ce7565b909155505060008c815260068601602052604090205482116114d05760008c815260068601602052604081205460098701805491929091611440908490613ce7565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116db578285600901546114ed9190613b85565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190613c90565b156115785760028a01805460ff1916600117905561165b565b895460038b01600061158b876001613ce7565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161160691815260200190565b602060405180830381865afa158015611623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116479190613d31565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016116a893929190613d84565b6000604051808303818588803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b50505050505b8034111561170957336108fc6116f18334613b85565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b611721826128da565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061179f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166117936000805160206142f28339815191525490565b6001600160a01b031614155b156117bd5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611817575060408051601f3d908101601f1916820190925261181491810190613d31565b60015b61183f57604051630c76093760e01b81526001600160a01b0383166004820152602401610a1f565b6000805160206142f2833981519152811461187057604051632a87526960e21b815260048101829052602401610a1f565b6000805160206142f28339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a281511561193b576000836001600160a01b0316836040516118d79190613e23565b600060405180830381855af49150503d8060008114611912576040519150601f19603f3d011682016040523d82523d6000602084013e611917565b606091505b5050905080611939576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461198b5760405163703e46dd60e11b815260040160405180910390fd5b506000805160206142f283398151915290565b600281815481106119ae57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916119e190613d4a565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0d90613d4a565b8015611a5a5780601f10611a2f57610100808354040283529160200191611a5a565b820191906000526020600020905b815481529060010190602001808311611a3d57829003601f168201915b5050505050905083565b61193984848484612907565b6000818152600360205260408120546002805460609392908110611a9657611a96613bd1565b60009182526020822060059091020180549092508290611ab890600190613b85565b81548110611ac857611ac8613bd1565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611b2657602002820191906000526020600020905b815481526020019060010190808311611b12575b505050505092505050919050565b600085815260036020526040812054600280548392908110611b5857611b58613bd1565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611b8c57611b8c613bd1565b90600052602060002090600d02016000018681548110611bae57611bae613bd1565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611c0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c309190613cab565b506003850154919350915060ff168015611c5457508183600201541480611c545750805b15611c6757612710945050505050610743565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611ca857611ca8613bd1565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611cdc57611cdc613bd1565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611d5357611d53613bd1565b60009182526020822060059091020180549092508290611d7590600190613b85565b81548110611d8557611d85613bd1565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e049190613c13565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015611e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e839190613e3f565b5050505050915050600081611e99578354611e9f565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b03163314611edc5760405162461bcd60e51b8152600401610a1f90613ea9565b6000836001600160a01b03168383604051611ef79190613e23565b60006040518083038185875af1925050503d8060008114611f34576040519150601f19603f3d011682016040523d82523d6000602084013e611f39565b606091505b50509050806119395760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610a1f565b611f8c868686868686612c0c565b505050505050565b6000546001600160a01b03163314611fbe5760405162461bcd60e51b8152600401610a1f90613ea9565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a8152602001908152602001600020548154811061200e5761200e613bd1565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061204257612042613bd1565b90600052602060002090600d0201600001878154811061206457612064613bd1565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146120d05760405162461bcd60e51b8152600401610a1f90613eeb565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad20161215b858783613f77565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190613d31565b6121e09190613b85565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612269908a908a908a90614037565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061229f5761229f613bd1565b600091825260208083208784526003600590930201918201905260408220548154919350839181106122d3576122d3613bd1565b90600052602060002090600d020160000184815481106122f5576122f5613bd1565b600091825260209091206004909102016003015460ff169695505050505050565b60046000612322612880565b8054909150600160401b900460ff1680612349575080546001600160401b03808416911610155b156123665760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b6001546000906001600160a01b031633146123f45760405162461bcd60e51b8152600401610a1f90613eeb565b60008381526003602052604090205460028054859290811061241857612418613bd1565b600091825260209091206002600590920201015460ff161561244c5760405162461bcd60e51b8152600401610a1f90613cfa565b60008481526003602052604081205460028054909190811061247057612470613bd1565b6000918252602082206005909102018054909250829061249290600190613b85565b815481106124a2576124a2613bd1565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252b919061406d565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561257a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259e9190613c13565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612602573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612626919061406d565b9650612633848a896132cf565b156126d057604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556126d5565b600096505b50505050505092915050565b60008281526003602052604081205460028054839290811061270557612705613bd1565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061273957612739613bd1565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015612798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bc9190613cab565b50915091508260040154600014806127eb5750801580156127eb57506000828152600284016020526040902054155b156127fd57600094505050505061282e565b801561281257505060040154915061282e9050565b50600090815260029091016020526040902054915061282e9050565b92915050565b6000546001600160a01b0316331461285e5760405162461bcd60e51b8152600401610a1f90613ea9565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b6128ac61358b565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146129045760405162461bcd60e51b8152600401610a1f90613ea9565b50565b60008481526003602052604090205460028054869290811061292b5761292b613bd1565b600091825260209091206002600590920201015460ff161561295f5760405162461bcd60e51b8152600401610a1f90613cfa565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa1580156129a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cd9190613c13565b50909350600192506129dd915050565b8160048111156129ef576129ef613c7a565b14612a4c5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610a1f565b82612a895760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610a1f565b600086815260036020526040812054600280549091908110612aad57612aad613bd1565b60009182526020822060059091020180549092508290612acf90600190613b85565b81548110612adf57612adf613bd1565b90600052602060002090600d0201905060005b86811015612ba5573382898984818110612b0e57612b0e613bd1565b9050602002013581548110612b2557612b25613bd1565b60009182526020909120600490910201546001600160a01b031614612b5c5760405162461bcd60e51b8152600401610a1f9061408a565b8582898984818110612b7057612b70613bd1565b9050602002013581548110612b8757612b87613bd1565b60009182526020909120600160049092020181019190915501612af2565b5086869050816005016000828254612bbd9190613ce7565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612bfa908b908b908b906140f3565b60405180910390a35050505050505050565b600086815260036020526040902054600280548892908110612c3057612c30613bd1565b600091825260209091206002600590920201015460ff1615612c645760405162461bcd60e51b8152600401610a1f90613cfa565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd29190613c13565b5090935060029250612ce2915050565b816004811115612cf457612cf4613c7a565b14612d4f5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610a1f565b85612d915760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610a1f565b600088815260036020526040812054600280549091908110612db557612db5613bd1565b906000526020600020906005020190508060010154861115612e105760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610a1f565b80546000908290612e2390600190613b85565b81548110612e3357612e33613bd1565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612e8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb29190613c13565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f319190613e3f565b50505050509150506000612f468a8a8a610931565b905060005b8b8110156131945733858e8e84818110612f6757612f67613bd1565b9050602002013581548110612f7e57612f7e613bd1565b60009182526020909120600490910201546001600160a01b031614612fb55760405162461bcd60e51b8152600401610a1f9061408a565b821580612ffc575081858e8e84818110612fd157612fd1613bd1565b9050602002013581548110612fe857612fe8613bd1565b906000526020600020906004020160010154145b61307c5760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a401610a1f565b848d8d8381811061308f5761308f613bd1565b90506020020135815481106130a6576130a6613bd1565b600091825260209091206003600490920201015460ff16156130ff5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610a1f565b8a858e8e8481811061311357613113613bd1565b905060200201358154811061312a5761312a613bd1565b60009182526020909120600260049092020101556001858e8e8481811061315357613153613bd1565b905060200201358154811061316a5761316a613bd1565b60009182526020909120600490910201600301805460ff1916911515919091179055600101612f4b565b508b8b90508460040160008282546131ac9190613ce7565b909155505060008a8152600285016020526040812080548d92906131d1908490613ce7565b909155505060018401548a0361320057600384015460ff16156131fb5760038401805460ff191690555b613279565b60018401546000908152600285016020526040808220548c83529120540361324257600384015460ff166131fb5760038401805460ff19166001179055613279565b60018401546000908152600285016020526040808220548c8352912054111561327957600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d6040516132b893929190614117565b60405180910390a450505050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561331d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133419190613c13565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156133a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133c49190613d31565b6133ce9190613b85565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa15801561340f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261343791908101906141da565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b7919061406d565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa15801561350e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061353291906142bb565b50509150915082816135449190613ce7565b60045490831015955060ff16156135805784801561357d57506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b6135936135b2565b6135b057604051631afcd79f60e31b815260040160405180910390fd5b565b60006135bc612880565b54600160401b900460ff16919050565b6000602082840312156135de57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561361e5761361e6135e5565b60405290565b604051601f8201601f191681016001600160401b038111828210171561364c5761364c6135e5565b604052919050565b600082601f83011261366557600080fd5b81356001600160401b0381111561367e5761367e6135e5565b613691601f8201601f1916602001613624565b8181528460208386010111156136a657600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156136d857600080fd5b833592506020840135915060408401356001600160401b038111156136fc57600080fd5b61370886828701613654565b9150509250925092565b6001600160a01b038116811461290457600080fd5b6000806000806080858703121561373d57600080fd5b84359350602085013561374f81613712565b93969395505050506040820135916060013590565b6000806040838503121561377757600080fd5b823561378281613712565b9150602083013561379281613712565b809150509250929050565b600080604083850312156137b057600080fd5b50508035926020909101359150565b600080604083850312156137d257600080fd5b82356137dd81613712565b915060208301356001600160401b038111156137f857600080fd5b61380485828601613654565b9150509250929050565b60005b83811015613829578181015183820152602001613811565b50506000910152565b6000815180845261384a81602086016020860161380e565b601f01601f19169290920160200192915050565b6020815260006138716020830184613832565b9392505050565b83815282151560208201526060604082015260006107436060830184613832565b60008083601f8401126138ab57600080fd5b5081356001600160401b038111156138c257600080fd5b6020830191508360208260051b85010111156138dd57600080fd5b9250929050565b600080600080606085870312156138fa57600080fd5b8435935060208501356001600160401b0381111561391757600080fd5b61392387828801613899565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561396e57835183529284019291840191600101613952565b50909695505050505050565b600080600080600060a0868803121561399257600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806000606084860312156139ca57600080fd5b505081359360208301359350604090920135919050565b6000806000606084860312156139f657600080fd5b8335613a0181613712565b92506020840135915060408401356001600160401b038111156136fc57600080fd5b60008060008060008060a08789031215613a3c57600080fd5b8635955060208701356001600160401b0380821115613a5a57600080fd5b613a668a838b01613899565b909750955060408901359450606089013593506080890135915080821115613a8d57600080fd5b50613a9a89828a01613654565b9150509295509295509295565b600060208284031215613ab957600080fd5b813561387181613712565b600080600080600060808688031215613adc57600080fd5b853594506020860135935060408601356001600160401b0380821115613b0157600080fd5b818801915088601f830112613b1557600080fd5b813581811115613b2457600080fd5b896020828501011115613b3657600080fd5b96999598505060200195606001359392505050565b60008060408385031215613b5e57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561282e5761282e613b6f565b808202811582820484141761282e5761282e613b6f565b600082613bcc57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613bfe57600080fd5b919050565b80518015158114613bfe57600080fd5b600080600080600060a08688031215613c2b57600080fd5b613c3486613be7565b94506020860151613c4481613712565b604087015190945060058110613c5957600080fd5b9250613c6760608701613c03565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613ca257600080fd5b61387182613c03565b600080600060608486031215613cc057600080fd5b83519250613cd060208501613c03565b9150613cde60408501613c03565b90509250925092565b8082018082111561282e5761282e613b6f565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b600060208284031215613d4357600080fd5b5051919050565b600181811c90821680613d5e57607f821691505b602082108103613d7e57634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613da581613d4a565b8060608701526080600180841660008114613dc75760018114613de357613e13565b60ff19851660808a0152608084151560051b8a01019550613e13565b89600052602060002060005b85811015613e0a5781548b8201860152908301908801613def565b8a016080019650505b50939a9950505050505050505050565b60008251613e3581846020870161380e565b9190910192915050565b600080600080600080600060e0888a031215613e5a57600080fd5b613e6388613be7565b9650613e7160208901613c03565b955060408801519450606088015193506080880151925060a08801519150613e9b60c08901613c03565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f82111561193b576000816000526020600020601f850160051c81016020861015613f585750805b601f850160051c820191505b81811015611f8c57828155600101613f64565b6001600160401b03831115613f8e57613f8e6135e5565b613fa283613f9c8354613d4a565b83613f2f565b6000601f841160018114613fd65760008515613fbe5750838201355b600019600387901b1c1916600186901b178355614030565b600083815260209020601f19861690835b828110156140075786850135825560209485019460019092019101613fe7565b50868210156140245760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561407f57600080fd5b815161387181613712565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b038311156140da57600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006141076040830185876140c1565b9050826020830152949350505050565b60408152600061412b6040830185876140c1565b828103602084015261413d8185613832565b9695505050505050565b600082601f83011261415857600080fd5b815160206001600160401b03821115614173576141736135e5565b8160051b614182828201613624565b928352848101820192828101908785111561419c57600080fd5b83870192505b848310156141c45782516141b581613712565b825291830191908301906141a2565b979650505050505050565b8051613bfe81613712565b6000602082840312156141ec57600080fd5b81516001600160401b038082111561420357600080fd5b90830190610160828603121561421857600080fd5b6142206135fb565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561426857600080fd5b61427487828601614147565b60c08301525060e083810151908201526101008084015190820152610120915061429f8284016141cf565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156142d157600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220775a89e12aa16e362b83a5f6bf0da7a9eb757dad94ec3fe3e048223fb192d21764736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106101b95760003560e01c806369f3f041116100ed578063b6ede54011610090578063b6ede54014610599578063ba66fde7146105b9578063be467604146105d9578063caeb50ed146105ef578063d2b8035a14610604578063da3beb8c14610624578063e349ad30146104e1578063e4c0aaf414610644578063f2f4eb261461066457600080fd5b806369f3f041146104545780636d4cd8ea146104a1578063751accd0146104c1578063796490f9146104e15780637c04034e146104f75780638e42646014610517578063a7cc08fe14610537578063b34bfaa81461058357600080fd5b8063485cc95511610160578063485cc9551461031d5780634b2f0ea01461033f5780634f1ef2861461035257806352d1902d1461036557806354fd4d501461037a578063564a565d146103b85780635c92e2f6146103e757806365540b9614610407578063675926f61461043457600080fd5b80630855bbe9146101be5780630baa64d1146101f35780630c340a24146102135780631200aabc1461024b5780631c3db16d146102865780631cc3423a146102c35780632621b9a2146102e3578063362c3479146102fd575b600080fd5b3480156101ca57600080fd5b506101de6101d93660046135cc565b610684565b60405190151581526020015b60405180910390f35b3480156101ff57600080fd5b506101de61020e3660046135cc565b61074c565b34801561021f57600080fd5b50600054610233906001600160a01b031681565b6040516001600160a01b0390911681526020016101ea565b34801561025757600080fd5b506102786102663660046135cc565b60036020526000908152604090205481565b6040519081526020016101ea565b34801561029257600080fd5b506102a66102a13660046135cc565b6107c3565b6040805193845291151560208401521515908201526060016101ea565b3480156102cf57600080fd5b506102786102de3660046136c3565b610931565b3480156102ef57600080fd5b506004546101de9060ff1681565b34801561030957600080fd5b50610278610318366004613727565b61095e565b34801561032957600080fd5b5061033d610338366004613764565b610de9565b005b61033d61034d36600461379d565b610eb1565b61033d6103603660046137bf565b611718565b34801561037157600080fd5b50610278611940565b34801561038657600080fd5b506103ab6040518060400160405280600581526020016418171c971960d91b81525081565b6040516101ea919061385e565b3480156103c457600080fd5b506103d86103d33660046135cc565b61199e565b6040516101ea93929190613878565b3480156103f357600080fd5b5061033d6104023660046138e4565b611a64565b34801561041357600080fd5b506104276104223660046135cc565b611a70565b6040516101ea9190613936565b34801561044057600080fd5b5061027861044f36600461397a565b611b34565b34801561046057600080fd5b5061047461046f3660046139b5565b611c77565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101ea565b3480156104ad57600080fd5b506101de6104bc3660046135cc565b611d2f565b3480156104cd57600080fd5b5061033d6104dc3660046139e1565b611eb2565b3480156104ed57600080fd5b5061027861271081565b34801561050357600080fd5b5061033d610512366004613a23565b611f7e565b34801561052357600080fd5b5061033d610532366004613aa7565b611f94565b34801561054357600080fd5b506105576105523660046139b5565b611fe0565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101ea565b34801561058f57600080fd5b50610278614e2081565b3480156105a557600080fd5b5061033d6105b4366004613ac4565b6120a6565b3480156105c557600080fd5b506101de6105d43660046139b5565b61227b565b3480156105e557600080fd5b5061027861138881565b3480156105fb57600080fd5b5061033d612316565b34801561061057600080fd5b5061023361061f36600461379d565b6123c7565b34801561063057600080fd5b5061027861063f36600461379d565b6126e1565b34801561065057600080fd5b5061033d61065f366004613aa7565b612834565b34801561067057600080fd5b50600154610233906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f59190613b4b565b91509150600061070485611a70565b90508051600014801561074357506127106113886107228585613b85565b61072c9190613b98565b6107369190613baf565b6107408442613b85565b10155b95945050505050565b60008181526003602052604081205460028054839290811061077057610770613bd1565b6000918252602082206005909102018054909250829061079290600190613b85565b815481106107a2576107a2613bd1565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106107ef576107ef613bd1565b6000918252602082206005909102018054909250829061081190600190613b85565b8154811061082157610821613bd1565b60009182526020909120600d90910201600381015460ff16945090508361084c57806001015461084f565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561089e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c29190613c13565b50909350600492506108d2915050565b8160048111156108e4576108e4613c7a565b036109275760006108f488611a70565b90508051600103610925578060008151811061091257610912613bd1565b6020026020010151965060009550600194505b505b5050509193909250565b50604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d09190613c13565b50935050505080610a285760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064015b60405180910390fd5b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190613c90565b15610add5760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b6044820152606401610a1f565b600086815260036020526040812054600280549091908110610b0157610b01613bd1565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610b3557610b35613bd1565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb49190613cab565b5050600087815260078401602052604090205490915060ff16610bfe576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610d43565b808603610c73576000868152600683016020526040902054610c21576000610c6c565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610c629190613b98565b610c6c9190613baf565b9450610d43565b600081815260078301602052604090205460ff16610d435781600601600083600a01600181548110610ca757610ca7613bd1565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610cdd57610cdd613bd1565b9060005260206000200154815260200190815260200160002054610d019190613ce7565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610d369190613b98565b610d409190613baf565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ddd576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610df5612880565b8054909150600160401b900460ff1680610e1c575080546001600160401b03808416911610155b15610e395760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610e6484846128a4565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610ed557610ed5613bd1565b600091825260209091206002600590920201015460ff1615610f095760405162461bcd60e51b8152600401610a1f90613cfa565b600083815260036020526040812054600280549091908110610f2d57610f2d613bd1565b906000526020600020906005020190508060010154831115610f915760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e6044820152606401610a1f565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015610fde573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110029190613b4b565b9150915081421015801561101557508042105b61105a5760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b6044820152606401610a1f565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa15801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613cab565b505090508681036110d4576127109150611155565b6127106113886110e48686613b85565b6110ee9190613b98565b6110f89190613baf565b6111028542613b85565b1061114f5760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f736572006044820152606401610a1f565b614e2091505b8454600090869061116890600190613b85565b8154811061117857611178613bd1565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190613d31565b6112059190613b85565b60008a815260078401602052604090205490915060ff16156112695760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e00000000006044820152606401610a1f565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa1580156112b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d79190613d31565b905060006127106112e88784613b98565b6112f29190613baf565b6112fc9083613ce7565b60008c8152600686016020526040812054919250908211156113ad5760008c815260068601602052604090205434906113359084613b85565b1161135a5760008c81526006860160205260409020546113559083613b85565b61135c565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f856040516113a4929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906113d9908490613ce7565b909155505060008c8152600686016020526040812080548392906113fe908490613ce7565b909155505060008c815260068601602052604090205482116114d05760008c815260068601602052604081205460098701805491929091611440908490613ce7565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156116db578285600901546114ed9190613b85565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190613c90565b156115785760028a01805460ff1916600117905561165b565b895460038b01600061158b876001613ce7565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b815260040161160691815260200190565b602060405180830381865afa158015611623573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116479190613d31565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016116a893929190613d84565b6000604051808303818588803b1580156116c157600080fd5b505af11580156116d5573d6000803e3d6000fd5b50505050505b8034111561170957336108fc6116f18334613b85565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b611721826128da565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061179f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166117936000805160206142f28339815191525490565b6001600160a01b031614155b156117bd5760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611817575060408051601f3d908101601f1916820190925261181491810190613d31565b60015b61183f57604051630c76093760e01b81526001600160a01b0383166004820152602401610a1f565b6000805160206142f2833981519152811461187057604051632a87526960e21b815260048101829052602401610a1f565b6000805160206142f28339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a281511561193b576000836001600160a01b0316836040516118d79190613e23565b600060405180830381855af49150503d8060008114611912576040519150601f19603f3d011682016040523d82523d6000602084013e611917565b606091505b5050905080611939576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461198b5760405163703e46dd60e11b815260040160405180910390fd5b506000805160206142f283398151915290565b600281815481106119ae57600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff90911692916119e190613d4a565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0d90613d4a565b8015611a5a5780601f10611a2f57610100808354040283529160200191611a5a565b820191906000526020600020905b815481529060010190602001808311611a3d57829003601f168201915b5050505050905083565b61193984848484612907565b6000818152600360205260408120546002805460609392908110611a9657611a96613bd1565b60009182526020822060059091020180549092508290611ab890600190613b85565b81548110611ac857611ac8613bd1565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611b2657602002820191906000526020600020905b815481526020019060010190808311611b12575b505050505092505050919050565b600085815260036020526040812054600280548392908110611b5857611b58613bd1565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611b8c57611b8c613bd1565b90600052602060002090600d02016000018681548110611bae57611bae613bd1565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611c0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c309190613cab565b506003850154919350915060ff168015611c5457508183600201541480611c545750805b15611c6757612710945050505050610743565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611ca857611ca8613bd1565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611cdc57611cdc613bd1565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611d5357611d53613bd1565b60009182526020822060059091020180549092508290611d7590600190613b85565b81548110611d8557611d85613bd1565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015611de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e049190613c13565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015611e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e839190613e3f565b5050505050915050600081611e99578354611e9f565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b03163314611edc5760405162461bcd60e51b8152600401610a1f90613ea9565b6000836001600160a01b03168383604051611ef79190613e23565b60006040518083038185875af1925050503d8060008114611f34576040519150601f19603f3d011682016040523d82523d6000602084013e611f39565b606091505b50509050806119395760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b6044820152606401610a1f565b611f8c868686868686612c0c565b505050505050565b6000546001600160a01b03163314611fbe5760405162461bcd60e51b8152600401610a1f90613ea9565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a8152602001908152602001600020548154811061200e5761200e613bd1565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061204257612042613bd1565b90600052602060002090600d0201600001878154811061206457612064613bd1565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146120d05760405162461bcd60e51b8152600401610a1f90613eeb565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad20161215b858783613f77565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156121b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d69190613d31565b6121e09190613b85565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890612269908a908a908a90614037565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061229f5761229f613bd1565b600091825260208083208784526003600590930201918201905260408220548154919350839181106122d3576122d3613bd1565b90600052602060002090600d020160000184815481106122f5576122f5613bd1565b600091825260209091206004909102016003015460ff169695505050505050565b60046000612322612880565b8054909150600160401b900460ff1680612349575080546001600160401b03808416911610155b156123665760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b6001546000906001600160a01b031633146123f45760405162461bcd60e51b8152600401610a1f90613eeb565b60008381526003602052604090205460028054859290811061241857612418613bd1565b600091825260209091206002600590920201015460ff161561244c5760405162461bcd60e51b8152600401610a1f90613cfa565b60008481526003602052604081205460028054909190811061247057612470613bd1565b6000918252602082206005909102018054909250829061249290600190613b85565b815481106124a2576124a2613bd1565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612507573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061252b919061406d565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561257a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259e9190613c13565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa158015612602573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612626919061406d565b9650612633848a896132cf565b156126d057604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556126d5565b600096505b50505050505092915050565b60008281526003602052604081205460028054839290811061270557612705613bd1565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061273957612739613bd1565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015612798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bc9190613cab565b50915091508260040154600014806127eb5750801580156127eb57506000828152600284016020526040902054155b156127fd57600094505050505061282e565b801561281257505060040154915061282e9050565b50600090815260029091016020526040902054915061282e9050565b92915050565b6000546001600160a01b0316331461285e5760405162461bcd60e51b8152600401610a1f90613ea9565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b6128ac61358b565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146129045760405162461bcd60e51b8152600401610a1f90613ea9565b50565b60008481526003602052604090205460028054869290811061292b5761292b613bd1565b600091825260209091206002600590920201015460ff161561295f5760405162461bcd60e51b8152600401610a1f90613cfa565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa1580156129a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cd9190613c13565b50909350600192506129dd915050565b8160048111156129ef576129ef613c7a565b14612a4c5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b6064820152608401610a1f565b82612a895760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b6044820152606401610a1f565b600086815260036020526040812054600280549091908110612aad57612aad613bd1565b60009182526020822060059091020180549092508290612acf90600190613b85565b81548110612adf57612adf613bd1565b90600052602060002090600d0201905060005b86811015612ba5573382898984818110612b0e57612b0e613bd1565b9050602002013581548110612b2557612b25613bd1565b60009182526020909120600490910201546001600160a01b031614612b5c5760405162461bcd60e51b8152600401610a1f9061408a565b8582898984818110612b7057612b70613bd1565b9050602002013581548110612b8757612b87613bd1565b60009182526020909120600160049092020181019190915501612af2565b5086869050816005016000828254612bbd9190613ce7565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612bfa908b908b908b906140f3565b60405180910390a35050505050505050565b600086815260036020526040902054600280548892908110612c3057612c30613bd1565b600091825260209091206002600590920201015460ff1615612c645760405162461bcd60e51b8152600401610a1f90613cfa565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd29190613c13565b5090935060029250612ce2915050565b816004811115612cf457612cf4613c7a565b14612d4f5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b6064820152608401610a1f565b85612d915760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b6044820152606401610a1f565b600088815260036020526040812054600280549091908110612db557612db5613bd1565b906000526020600020906005020190508060010154861115612e105760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b6044820152606401610a1f565b80546000908290612e2390600190613b85565b81548110612e3357612e33613bd1565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612e8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb29190613c13565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f319190613e3f565b50505050509150506000612f468a8a8a610931565b905060005b8b8110156131945733858e8e84818110612f6757612f67613bd1565b9050602002013581548110612f7e57612f7e613bd1565b60009182526020909120600490910201546001600160a01b031614612fb55760405162461bcd60e51b8152600401610a1f9061408a565b821580612ffc575081858e8e84818110612fd157612fd1613bd1565b9050602002013581548110612fe857612fe8613bd1565b906000526020600020906004020160010154145b61307c5760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a401610a1f565b848d8d8381811061308f5761308f613bd1565b90506020020135815481106130a6576130a6613bd1565b600091825260209091206003600490920201015460ff16156130ff5760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b6044820152606401610a1f565b8a858e8e8481811061311357613113613bd1565b905060200201358154811061312a5761312a613bd1565b60009182526020909120600260049092020101556001858e8e8481811061315357613153613bd1565b905060200201358154811061316a5761316a613bd1565b60009182526020909120600490910201600301805460ff1916911515919091179055600101612f4b565b508b8b90508460040160008282546131ac9190613ce7565b909155505060008a8152600285016020526040812080548d92906131d1908490613ce7565b909155505060018401548a0361320057600384015460ff16156131fb5760038401805460ff191690555b613279565b60018401546000908152600285016020526040808220548c83529120540361324257600384015460ff166131fb5760038401805460ff19166001179055613279565b60018401546000908152600285016020526040808220548c8352912054111561327957600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d6040516132b893929190614117565b60405180910390a450505050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561331d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133419190613c13565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156133a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133c49190613d31565b6133ce9190613b85565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa15801561340f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261343791908101906141da565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613493573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134b7919061406d565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa15801561350e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061353291906142bb565b50509150915082816135449190613ce7565b60045490831015955060ff16156135805784801561357d57506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b6135936135b2565b6135b057604051631afcd79f60e31b815260040160405180910390fd5b565b60006135bc612880565b54600160401b900460ff16919050565b6000602082840312156135de57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561361e5761361e6135e5565b60405290565b604051601f8201601f191681016001600160401b038111828210171561364c5761364c6135e5565b604052919050565b600082601f83011261366557600080fd5b81356001600160401b0381111561367e5761367e6135e5565b613691601f8201601f1916602001613624565b8181528460208386010111156136a657600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156136d857600080fd5b833592506020840135915060408401356001600160401b038111156136fc57600080fd5b61370886828701613654565b9150509250925092565b6001600160a01b038116811461290457600080fd5b6000806000806080858703121561373d57600080fd5b84359350602085013561374f81613712565b93969395505050506040820135916060013590565b6000806040838503121561377757600080fd5b823561378281613712565b9150602083013561379281613712565b809150509250929050565b600080604083850312156137b057600080fd5b50508035926020909101359150565b600080604083850312156137d257600080fd5b82356137dd81613712565b915060208301356001600160401b038111156137f857600080fd5b61380485828601613654565b9150509250929050565b60005b83811015613829578181015183820152602001613811565b50506000910152565b6000815180845261384a81602086016020860161380e565b601f01601f19169290920160200192915050565b6020815260006138716020830184613832565b9392505050565b83815282151560208201526060604082015260006107436060830184613832565b60008083601f8401126138ab57600080fd5b5081356001600160401b038111156138c257600080fd5b6020830191508360208260051b85010111156138dd57600080fd5b9250929050565b600080600080606085870312156138fa57600080fd5b8435935060208501356001600160401b0381111561391757600080fd5b61392387828801613899565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561396e57835183529284019291840191600101613952565b50909695505050505050565b600080600080600060a0868803121561399257600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b6000806000606084860312156139ca57600080fd5b505081359360208301359350604090920135919050565b6000806000606084860312156139f657600080fd5b8335613a0181613712565b92506020840135915060408401356001600160401b038111156136fc57600080fd5b60008060008060008060a08789031215613a3c57600080fd5b8635955060208701356001600160401b0380821115613a5a57600080fd5b613a668a838b01613899565b909750955060408901359450606089013593506080890135915080821115613a8d57600080fd5b50613a9a89828a01613654565b9150509295509295509295565b600060208284031215613ab957600080fd5b813561387181613712565b600080600080600060808688031215613adc57600080fd5b853594506020860135935060408601356001600160401b0380821115613b0157600080fd5b818801915088601f830112613b1557600080fd5b813581811115613b2457600080fd5b896020828501011115613b3657600080fd5b96999598505060200195606001359392505050565b60008060408385031215613b5e57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561282e5761282e613b6f565b808202811582820484141761282e5761282e613b6f565b600082613bcc57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b80516001600160601b0381168114613bfe57600080fd5b919050565b80518015158114613bfe57600080fd5b600080600080600060a08688031215613c2b57600080fd5b613c3486613be7565b94506020860151613c4481613712565b604087015190945060058110613c5957600080fd5b9250613c6760608701613c03565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613ca257600080fd5b61387182613c03565b600080600060608486031215613cc057600080fd5b83519250613cd060208501613c03565b9150613cde60408501613c03565b90509250925092565b8082018082111561282e5761282e613b6f565b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b600060208284031215613d4357600080fd5b5051919050565b600181811c90821680613d5e57607f821691505b602082108103613d7e57634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613da581613d4a565b8060608701526080600180841660008114613dc75760018114613de357613e13565b60ff19851660808a0152608084151560051b8a01019550613e13565b89600052602060002060005b85811015613e0a5781548b8201860152908301908801613def565b8a016080019650505b50939a9950505050505050505050565b60008251613e3581846020870161380e565b9190910192915050565b600080600080600080600060e0888a031215613e5a57600080fd5b613e6388613be7565b9650613e7160208901613c03565b955060408801519450606088015193506080880151925060a08801519150613e9b60c08901613c03565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f82111561193b576000816000526020600020601f850160051c81016020861015613f585750805b601f850160051c820191505b81811015611f8c57828155600101613f64565b6001600160401b03831115613f8e57613f8e6135e5565b613fa283613f9c8354613d4a565b83613f2f565b6000601f841160018114613fd65760008515613fbe5750838201355b600019600387901b1c1916600186901b178355614030565b600083815260209020601f19861690835b828110156140075786850135825560209485019460019092019101613fe7565b50868210156140245760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b60006020828403121561407f57600080fd5b815161387181613712565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b038311156140da57600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006141076040830185876140c1565b9050826020830152949350505050565b60408152600061412b6040830185876140c1565b828103602084015261413d8185613832565b9695505050505050565b600082601f83011261415857600080fd5b815160206001600160401b03821115614173576141736135e5565b8160051b614182828201613624565b928352848101820192828101908785111561419c57600080fd5b83870192505b848310156141c45782516141b581613712565b825291830191908301906141a2565b979650505050505050565b8051613bfe81613712565b6000602082840312156141ec57600080fd5b81516001600160401b038082111561420357600080fd5b90830190610160828603121561421857600080fd5b6142206135fb565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561426857600080fd5b61427487828601614147565b60c08301525060e083810151908201526101008084015190820152610120915061429f8284016141cf565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156142d157600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220775a89e12aa16e362b83a5f6bf0da7a9eb757dad94ec3fe3e048223fb192d21764736f6c63430008180033", "devdoc": { "errors": { "AlreadyInitialized()": [ diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json index c8f3fee8b..9a24928d4 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json @@ -924,7 +924,7 @@ }, { "inputs": [], - "name": "initialize2", + "name": "initialize4", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1118,16 +1118,16 @@ "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", "0x485cc955000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c590000000000000000000000004838e31e0ea315232c431598110fe677caf2d6e6" ], - "numDeployments": 2, + "numDeployments": 3, "solcInputHash": "96b8e3f55478438b6784f67c1730309e", "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitShutterProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitShutterProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x209228b56d42a8444ca70919e1ded5711fba434a746f26d426e230f57526fc6c\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", "execute": { - "methodName": "initialize2", + "methodName": "initialize4", "args": [] }, - "implementation": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", + "implementation": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", "devdoc": { "kind": "dev", "methods": {}, diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json index 43fd713f2..2fa91c062 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", + "address": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", "abi": [ { "inputs": [], @@ -921,7 +921,7 @@ }, { "inputs": [], - "name": "initialize2", + "name": "initialize4", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1066,41 +1066,41 @@ "type": "function" } ], - "transactionHash": "0x31a2311a33cd1a74a416eeb916aa8f64b65accd95a16a9410203c3fae19e5f5c", + "transactionHash": "0x4652912ebec3fcf633568c2731bcd2ea3f6c38efc4b55757f2c55fcd9a6af4ae", "receipt": { "to": null, "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", - "contractAddress": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", + "contractAddress": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", "transactionIndex": 1, - "gasUsed": "4159870", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000040000000000000000000000000000000000000000000000000000800000000000800000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1bcabc5ab2d8f545f5091a09103b368cef836aaf173fb51c44d496c0bdd0bf15", - "transactionHash": "0x31a2311a33cd1a74a416eeb916aa8f64b65accd95a16a9410203c3fae19e5f5c", + "gasUsed": "3906991", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000002000000000000000000000000000000000000000000000", + "blockHash": "0x2c78cd9dcbec549968acacf96d2f6908bf4a606399d6de881daa449defb67bc4", + "transactionHash": "0x4652912ebec3fcf633568c2731bcd2ea3f6c38efc4b55757f2c55fcd9a6af4ae", "logs": [ { "transactionIndex": 1, - "blockNumber": 148204767, - "transactionHash": "0x31a2311a33cd1a74a416eeb916aa8f64b65accd95a16a9410203c3fae19e5f5c", - "address": "0x646435dBA7C6E8CCbCAED1C20764720adc54F4A1", + "blockNumber": 148226049, + "transactionHash": "0x4652912ebec3fcf633568c2731bcd2ea3f6c38efc4b55757f2c55fcd9a6af4ae", + "address": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", "topics": [ "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" ], "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", "logIndex": 0, - "blockHash": "0x1bcabc5ab2d8f545f5091a09103b368cef836aaf173fb51c44d496c0bdd0bf15" + "blockHash": "0x2c78cd9dcbec549968acacf96d2f6908bf4a606399d6de881daa449defb67bc4" } ], - "blockNumber": 148204767, - "cumulativeGasUsed": "4159870", + "blockNumber": 148226049, + "cumulativeGasUsed": "3906991", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "720097f21043cca39229dbd8e433d9d2", - "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"CommitCastShutter\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"castCommitShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"CommitCastShutter(bytes32,bytes32,bytes)\":{\"details\":\"Emitted when a vote is cast.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castCommitShutter(uint256,uint256[],bytes32,bytes32,bytes)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash including the justification.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encoding\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":\"DisputeKitShutter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbf209306f450437b609837aab267810dcf8311442ed28abb32ad5d62ed43bd9b\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitShutter\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\n/// Added functionality: an Shutter-specific event emitted when a vote is cast.\\ncontract DisputeKitShutter is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.1\\\";\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev Emitted when a vote is cast.\\n /// @param _commit The commitment hash.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity, bytes _encryptedVote);\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize2() external reinitializer(2) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash including the justification.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n function castCommitShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit,\\n bytes32 _identity,\\n bytes calldata _encryptedVote\\n ) external notJumped(_coreDisputeID) {\\n this.castCommit(_coreDisputeID, _voteIDs, _commit);\\n emit CommitCastShutter(_commit, _identity, _encryptedVote);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure override returns (bytes32) {\\n bytes32 justificationHash = keccak256(bytes(_justification));\\n return keccak256(abi.encode(_choice, _salt, justificationHash));\\n }\\n}\\n\",\"keccak256\":\"0x94bebe1d3b5297a7130dd2c7f4bdae3af2789491bed0256d4dd1aaefecb98ab5\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161452b62000103600039600081816119150152818161193e0152611b36015261452b6000f3fe6080604052600436106101c45760003560e01c806365540b96116100f8578063b34bfaa811610090578063b34bfaa8146105c3578063b6ede540146105d9578063ba66fde7146105f9578063be46760414610619578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad3014610521578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b806365540b9614610447578063675926f61461047457806369f3f041146104945780636d4cd8ea146104e1578063751accd014610501578063796490f9146105215780637c04034e146105375780638e42646014610557578063a7cc08fe1461057757600080fd5b8063362c34791161016b578063362c34791461032a578063472abf681461034a578063485cc9551461035f5780634b2f0ea01461037f5780634f1ef2861461039257806352d1902d146103a557806354fd4d50146103ba578063564a565d146103f85780635c92e2f61461042757600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136d0565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613775565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136d0565b610879565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136d0565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136d0565b6108f0565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138df565b610a5e565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613943565b610a9b565b34801561035657600080fd5b5061021e610f21565b34801561036b57600080fd5b5061021e61037a366004613980565b610fd2565b61021e61038d3660046139b9565b61109a565b61021e6103a03660046139db565b611901565b3480156103b157600080fd5b506102a5611b29565b3480156103c657600080fd5b506103eb60405180604001604052806005815260200164302e392e3160d81b81525081565b6040516101f59190613a7a565b34801561040457600080fd5b506104186104133660046136d0565b611b87565b6040516101f593929190613a94565b34801561043357600080fd5b5061021e610442366004613ab5565b611c4d565b34801561045357600080fd5b506104676104623660046136d0565b611f52565b6040516101f59190613b07565b34801561048057600080fd5b506102a561048f366004613b4b565b612016565b3480156104a057600080fd5b506104b46104af366004613b86565b612159565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104ed57600080fd5b506101e96104fc3660046136d0565b612211565b34801561050d57600080fd5b5061021e61051c366004613bb2565b612394565b34801561052d57600080fd5b506102a561271081565b34801561054357600080fd5b5061021e610552366004613bf4565b612460565b34801561056357600080fd5b5061021e610572366004613c78565b612b23565b34801561058357600080fd5b50610597610592366004613b86565b612b6f565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105cf57600080fd5b506102a5614e2081565b3480156105e557600080fd5b5061021e6105f4366004613c95565b612c35565b34801561060557600080fd5b506101e9610614366004613b86565b612df8565b34801561062557600080fd5b506102a561138881565b34801561063b57600080fd5b5061026061064a3660046139b9565b612e93565b34801561065b57600080fd5b506102a561066a3660046139b9565b6131ad565b34801561067b57600080fd5b5061021e61068a366004613c78565b613300565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cef565b91509150600061072f85611f52565b90508051600014801561076e575061271061138861074d8585613d29565b6107579190613d3c565b6107619190613d53565b61076b8442613d29565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d75565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d8b565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610801908b908b908b908b90600401613df4565b600060405180830381600087803b15801561081b57600080fd5b505af115801561082f573d6000803e3d6000fd5b50505050847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161086793929190613e48565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061089d5761089d613d75565b600091825260208220600590910201805490925082906108bf90600190613d29565b815481106108cf576108cf613d75565b60009182526020909120600d90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061091c5761091c613d75565b6000918252602082206005909102018054909250829061093e90600190613d29565b8154811061094e5761094e613d75565b60009182526020909120600d90910201600381015460ff16945090508361097957806001015461097c565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190613e8e565b50909350600492506109ff915050565b816004811115610a1157610a11613ef5565b03610a54576000610a2188611f52565b90508051600103610a525780600081518110610a3f57610a3f613d75565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0d9190613e8e565b50935050505080610b605760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd79190613f0b565b15610c155760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610c3957610c39613d75565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c6d57610c6d613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec9190613f26565b5050600087815260078401602052604090205490915060ff16610d36576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e7b565b808603610dab576000868152600683016020526040902054610d59576000610da4565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d9a9190613d3c565b610da49190613d53565b9450610e7b565b600081815260078301602052604090205460ff16610e7b5781600601600083600a01600181548110610ddf57610ddf613d75565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610e1557610e15613d75565b9060005260206000200154815260200190815260200160002054610e399190613f62565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e6e9190613d3c565b610e789190613d53565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610f15576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60026000610f2d61334c565b8054909150600160401b900460ff1680610f54575080546001600160401b03808416911610155b15610f715760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b60016000610fde61334c565b8054909150600160401b900460ff1680611005575080546001600160401b03808416911610155b156110225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b17815561104d8484613370565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b6000828152600360205260409020546002805484929081106110be576110be613d75565b600091825260209091206002600590920201015460ff16156110f25760405162461bcd60e51b81526004016107cf90613d8b565b60008381526003602052604081205460028054909190811061111657611116613d75565b90600052602060002090600502019050806001015483111561117a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb9190613cef565b915091508142101580156111fe57508042105b6112435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a89190613f26565b505090508681036112bd57612710915061133e565b6127106113886112cd8686613d29565b6112d79190613d3c565b6112e19190613d53565b6112eb8542613d29565b106113385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061135190600190613d29565b8154811061136157611361613d75565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156113c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e49190613f75565b6113ee9190613d29565b60008a815260078401602052604090205490915060ff16156114525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190613f75565b905060006127106114d18784613d3c565b6114db9190613d53565b6114e59083613f62565b60008c8152600686016020526040812054919250908211156115965760008c8152600686016020526040902054349061151e9084613d29565b116115435760008c815260068601602052604090205461153e9083613d29565b611545565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161158d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906115c2908490613f62565b909155505060008c8152600686016020526040812080548392906115e7908490613f62565b909155505060008c815260068601602052604090205482116116b95760008c815260068601602052604081205460098701805491929091611629908490613f62565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156118c4578285600901546116d69190613d29565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117489190613f0b565b156117615760028a01805460ff19166001179055611844565b895460038b016000611774876001613f62565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016117ef91815260200190565b602060405180830381865afa15801561180c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118309190613f75565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161189193929190613fc8565b6000604051808303818588803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b50505050505b803411156118f257336108fc6118da8334613d29565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61190a826133a6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061198857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661197c6000805160206144d68339815191525490565b6001600160a01b031614155b156119a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a00575060408051601f3d908101601f191682019092526119fd91810190613f75565b60015b611a2857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b6000805160206144d68339815191528114611a5957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144d68339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611b24576000836001600160a01b031683604051611ac09190614067565b600060405180830381855af49150503d8060008114611afb576040519150601f19603f3d011682016040523d82523d6000602084013e611b00565b606091505b5050905080611b22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611b745760405163703e46dd60e11b815260040160405180910390fd5b506000805160206144d683398151915290565b60028181548110611b9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611bca90613f8e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf690613f8e565b8015611c435780601f10611c1857610100808354040283529160200191611c43565b820191906000526020600020905b815481529060010190602001808311611c2657829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611c7157611c71613d75565b600091825260209091206002600590920201015460ff1615611ca55760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d139190613e8e565b5090935060019250611d23915050565b816004811115611d3557611d35613ef5565b14611d925760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82611dcf5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110611df357611df3613d75565b60009182526020822060059091020180549092508290611e1590600190613d29565b81548110611e2557611e25613d75565b90600052602060002090600d0201905060005b86811015611eeb573382898984818110611e5457611e54613d75565b9050602002013581548110611e6b57611e6b613d75565b60009182526020909120600490910201546001600160a01b031614611ea25760405162461bcd60e51b81526004016107cf90614083565b8582898984818110611eb657611eb6613d75565b9050602002013581548110611ecd57611ecd613d75565b60009182526020909120600160049092020181019190915501611e38565b5086869050816005016000828254611f039190613f62565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611f40908b908b908b906140ba565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611f7857611f78613d75565b60009182526020822060059091020180549092508290611f9a90600190613d29565b81548110611faa57611faa613d75565b90600052602060002090600d0201905080600a0180548060200260200160405190810160405280929190818152602001828054801561200857602002820191906000526020600020905b815481526020019060010190808311611ff4575b505050505092505050919050565b60008581526003602052604081205460028054839290811061203a5761203a613d75565b6000918252602080832089845260036005909302019182019052604082205481549193508391811061206e5761206e613d75565b90600052602060002090600d0201600001868154811061209057612090613d75565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156120ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121129190613f26565b506003850154919350915060ff168015612136575081836002015414806121365750805b156121495761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c8152602001908152602001600020548154811061218a5761218a613d75565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106121be576121be613d75565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061223557612235613d75565b6000918252602082206005909102018054909250829061225790600190613d29565b8154811061226757612267613d75565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e69190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612341573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236591906140de565b505050505091505060008161237b578354612381565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146123be5760405162461bcd60e51b81526004016107cf90614148565b6000836001600160a01b031683836040516123d99190614067565b60006040518083038185875af1925050503d8060008114612416576040519150601f19603f3d011682016040523d82523d6000602084013e61241b565b606091505b5050905080611b225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b60008681526003602052604090205460028054889290811061248457612484613d75565b600091825260209091206002600590920201015460ff16156124b85760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612502573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125269190613e8e565b5090935060029250612536915050565b81600481111561254857612548613ef5565b146125a35760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b856125e55760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b60008881526003602052604081205460028054909190811061260957612609613d75565b9060005260206000209060050201905080600101548611156126645760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b8054600090829061267790600190613d29565b8154811061268757612687613d75565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156126e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127069190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278591906140de565b5050505050915050600061279a8a8a8a610a5e565b905060005b8b8110156129e85733858e8e848181106127bb576127bb613d75565b90506020020135815481106127d2576127d2613d75565b60009182526020909120600490910201546001600160a01b0316146128095760405162461bcd60e51b81526004016107cf90614083565b821580612850575081858e8e8481811061282557612825613d75565b905060200201358154811061283c5761283c613d75565b906000526020600020906004020160010154145b6128d05760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d838181106128e3576128e3613d75565b90506020020135815481106128fa576128fa613d75565b600091825260209091206003600490920201015460ff16156129535760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e8481811061296757612967613d75565b905060200201358154811061297e5761297e613d75565b60009182526020909120600260049092020101556001858e8e848181106129a7576129a7613d75565b90506020020135815481106129be576129be613d75565b60009182526020909120600490910201600301805460ff191691151591909117905560010161279f565b508b8b9050846004016000828254612a009190613f62565b909155505060008a8152600285016020526040812080548d9290612a25908490613f62565b909155505060018401548a03612a5457600384015460ff1615612a4f5760038401805460ff191690555b612acd565b60018401546000908152600285016020526040808220548c835291205403612a9657600384015460ff16612a4f5760038401805460ff19166001179055612acd565b60018401546000908152600285016020526040808220548c83529120541115612acd57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612b0c9392919061418a565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612b4d5760405162461bcd60e51b81526004016107cf90614148565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612b9d57612b9d613d75565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612bd157612bd1613d75565b90600052602060002090600d02016000018781548110612bf357612bf3613d75565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612c5f5760405162461bcd60e51b81526004016107cf906141ba565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612cea85878361424e565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d659190613f75565b612d6f9190613d29565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610867908a908a908a90613e48565b600083815260036020526040812054600280548392908110612e1c57612e1c613d75565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612e5057612e50613d75565b90600052602060002090600d02016000018481548110612e7257612e72613d75565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ec05760405162461bcd60e51b81526004016107cf906141ba565b600083815260036020526040902054600280548592908110612ee457612ee4613d75565b600091825260209091206002600590920201015460ff1615612f185760405162461bcd60e51b81526004016107cf90613d8b565b600084815260036020526040812054600280549091908110612f3c57612f3c613d75565b60009182526020822060059091020180549092508290612f5e90600190613d29565b81548110612f6e57612f6e613d75565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff7919061430e565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306a9190613e8e565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156130ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f2919061430e565b96506130ff848a896133d3565b1561319c57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556131a1565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106131d1576131d1613d75565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061320557613205613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015613264573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132889190613f26565b50915091508260040154600014806132b75750801580156132b757506000828152600284016020526040902054155b156132c95760009450505050506132fa565b80156132de5750506004015491506132fa9050565b5060009081526002909101602052604090205491506132fa9050565b92915050565b6000546001600160a01b0316331461332a5760405162461bcd60e51b81526004016107cf90614148565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b61337861368f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146133d05760405162461bcd60e51b81526004016107cf90614148565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134459190613e8e565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156134a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c89190613f75565b6134d29190613d29565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613513573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261353b91908101906143be565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613597573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135bb919061430e565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613612573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613636919061449f565b50509150915082816136489190613f62565b60045490831015955060ff16156136845784801561368157506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b6136976136b6565b6136b457604051631afcd79f60e31b815260040160405180910390fd5b565b60006136c061334c565b54600160401b900460ff16919050565b6000602082840312156136e257600080fd5b5035919050565b60008083601f8401126136fb57600080fd5b5081356001600160401b0381111561371257600080fd5b6020830191508360208260051b850101111561372d57600080fd5b9250929050565b60008083601f84011261374657600080fd5b5081356001600160401b0381111561375d57600080fd5b60208301915083602082850101111561372d57600080fd5b600080600080600080600060a0888a03121561379057600080fd5b8735965060208801356001600160401b03808211156137ae57600080fd5b6137ba8b838c016136e9565b909850965060408a0135955060608a0135945060808a01359150808211156137e157600080fd5b506137ee8a828b01613734565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561383a5761383a613801565b60405290565b604051601f8201601f191681016001600160401b038111828210171561386857613868613801565b604052919050565b600082601f83011261388157600080fd5b81356001600160401b0381111561389a5761389a613801565b6138ad601f8201601f1916602001613840565b8181528460208386010111156138c257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138f457600080fd5b833592506020840135915060408401356001600160401b0381111561391857600080fd5b61392486828701613870565b9150509250925092565b6001600160a01b03811681146133d057600080fd5b6000806000806080858703121561395957600080fd5b84359350602085013561396b8161392e565b93969395505050506040820135916060013590565b6000806040838503121561399357600080fd5b823561399e8161392e565b915060208301356139ae8161392e565b809150509250929050565b600080604083850312156139cc57600080fd5b50508035926020909101359150565b600080604083850312156139ee57600080fd5b82356139f98161392e565b915060208301356001600160401b03811115613a1457600080fd5b613a2085828601613870565b9150509250929050565b60005b83811015613a45578181015183820152602001613a2d565b50506000910152565b60008151808452613a66816020860160208601613a2a565b601f01601f19169290920160200192915050565b602081526000613a8d6020830184613a4e565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a4e565b60008060008060608587031215613acb57600080fd5b8435935060208501356001600160401b03811115613ae857600080fd5b613af4878288016136e9565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b3f57835183529284019291840191600101613b23565b50909695505050505050565b600080600080600060a08688031215613b6357600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b9b57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613bc757600080fd5b8335613bd28161392e565b92506020840135915060408401356001600160401b0381111561391857600080fd5b60008060008060008060a08789031215613c0d57600080fd5b8635955060208701356001600160401b0380821115613c2b57600080fd5b613c378a838b016136e9565b909750955060408901359450606089013593506080890135915080821115613c5e57600080fd5b50613c6b89828a01613870565b9150509295509295509295565b600060208284031215613c8a57600080fd5b8135613a8d8161392e565b600080600080600060808688031215613cad57600080fd5b853594506020860135935060408601356001600160401b03811115613cd157600080fd5b613cdd88828901613734565b96999598509660600135949350505050565b60008060408385031215613d0257600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b818103818111156132fa576132fa613d13565b80820281158282048414176132fa576132fa613d13565b600082613d7057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613ddb57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613e0e606083018587613dc2565b905082604083015295945050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613e1f565b80516001600160601b0381168114613e7957600080fd5b919050565b80518015158114613e7957600080fd5b600080600080600060a08688031215613ea657600080fd5b613eaf86613e62565b94506020860151613ebf8161392e565b604087015190945060058110613ed457600080fd5b9250613ee260608701613e7e565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613f1d57600080fd5b613a8d82613e7e565b600080600060608486031215613f3b57600080fd5b83519250613f4b60208501613e7e565b9150613f5960408501613e7e565b90509250925092565b808201808211156132fa576132fa613d13565b600060208284031215613f8757600080fd5b5051919050565b600181811c90821680613fa257607f821691505b602082108103613fc257634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613fe981613f8e565b806060870152608060018084166000811461400b576001811461402757614057565b60ff19851660808a0152608084151560051b8a01019550614057565b89600052602060002060005b8581101561404e5781548b8201860152908301908801614033565b8a016080019650505b50939a9950505050505050505050565b60008251614079818460208701613a2a565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6040815260006140ce604083018587613dc2565b9050826020830152949350505050565b600080600080600080600060e0888a0312156140f957600080fd5b61410288613e62565b965061411060208901613e7e565b955060408801519450606088015193506080880151925060a0880151915061413a60c08901613e7e565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60408152600061419e604083018587613dc2565b82810360208401526141b08185613a4e565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611b24576000816000526020600020601f850160051c810160208610156142275750805b601f850160051c820191505b8181101561424657828155600101614233565b505050505050565b6001600160401b0383111561426557614265613801565b614279836142738354613f8e565b836141fe565b6000601f8411600181146142ad57600085156142955750838201355b600019600387901b1c1916600186901b178355614307565b600083815260209020601f19861690835b828110156142de57868501358255602094850194600190920191016142be565b50868210156142fb5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561432057600080fd5b8151613a8d8161392e565b600082601f83011261433c57600080fd5b815160206001600160401b0382111561435757614357613801565b8160051b614366828201613840565b928352848101820192828101908785111561438057600080fd5b83870192505b848310156143a85782516143998161392e565b82529183019190830190614386565b979650505050505050565b8051613e798161392e565b6000602082840312156143d057600080fd5b81516001600160401b03808211156143e757600080fd5b9083019061016082860312156143fc57600080fd5b614404613817565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561444c57600080fd5b6144588782860161432b565b60c08301525060e08381015190820152610100808401519082015261012091506144838284016143b3565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156144b557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212202ec8f9386176b2ca726899fd0a6a21acb3ebb48958caaa7e6fab6be5a1dfa56f64736f6c63430008180033", - "deployedBytecode": "0x6080604052600436106101c45760003560e01c806365540b96116100f8578063b34bfaa811610090578063b34bfaa8146105c3578063b6ede540146105d9578063ba66fde7146105f9578063be46760414610619578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad3014610521578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b806365540b9614610447578063675926f61461047457806369f3f041146104945780636d4cd8ea146104e1578063751accd014610501578063796490f9146105215780637c04034e146105375780638e42646014610557578063a7cc08fe1461057757600080fd5b8063362c34791161016b578063362c34791461032a578063472abf681461034a578063485cc9551461035f5780634b2f0ea01461037f5780634f1ef2861461039257806352d1902d146103a557806354fd4d50146103ba578063564a565d146103f85780635c92e2f61461042757600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136d0565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613775565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136d0565b610879565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136d0565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136d0565b6108f0565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138df565b610a5e565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613943565b610a9b565b34801561035657600080fd5b5061021e610f21565b34801561036b57600080fd5b5061021e61037a366004613980565b610fd2565b61021e61038d3660046139b9565b61109a565b61021e6103a03660046139db565b611901565b3480156103b157600080fd5b506102a5611b29565b3480156103c657600080fd5b506103eb60405180604001604052806005815260200164302e392e3160d81b81525081565b6040516101f59190613a7a565b34801561040457600080fd5b506104186104133660046136d0565b611b87565b6040516101f593929190613a94565b34801561043357600080fd5b5061021e610442366004613ab5565b611c4d565b34801561045357600080fd5b506104676104623660046136d0565b611f52565b6040516101f59190613b07565b34801561048057600080fd5b506102a561048f366004613b4b565b612016565b3480156104a057600080fd5b506104b46104af366004613b86565b612159565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104ed57600080fd5b506101e96104fc3660046136d0565b612211565b34801561050d57600080fd5b5061021e61051c366004613bb2565b612394565b34801561052d57600080fd5b506102a561271081565b34801561054357600080fd5b5061021e610552366004613bf4565b612460565b34801561056357600080fd5b5061021e610572366004613c78565b612b23565b34801561058357600080fd5b50610597610592366004613b86565b612b6f565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105cf57600080fd5b506102a5614e2081565b3480156105e557600080fd5b5061021e6105f4366004613c95565b612c35565b34801561060557600080fd5b506101e9610614366004613b86565b612df8565b34801561062557600080fd5b506102a561138881565b34801561063b57600080fd5b5061026061064a3660046139b9565b612e93565b34801561065b57600080fd5b506102a561066a3660046139b9565b6131ad565b34801561067b57600080fd5b5061021e61068a366004613c78565b613300565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cef565b91509150600061072f85611f52565b90508051600014801561076e575061271061138861074d8585613d29565b6107579190613d3c565b6107619190613d53565b61076b8442613d29565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d75565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d8b565b60405180910390fd5b604051632e49717b60e11b81523090635c92e2f690610801908b908b908b908b90600401613df4565b600060405180830381600087803b15801561081b57600080fd5b505af115801561082f573d6000803e3d6000fd5b50505050847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161086793929190613e48565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061089d5761089d613d75565b600091825260208220600590910201805490925082906108bf90600190613d29565b815481106108cf576108cf613d75565b60009182526020909120600d90910201805460059091015414949350505050565b600080600080600260036000878152602001908152602001600020548154811061091c5761091c613d75565b6000918252602082206005909102018054909250829061093e90600190613d29565b8154811061094e5761094e613d75565b60009182526020909120600d90910201600381015460ff16945090508361097957806001015461097c565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190613e8e565b50909350600492506109ff915050565b816004811115610a1157610a11613ef5565b03610a54576000610a2188611f52565b90508051600103610a525780600081518110610a3f57610a3f613d75565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0d9190613e8e565b50935050505080610b605760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd79190613f0b565b15610c155760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610c3957610c39613d75565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c6d57610c6d613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec9190613f26565b5050600087815260078401602052604090205490915060ff16610d36576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e7b565b808603610dab576000868152600683016020526040902054610d59576000610da4565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d9a9190613d3c565b610da49190613d53565b9450610e7b565b600081815260078301602052604090205460ff16610e7b5781600601600083600a01600181548110610ddf57610ddf613d75565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610e1557610e15613d75565b9060005260206000200154815260200190815260200160002054610e399190613f62565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e6e9190613d3c565b610e789190613d53565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610f15576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60026000610f2d61334c565b8054909150600160401b900460ff1680610f54575080546001600160401b03808416911610155b15610f715760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b60016000610fde61334c565b8054909150600160401b900460ff1680611005575080546001600160401b03808416911610155b156110225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b17815561104d8484613370565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b6000828152600360205260409020546002805484929081106110be576110be613d75565b600091825260209091206002600590920201015460ff16156110f25760405162461bcd60e51b81526004016107cf90613d8b565b60008381526003602052604081205460028054909190811061111657611116613d75565b90600052602060002090600502019050806001015483111561117a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb9190613cef565b915091508142101580156111fe57508042105b6112435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611284573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a89190613f26565b505090508681036112bd57612710915061133e565b6127106113886112cd8686613d29565b6112d79190613d3c565b6112e19190613d53565b6112eb8542613d29565b106113385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061135190600190613d29565b8154811061136157611361613d75565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156113c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e49190613f75565b6113ee9190613d29565b60008a815260078401602052604090205490915060ff16156114525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561149c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c09190613f75565b905060006127106114d18784613d3c565b6114db9190613d53565b6114e59083613f62565b60008c8152600686016020526040812054919250908211156115965760008c8152600686016020526040902054349061151e9084613d29565b116115435760008c815260068601602052604090205461153e9083613d29565b611545565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161158d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906115c2908490613f62565b909155505060008c8152600686016020526040812080548392906115e7908490613f62565b909155505060008c815260068601602052604090205482116116b95760008c815260068601602052604081205460098701805491929091611629908490613f62565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156118c4578285600901546116d69190613d29565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611724573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117489190613f0b565b156117615760028a01805460ff19166001179055611844565b895460038b016000611774876001613f62565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016117ef91815260200190565b602060405180830381865afa15801561180c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118309190613f75565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161189193929190613fc8565b6000604051808303818588803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b50505050505b803411156118f257336108fc6118da8334613d29565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61190a826133a6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061198857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661197c6000805160206144d68339815191525490565b6001600160a01b031614155b156119a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a00575060408051601f3d908101601f191682019092526119fd91810190613f75565b60015b611a2857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b6000805160206144d68339815191528114611a5957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144d68339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611b24576000836001600160a01b031683604051611ac09190614067565b600060405180830381855af49150503d8060008114611afb576040519150601f19603f3d011682016040523d82523d6000602084013e611b00565b606091505b5050905080611b22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611b745760405163703e46dd60e11b815260040160405180910390fd5b506000805160206144d683398151915290565b60028181548110611b9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611bca90613f8e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf690613f8e565b8015611c435780601f10611c1857610100808354040283529160200191611c43565b820191906000526020600020905b815481529060010190602001808311611c2657829003601f168201915b5050505050905083565b600084815260036020526040902054600280548692908110611c7157611c71613d75565b600091825260209091206002600590920201015460ff1615611ca55760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015611cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d139190613e8e565b5090935060019250611d23915050565b816004811115611d3557611d35613ef5565b14611d925760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82611dcf5760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110611df357611df3613d75565b60009182526020822060059091020180549092508290611e1590600190613d29565b81548110611e2557611e25613d75565b90600052602060002090600d0201905060005b86811015611eeb573382898984818110611e5457611e54613d75565b9050602002013581548110611e6b57611e6b613d75565b60009182526020909120600490910201546001600160a01b031614611ea25760405162461bcd60e51b81526004016107cf90614083565b8582898984818110611eb657611eb6613d75565b9050602002013581548110611ecd57611ecd613d75565b60009182526020909120600160049092020181019190915501611e38565b5086869050816005016000828254611f039190613f62565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890611f40908b908b908b906140ba565b60405180910390a35050505050505050565b6000818152600360205260408120546002805460609392908110611f7857611f78613d75565b60009182526020822060059091020180549092508290611f9a90600190613d29565b81548110611faa57611faa613d75565b90600052602060002090600d0201905080600a0180548060200260200160405190810160405280929190818152602001828054801561200857602002820191906000526020600020905b815481526020019060010190808311611ff4575b505050505092505050919050565b60008581526003602052604081205460028054839290811061203a5761203a613d75565b6000918252602080832089845260036005909302019182019052604082205481549193508391811061206e5761206e613d75565b90600052602060002090600d0201600001868154811061209057612090613d75565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa1580156120ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121129190613f26565b506003850154919350915060ff168015612136575081836002015414806121365750805b156121495761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c8152602001908152602001600020548154811061218a5761218a613d75565b600091825260208083208c84526003600590930201918201905260408220548154919350839181106121be576121be613d75565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061223557612235613d75565b6000918252602082206005909102018054909250829061225790600190613d29565b8154811061226757612267613d75565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e69190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612341573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236591906140de565b505050505091505060008161237b578354612381565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146123be5760405162461bcd60e51b81526004016107cf90614148565b6000836001600160a01b031683836040516123d99190614067565b60006040518083038185875af1925050503d8060008114612416576040519150601f19603f3d011682016040523d82523d6000602084013e61241b565b606091505b5050905080611b225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b60008681526003602052604090205460028054889290811061248457612484613d75565b600091825260209091206002600590920201015460ff16156124b85760405162461bcd60e51b81526004016107cf90613d8b565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612502573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125269190613e8e565b5090935060029250612536915050565b81600481111561254857612548613ef5565b146125a35760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b856125e55760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b60008881526003602052604081205460028054909190811061260957612609613d75565b9060005260206000209060050201905080600101548611156126645760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b8054600090829061267790600190613d29565b8154811061268757612687613d75565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa1580156126e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127069190613e8e565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278591906140de565b5050505050915050600061279a8a8a8a610a5e565b905060005b8b8110156129e85733858e8e848181106127bb576127bb613d75565b90506020020135815481106127d2576127d2613d75565b60009182526020909120600490910201546001600160a01b0316146128095760405162461bcd60e51b81526004016107cf90614083565b821580612850575081858e8e8481811061282557612825613d75565b905060200201358154811061283c5761283c613d75565b906000526020600020906004020160010154145b6128d05760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d838181106128e3576128e3613d75565b90506020020135815481106128fa576128fa613d75565b600091825260209091206003600490920201015460ff16156129535760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e8481811061296757612967613d75565b905060200201358154811061297e5761297e613d75565b60009182526020909120600260049092020101556001858e8e848181106129a7576129a7613d75565b90506020020135815481106129be576129be613d75565b60009182526020909120600490910201600301805460ff191691151591909117905560010161279f565b508b8b9050846004016000828254612a009190613f62565b909155505060008a8152600285016020526040812080548d9290612a25908490613f62565b909155505060018401548a03612a5457600384015460ff1615612a4f5760038401805460ff191690555b612acd565b60018401546000908152600285016020526040808220548c835291205403612a9657600384015460ff16612a4f5760038401805460ff19166001179055612acd565b60018401546000908152600285016020526040808220548c83529120541115612acd57600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d604051612b0c9392919061418a565b60405180910390a450505050505050505050505050565b6000546001600160a01b03163314612b4d5760405162461bcd60e51b81526004016107cf90614148565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a81526020019081526020016000205481548110612b9d57612b9d613d75565b600091825260208083208a8452600360059093020191820190526040822054815491935083918110612bd157612bd1613d75565b90600052602060002090600d02016000018781548110612bf357612bf3613d75565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b03163314612c5f5760405162461bcd60e51b81526004016107cf906141ba565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612cea85878361424e565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d659190613f75565b612d6f9190613d29565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610867908a908a908a90613e48565b600083815260036020526040812054600280548392908110612e1c57612e1c613d75565b60009182526020808320878452600360059093020191820190526040822054815491935083918110612e5057612e50613d75565b90600052602060002090600d02016000018481548110612e7257612e72613d75565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b03163314612ec05760405162461bcd60e51b81526004016107cf906141ba565b600083815260036020526040902054600280548592908110612ee457612ee4613d75565b600091825260209091206002600590920201015460ff1615612f185760405162461bcd60e51b81526004016107cf90613d8b565b600084815260036020526040812054600280549091908110612f3c57612f3c613d75565b60009182526020822060059091020180549092508290612f5e90600190613d29565b81548110612f6e57612f6e613d75565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612fd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ff7919061430e565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306a9190613e8e565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156130ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f2919061430e565b96506130ff848a896133d3565b1561319c57604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556131a1565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106131d1576131d1613d75565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061320557613205613d75565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015613264573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132889190613f26565b50915091508260040154600014806132b75750801580156132b757506000828152600284016020526040902054155b156132c95760009450505050506132fa565b80156132de5750506004015491506132fa9050565b5060009081526002909101602052604090205491506132fa9050565b92915050565b6000546001600160a01b0316331461332a5760405162461bcd60e51b81526004016107cf90614148565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b61337861368f565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b031633146133d05760405162461bcd60e51b81526004016107cf90614148565b50565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015613421573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134459190613e8e565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa1580156134a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c89190613f75565b6134d29190613d29565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa158015613513573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261353b91908101906143be565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613597573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135bb919061430e565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa158015613612573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613636919061449f565b50509150915082816136489190613f62565b60045490831015955060ff16156136845784801561368157506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b6136976136b6565b6136b457604051631afcd79f60e31b815260040160405180910390fd5b565b60006136c061334c565b54600160401b900460ff16919050565b6000602082840312156136e257600080fd5b5035919050565b60008083601f8401126136fb57600080fd5b5081356001600160401b0381111561371257600080fd5b6020830191508360208260051b850101111561372d57600080fd5b9250929050565b60008083601f84011261374657600080fd5b5081356001600160401b0381111561375d57600080fd5b60208301915083602082850101111561372d57600080fd5b600080600080600080600060a0888a03121561379057600080fd5b8735965060208801356001600160401b03808211156137ae57600080fd5b6137ba8b838c016136e9565b909850965060408a0135955060608a0135945060808a01359150808211156137e157600080fd5b506137ee8a828b01613734565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561383a5761383a613801565b60405290565b604051601f8201601f191681016001600160401b038111828210171561386857613868613801565b604052919050565b600082601f83011261388157600080fd5b81356001600160401b0381111561389a5761389a613801565b6138ad601f8201601f1916602001613840565b8181528460208386010111156138c257600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138f457600080fd5b833592506020840135915060408401356001600160401b0381111561391857600080fd5b61392486828701613870565b9150509250925092565b6001600160a01b03811681146133d057600080fd5b6000806000806080858703121561395957600080fd5b84359350602085013561396b8161392e565b93969395505050506040820135916060013590565b6000806040838503121561399357600080fd5b823561399e8161392e565b915060208301356139ae8161392e565b809150509250929050565b600080604083850312156139cc57600080fd5b50508035926020909101359150565b600080604083850312156139ee57600080fd5b82356139f98161392e565b915060208301356001600160401b03811115613a1457600080fd5b613a2085828601613870565b9150509250929050565b60005b83811015613a45578181015183820152602001613a2d565b50506000910152565b60008151808452613a66816020860160208601613a2a565b601f01601f19169290920160200192915050565b602081526000613a8d6020830184613a4e565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a4e565b60008060008060608587031215613acb57600080fd5b8435935060208501356001600160401b03811115613ae857600080fd5b613af4878288016136e9565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b3f57835183529284019291840191600101613b23565b50909695505050505050565b600080600080600060a08688031215613b6357600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b9b57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613bc757600080fd5b8335613bd28161392e565b92506020840135915060408401356001600160401b0381111561391857600080fd5b60008060008060008060a08789031215613c0d57600080fd5b8635955060208701356001600160401b0380821115613c2b57600080fd5b613c378a838b016136e9565b909750955060408901359450606089013593506080890135915080821115613c5e57600080fd5b50613c6b89828a01613870565b9150509295509295509295565b600060208284031215613c8a57600080fd5b8135613a8d8161392e565b600080600080600060808688031215613cad57600080fd5b853594506020860135935060408601356001600160401b03811115613cd157600080fd5b613cdd88828901613734565b96999598509660600135949350505050565b60008060408385031215613d0257600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b818103818111156132fa576132fa613d13565b80820281158282048414176132fa576132fa613d13565b600082613d7057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835260006001600160fb1b03831115613ddb57600080fd5b8260051b80836020870137939093016020019392505050565b848152606060208201526000613e0e606083018587613dc2565b905082604083015295945050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613e1f565b80516001600160601b0381168114613e7957600080fd5b919050565b80518015158114613e7957600080fd5b600080600080600060a08688031215613ea657600080fd5b613eaf86613e62565b94506020860151613ebf8161392e565b604087015190945060058110613ed457600080fd5b9250613ee260608701613e7e565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613f1d57600080fd5b613a8d82613e7e565b600080600060608486031215613f3b57600080fd5b83519250613f4b60208501613e7e565b9150613f5960408501613e7e565b90509250925092565b808201808211156132fa576132fa613d13565b600060208284031215613f8757600080fd5b5051919050565b600181811c90821680613fa257607f821691505b602082108103613fc257634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613fe981613f8e565b806060870152608060018084166000811461400b576001811461402757614057565b60ff19851660808a0152608084151560051b8a01019550614057565b89600052602060002060005b8581101561404e5781548b8201860152908301908801614033565b8a016080019650505b50939a9950505050505050505050565b60008251614079818460208701613a2a565b9190910192915050565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b6040815260006140ce604083018587613dc2565b9050826020830152949350505050565b600080600080600080600060e0888a0312156140f957600080fd5b61410288613e62565b965061411060208901613e7e565b955060408801519450606088015193506080880151925060a0880151915061413a60c08901613e7e565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60408152600061419e604083018587613dc2565b82810360208401526141b08185613a4e565b9695505050505050565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611b24576000816000526020600020601f850160051c810160208610156142275750805b601f850160051c820191505b8181101561424657828155600101614233565b505050505050565b6001600160401b0383111561426557614265613801565b614279836142738354613f8e565b836141fe565b6000601f8411600181146142ad57600085156142955750838201355b600019600387901b1c1916600186901b178355614307565b600083815260209020601f19861690835b828110156142de57868501358255602094850194600190920191016142be565b50868210156142fb5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561432057600080fd5b8151613a8d8161392e565b600082601f83011261433c57600080fd5b815160206001600160401b0382111561435757614357613801565b8160051b614366828201613840565b928352848101820192828101908785111561438057600080fd5b83870192505b848310156143a85782516143998161392e565b82529183019190830190614386565b979650505050505050565b8051613e798161392e565b6000602082840312156143d057600080fd5b81516001600160401b03808211156143e757600080fd5b9083019061016082860312156143fc57600080fd5b614404613817565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c08301518281111561444c57600080fd5b6144588782860161432b565b60c08301525060e08381015190820152610100808401519082015261012091506144838284016143b3565b9181019190915261014091820151918101919091529392505050565b600080600080608085870312156144b557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212202ec8f9386176b2ca726899fd0a6a21acb3ebb48958caaa7e6fab6be5a1dfa56f64736f6c63430008180033", + "numDeployments": 3, + "solcInputHash": "525260efd109be98dd6a976c1b7235d3", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"CommitCastShutter\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"castCommitShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize4\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"CommitCastShutter(bytes32,bytes32,bytes)\":{\"details\":\"Emitted when a vote is cast.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castCommitShutter(uint256,uint256[],bytes32,bytes32,bytes)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash including the justification.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encoding\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":\"DisputeKitShutter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(uint256 _coreDisputeID, uint256[] calldata _voteIDs, bytes32 _commit) external {\\n _castCommit(_coreDisputeID, _voteIDs, _commit);\\n }\\n\\n function _castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external {\\n _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification);\\n }\\n\\n function _castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf11760d6d9407a37f0d0fc7adc7ec1a5056c167bffc1c1c785247909fcf64cc4\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitShutter\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\n/// Added functionality: an Shutter-specific event emitted when a vote is cast.\\ncontract DisputeKitShutter is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.2\\\";\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev Emitted when a vote is cast.\\n /// @param _commit The commitment hash.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity, bytes _encryptedVote);\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize4() external reinitializer(4) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash including the justification.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n function castCommitShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit,\\n bytes32 _identity,\\n bytes calldata _encryptedVote\\n ) external notJumped(_coreDisputeID) {\\n _castCommit(_coreDisputeID, _voteIDs, _commit);\\n emit CommitCastShutter(_commit, _identity, _encryptedVote);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure override returns (bytes32) {\\n bytes32 justificationHash = keccak256(bytes(_justification));\\n return keccak256(abi.encode(_choice, _salt, justificationHash));\\n }\\n}\\n\",\"keccak256\":\"0x68706bd6beb162156f5a73c7c9ca4f79bc211169e082b9fbf5747ea67859e5c7\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6080516144cb62000103600039600081816118150152818161183e0152611a3601526144cb6000f3fe6080604052600436106101c45760003560e01c8063675926f6116100f8578063b6ede54011610090578063b6ede540146105c4578063ba66fde7146105e4578063be46760414610604578063caeb50ed1461061a578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad301461050c578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b8063675926f61461045f57806369f3f0411461047f5780636d4cd8ea146104cc578063751accd0146104ec578063796490f91461050c5780637c04034e146105225780638e42646014610542578063a7cc08fe14610562578063b34bfaa8146105ae57600080fd5b8063362c34791161016b578063362c34791461032a578063485cc9551461034a5780634b2f0ea01461036a5780634f1ef2861461037d57806352d1902d1461039057806354fd4d50146103a5578063564a565d146103e35780635c92e2f61461041257806365540b961461043257600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136a3565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613748565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136a3565b61082a565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136a3565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136a3565b6108a1565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138b2565b610a0f565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613916565b610a4c565b34801561035657600080fd5b5061021e610365366004613953565b610ed2565b61021e61037836600461398c565b610f9a565b61021e61038b3660046139ae565b611801565b34801561039c57600080fd5b506102a5611a29565b3480156103b157600080fd5b506103d66040518060400160405280600581526020016418171c971960d91b81525081565b6040516101f59190613a4d565b3480156103ef57600080fd5b506104036103fe3660046136a3565b611a87565b6040516101f593929190613a67565b34801561041e57600080fd5b5061021e61042d366004613a88565b611b4d565b34801561043e57600080fd5b5061045261044d3660046136a3565b611b59565b6040516101f59190613ada565b34801561046b57600080fd5b506102a561047a366004613b1e565b611c1d565b34801561048b57600080fd5b5061049f61049a366004613b59565b611d60565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104d857600080fd5b506101e96104e73660046136a3565b611e18565b3480156104f857600080fd5b5061021e610507366004613b85565b611f9b565b34801561051857600080fd5b506102a561271081565b34801561052e57600080fd5b5061021e61053d366004613bc7565b612067565b34801561054e57600080fd5b5061021e61055d366004613c4b565b61207d565b34801561056e57600080fd5b5061058261057d366004613b59565b6120c9565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105ba57600080fd5b506102a5614e2081565b3480156105d057600080fd5b5061021e6105df366004613c68565b61218f565b3480156105f057600080fd5b506101e96105ff366004613b59565b612352565b34801561061057600080fd5b506102a561138881565b34801561062657600080fd5b5061021e6123ed565b34801561063b57600080fd5b5061026061064a36600461398c565b61249e565b34801561065b57600080fd5b506102a561066a36600461398c565b6127b8565b34801561067b57600080fd5b5061021e61068a366004613c4b565b61290b565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cc2565b91509150600061072f85611b59565b90508051600014801561076e575061271061138861074d8585613cfc565b6107579190613d0f565b6107619190613d26565b61076b8442613cfc565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d48565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d5e565b60405180910390fd5b6107e488888888612957565b847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161081893929190613dbe565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061084e5761084e613d48565b6000918252602082206005909102018054909250829061087090600190613cfc565b8154811061088057610880613d48565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106108cd576108cd613d48565b600091825260208220600590910201805490925082906108ef90600190613cfc565b815481106108ff576108ff613d48565b60009182526020909120600d90910201600381015460ff16945090508361092a57806001015461092d565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a09190613e04565b50909350600492506109b0915050565b8160048111156109c2576109c2613e6b565b03610a055760006109d288611b59565b90508051600103610a0357806000815181106109f0576109f0613d48565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190613e04565b50935050505080610b115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b889190613e81565b15610bc65760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610bea57610bea613d48565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c1e57610c1e613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190613e9c565b5050600087815260078401602052604090205490915060ff16610ce7576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e2c565b808603610d5c576000868152600683016020526040902054610d0a576000610d55565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d4b9190613d0f565b610d559190613d26565b9450610e2c565b600081815260078301602052604090205460ff16610e2c5781600601600083600a01600181548110610d9057610d90613d48565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610dc657610dc6613d48565b9060005260206000200154815260200190815260200160002054610dea9190613ed8565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e1f9190613d0f565b610e299190613d26565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ec6576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610ede612c5c565b8054909150600160401b900460ff1680610f05575080546001600160401b03808416911610155b15610f225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f4d8484612c80565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fbe57610fbe613d48565b600091825260209091206002600590920201015460ff1615610ff25760405162461bcd60e51b81526004016107cf90613d5e565b60008381526003602052604081205460028054909190811061101657611016613d48565b90600052602060002090600502019050806001015483111561107a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156110c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110eb9190613cc2565b915091508142101580156110fe57508042105b6111435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611184573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a89190613e9c565b505090508681036111bd57612710915061123e565b6127106113886111cd8686613cfc565b6111d79190613d0f565b6111e19190613d26565b6111eb8542613cfc565b106112385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061125190600190613cfc565b8154811061126157611261613d48565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190613eeb565b6112ee9190613cfc565b60008a815260078401602052604090205490915060ff16156113525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561139c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c09190613eeb565b905060006127106113d18784613d0f565b6113db9190613d26565b6113e59083613ed8565b60008c8152600686016020526040812054919250908211156114965760008c8152600686016020526040902054349061141e9084613cfc565b116114435760008c815260068601602052604090205461143e9083613cfc565b611445565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161148d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906114c2908490613ed8565b909155505060008c8152600686016020526040812080548392906114e7908490613ed8565b909155505060008c815260068601602052604090205482116115b95760008c815260068601602052604081205460098701805491929091611529908490613ed8565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156117c4578285600901546115d69190613cfc565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116489190613e81565b156116615760028a01805460ff19166001179055611744565b895460038b016000611674876001613ed8565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016116ef91815260200190565b602060405180830381865afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117309190613eeb565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161179193929190613f3e565b6000604051808303818588803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b50505050505b803411156117f257336108fc6117da8334613cfc565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61180a82612cb6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061188857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661187c6000805160206144768339815191525490565b6001600160a01b031614155b156118a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611900575060408051601f3d908101601f191682019092526118fd91810190613eeb565b60015b61192857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b600080516020614476833981519152811461195957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144768339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a24576000836001600160a01b0316836040516119c09190613fdd565b600060405180830381855af49150503d80600081146119fb576040519150601f19603f3d011682016040523d82523d6000602084013e611a00565b606091505b5050905080611a22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a745760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061447683398151915290565b60028181548110611a9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611aca90613f04565b80601f0160208091040260200160405190810160405280929190818152602001828054611af690613f04565b8015611b435780601f10611b1857610100808354040283529160200191611b43565b820191906000526020600020905b815481529060010190602001808311611b2657829003601f168201915b5050505050905083565b611a2284848484612957565b6000818152600360205260408120546002805460609392908110611b7f57611b7f613d48565b60009182526020822060059091020180549092508290611ba190600190613cfc565b81548110611bb157611bb1613d48565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c0f57602002820191906000526020600020905b815481526020019060010190808311611bfb575b505050505092505050919050565b600085815260036020526040812054600280548392908110611c4157611c41613d48565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611c7557611c75613d48565b90600052602060002090600d02016000018681548110611c9757611c97613d48565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d199190613e9c565b506003850154919350915060ff168015611d3d57508183600201541480611d3d5750805b15611d505761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611d9157611d91613d48565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611dc557611dc5613d48565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611e3c57611e3c613d48565b60009182526020822060059091020180549092508290611e5e90600190613cfc565b81548110611e6e57611e6e613d48565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015611ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eed9190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015611f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6c9190613ff9565b5050505050915050600081611f82578354611f88565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b03163314611fc55760405162461bcd60e51b81526004016107cf90614063565b6000836001600160a01b03168383604051611fe09190613fdd565b60006040518083038185875af1925050503d806000811461201d576040519150601f19603f3d011682016040523d82523d6000602084013e612022565b606091505b5050905080611a225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b612075868686868686612ce3565b505050505050565b6000546001600160a01b031633146120a75760405162461bcd60e51b81526004016107cf90614063565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106120f7576120f7613d48565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061212b5761212b613d48565b90600052602060002090600d0201600001878154811061214d5761214d613d48565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146121b95760405162461bcd60e51b81526004016107cf906140a5565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612244858783614131565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561229b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bf9190613eeb565b6122c99190613cfc565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610818908a908a908a90613dbe565b60008381526003602052604081205460028054839290811061237657612376613d48565b600091825260208083208784526003600590930201918201905260408220548154919350839181106123aa576123aa613d48565b90600052602060002090600d020160000184815481106123cc576123cc613d48565b600091825260209091206004909102016003015460ff169695505050505050565b600460006123f9612c5c565b8054909150600160401b900460ff1680612420575080546001600160401b03808416911610155b1561243d5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b6001546000906001600160a01b031633146124cb5760405162461bcd60e51b81526004016107cf906140a5565b6000838152600360205260409020546002805485929081106124ef576124ef613d48565b600091825260209091206002600590920201015460ff16156125235760405162461bcd60e51b81526004016107cf90613d5e565b60008481526003602052604081205460028054909190811061254757612547613d48565b6000918252602082206005909102018054909250829061256990600190613cfc565b8154811061257957612579613d48565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260291906141f1565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126759190613e04565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd91906141f1565b965061270a848a896133a6565b156127a757604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556127ac565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106127dc576127dc613d48565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061281057612810613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190613e9c565b50915091508260040154600014806128c25750801580156128c257506000828152600284016020526040902054155b156128d4576000945050505050612905565b80156128e95750506004015491506129059050565b5060009081526002909101602052604090205491506129059050565b92915050565b6000546001600160a01b031633146129355760405162461bcd60e51b81526004016107cf90614063565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008481526003602052604090205460028054869290811061297b5761297b613d48565b600091825260209091206002600590920201015460ff16156129af5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa1580156129f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1d9190613e04565b5090935060019250612a2d915050565b816004811115612a3f57612a3f613e6b565b14612a9c5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82612ad95760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110612afd57612afd613d48565b60009182526020822060059091020180549092508290612b1f90600190613cfc565b81548110612b2f57612b2f613d48565b90600052602060002090600d0201905060005b86811015612bf5573382898984818110612b5e57612b5e613d48565b9050602002013581548110612b7557612b75613d48565b60009182526020909120600490910201546001600160a01b031614612bac5760405162461bcd60e51b81526004016107cf9061420e565b8582898984818110612bc057612bc0613d48565b9050602002013581548110612bd757612bd7613d48565b60009182526020909120600160049092020181019190915501612b42565b5086869050816005016000828254612c0d9190613ed8565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612c4a908b908b908b90614277565b60405180910390a35050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b612c88613662565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b03163314612ce05760405162461bcd60e51b81526004016107cf90614063565b50565b600086815260036020526040902054600280548892908110612d0757612d07613d48565b600091825260209091206002600590920201015460ff1615612d3b5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612d85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da99190613e04565b5090935060029250612db9915050565b816004811115612dcb57612dcb613e6b565b14612e265760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b85612e685760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b600088815260036020526040812054600280549091908110612e8c57612e8c613d48565b906000526020600020906005020190508060010154861115612ee75760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b80546000908290612efa90600190613cfc565b81548110612f0a57612f0a613d48565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f899190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130089190613ff9565b5050505050915050600061301d8a8a8a610a0f565b905060005b8b81101561326b5733858e8e8481811061303e5761303e613d48565b905060200201358154811061305557613055613d48565b60009182526020909120600490910201546001600160a01b03161461308c5760405162461bcd60e51b81526004016107cf9061420e565b8215806130d3575081858e8e848181106130a8576130a8613d48565b90506020020135815481106130bf576130bf613d48565b906000526020600020906004020160010154145b6131535760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d8381811061316657613166613d48565b905060200201358154811061317d5761317d613d48565b600091825260209091206003600490920201015460ff16156131d65760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e848181106131ea576131ea613d48565b905060200201358154811061320157613201613d48565b60009182526020909120600260049092020101556001858e8e8481811061322a5761322a613d48565b905060200201358154811061324157613241613d48565b60009182526020909120600490910201600301805460ff1916911515919091179055600101613022565b508b8b90508460040160008282546132839190613ed8565b909155505060008a8152600285016020526040812080548d92906132a8908490613ed8565b909155505060018401548a036132d757600384015460ff16156132d25760038401805460ff191690555b613350565b60018401546000908152600285016020526040808220548c83529120540361331957600384015460ff166132d25760038401805460ff19166001179055613350565b60018401546000908152600285016020526040808220548c8352912054111561335057600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161338f9392919061429b565b60405180910390a450505050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156133f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134189190613e04565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015613477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349b9190613eeb565b6134a59190613cfc565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156134e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261350e919081019061435e565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561356a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358e91906141f1565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156135e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613609919061443f565b505091509150828161361b9190613ed8565b60045490831015955060ff16156136575784801561365457506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b61366a613689565b61368757604051631afcd79f60e31b815260040160405180910390fd5b565b6000613693612c5c565b54600160401b900460ff16919050565b6000602082840312156136b557600080fd5b5035919050565b60008083601f8401126136ce57600080fd5b5081356001600160401b038111156136e557600080fd5b6020830191508360208260051b850101111561370057600080fd5b9250929050565b60008083601f84011261371957600080fd5b5081356001600160401b0381111561373057600080fd5b60208301915083602082850101111561370057600080fd5b600080600080600080600060a0888a03121561376357600080fd5b8735965060208801356001600160401b038082111561378157600080fd5b61378d8b838c016136bc565b909850965060408a0135955060608a0135945060808a01359150808211156137b457600080fd5b506137c18a828b01613707565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561380d5761380d6137d4565b60405290565b604051601f8201601f191681016001600160401b038111828210171561383b5761383b6137d4565b604052919050565b600082601f83011261385457600080fd5b81356001600160401b0381111561386d5761386d6137d4565b613880601f8201601f1916602001613813565b81815284602083860101111561389557600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138c757600080fd5b833592506020840135915060408401356001600160401b038111156138eb57600080fd5b6138f786828701613843565b9150509250925092565b6001600160a01b0381168114612ce057600080fd5b6000806000806080858703121561392c57600080fd5b84359350602085013561393e81613901565b93969395505050506040820135916060013590565b6000806040838503121561396657600080fd5b823561397181613901565b9150602083013561398181613901565b809150509250929050565b6000806040838503121561399f57600080fd5b50508035926020909101359150565b600080604083850312156139c157600080fd5b82356139cc81613901565b915060208301356001600160401b038111156139e757600080fd5b6139f385828601613843565b9150509250929050565b60005b83811015613a18578181015183820152602001613a00565b50506000910152565b60008151808452613a398160208601602086016139fd565b601f01601f19169290920160200192915050565b602081526000613a606020830184613a21565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a21565b60008060008060608587031215613a9e57600080fd5b8435935060208501356001600160401b03811115613abb57600080fd5b613ac7878288016136bc565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b1257835183529284019291840191600101613af6565b50909695505050505050565b600080600080600060a08688031215613b3657600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b6e57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613b9a57600080fd5b8335613ba581613901565b92506020840135915060408401356001600160401b038111156138eb57600080fd5b60008060008060008060a08789031215613be057600080fd5b8635955060208701356001600160401b0380821115613bfe57600080fd5b613c0a8a838b016136bc565b909750955060408901359450606089013593506080890135915080821115613c3157600080fd5b50613c3e89828a01613843565b9150509295509295509295565b600060208284031215613c5d57600080fd5b8135613a6081613901565b600080600080600060808688031215613c8057600080fd5b853594506020860135935060408601356001600160401b03811115613ca457600080fd5b613cb088828901613707565b96999598509660600135949350505050565b60008060408385031215613cd557600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561290557612905613ce6565b808202811582820484141761290557612905613ce6565b600082613d4357634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613d95565b80516001600160601b0381168114613def57600080fd5b919050565b80518015158114613def57600080fd5b600080600080600060a08688031215613e1c57600080fd5b613e2586613dd8565b94506020860151613e3581613901565b604087015190945060058110613e4a57600080fd5b9250613e5860608701613df4565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613e9357600080fd5b613a6082613df4565b600080600060608486031215613eb157600080fd5b83519250613ec160208501613df4565b9150613ecf60408501613df4565b90509250925092565b8082018082111561290557612905613ce6565b600060208284031215613efd57600080fd5b5051919050565b600181811c90821680613f1857607f821691505b602082108103613f3857634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613f5f81613f04565b8060608701526080600180841660008114613f815760018114613f9d57613fcd565b60ff19851660808a0152608084151560051b8a01019550613fcd565b89600052602060002060005b85811015613fc45781548b8201860152908301908801613fa9565b8a016080019650505b50939a9950505050505050505050565b60008251613fef8184602087016139fd565b9190910192915050565b600080600080600080600060e0888a03121561401457600080fd5b61401d88613dd8565b965061402b60208901613df4565b955060408801519450606088015193506080880151925060a0880151915061405560c08901613df4565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a24576000816000526020600020601f850160051c810160208610156141125750805b601f850160051c820191505b818110156120755782815560010161411e565b6001600160401b03831115614148576141486137d4565b61415c836141568354613f04565b836140e9565b6000601f84116001811461419057600085156141785750838201355b600019600387901b1c1916600186901b1783556141ea565b600083815260209020601f19861690835b828110156141c157868501358255602094850194600190920191016141a1565b50868210156141de5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561420357600080fd5b8151613a6081613901565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b0383111561425e57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061428b604083018587614245565b9050826020830152949350505050565b6040815260006142af604083018587614245565b82810360208401526142c18185613a21565b9695505050505050565b600082601f8301126142dc57600080fd5b815160206001600160401b038211156142f7576142f76137d4565b8160051b614306828201613813565b928352848101820192828101908785111561432057600080fd5b83870192505b8483101561434857825161433981613901565b82529183019190830190614326565b979650505050505050565b8051613def81613901565b60006020828403121561437057600080fd5b81516001600160401b038082111561438757600080fd5b90830190610160828603121561439c57600080fd5b6143a46137ea565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151828111156143ec57600080fd5b6143f8878286016142cb565b60c08301525060e0838101519082015261010080840151908201526101209150614423828401614353565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561445557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212203ada2f3e13f6acb3c61148590d88e774a75ff8a53adb5bb0bd110996f279319e64736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106101c45760003560e01c8063675926f6116100f8578063b6ede54011610090578063b6ede540146105c4578063ba66fde7146105e4578063be46760414610604578063caeb50ed1461061a578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad301461050c578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b8063675926f61461045f57806369f3f0411461047f5780636d4cd8ea146104cc578063751accd0146104ec578063796490f91461050c5780637c04034e146105225780638e42646014610542578063a7cc08fe14610562578063b34bfaa8146105ae57600080fd5b8063362c34791161016b578063362c34791461032a578063485cc9551461034a5780634b2f0ea01461036a5780634f1ef2861461037d57806352d1902d1461039057806354fd4d50146103a5578063564a565d146103e35780635c92e2f61461041257806365540b961461043257600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136a3565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613748565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136a3565b61082a565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136a3565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136a3565b6108a1565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138b2565b610a0f565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613916565b610a4c565b34801561035657600080fd5b5061021e610365366004613953565b610ed2565b61021e61037836600461398c565b610f9a565b61021e61038b3660046139ae565b611801565b34801561039c57600080fd5b506102a5611a29565b3480156103b157600080fd5b506103d66040518060400160405280600581526020016418171c971960d91b81525081565b6040516101f59190613a4d565b3480156103ef57600080fd5b506104036103fe3660046136a3565b611a87565b6040516101f593929190613a67565b34801561041e57600080fd5b5061021e61042d366004613a88565b611b4d565b34801561043e57600080fd5b5061045261044d3660046136a3565b611b59565b6040516101f59190613ada565b34801561046b57600080fd5b506102a561047a366004613b1e565b611c1d565b34801561048b57600080fd5b5061049f61049a366004613b59565b611d60565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104d857600080fd5b506101e96104e73660046136a3565b611e18565b3480156104f857600080fd5b5061021e610507366004613b85565b611f9b565b34801561051857600080fd5b506102a561271081565b34801561052e57600080fd5b5061021e61053d366004613bc7565b612067565b34801561054e57600080fd5b5061021e61055d366004613c4b565b61207d565b34801561056e57600080fd5b5061058261057d366004613b59565b6120c9565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105ba57600080fd5b506102a5614e2081565b3480156105d057600080fd5b5061021e6105df366004613c68565b61218f565b3480156105f057600080fd5b506101e96105ff366004613b59565b612352565b34801561061057600080fd5b506102a561138881565b34801561062657600080fd5b5061021e6123ed565b34801561063b57600080fd5b5061026061064a36600461398c565b61249e565b34801561065b57600080fd5b506102a561066a36600461398c565b6127b8565b34801561067b57600080fd5b5061021e61068a366004613c4b565b61290b565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cc2565b91509150600061072f85611b59565b90508051600014801561076e575061271061138861074d8585613cfc565b6107579190613d0f565b6107619190613d26565b61076b8442613cfc565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d48565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d5e565b60405180910390fd5b6107e488888888612957565b847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161081893929190613dbe565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061084e5761084e613d48565b6000918252602082206005909102018054909250829061087090600190613cfc565b8154811061088057610880613d48565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106108cd576108cd613d48565b600091825260208220600590910201805490925082906108ef90600190613cfc565b815481106108ff576108ff613d48565b60009182526020909120600d90910201600381015460ff16945090508361092a57806001015461092d565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a09190613e04565b50909350600492506109b0915050565b8160048111156109c2576109c2613e6b565b03610a055760006109d288611b59565b90508051600103610a0357806000815181106109f0576109f0613d48565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190613e04565b50935050505080610b115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b889190613e81565b15610bc65760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610bea57610bea613d48565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c1e57610c1e613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190613e9c565b5050600087815260078401602052604090205490915060ff16610ce7576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e2c565b808603610d5c576000868152600683016020526040902054610d0a576000610d55565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d4b9190613d0f565b610d559190613d26565b9450610e2c565b600081815260078301602052604090205460ff16610e2c5781600601600083600a01600181548110610d9057610d90613d48565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610dc657610dc6613d48565b9060005260206000200154815260200190815260200160002054610dea9190613ed8565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e1f9190613d0f565b610e299190613d26565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ec6576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610ede612c5c565b8054909150600160401b900460ff1680610f05575080546001600160401b03808416911610155b15610f225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f4d8484612c80565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fbe57610fbe613d48565b600091825260209091206002600590920201015460ff1615610ff25760405162461bcd60e51b81526004016107cf90613d5e565b60008381526003602052604081205460028054909190811061101657611016613d48565b90600052602060002090600502019050806001015483111561107a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156110c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110eb9190613cc2565b915091508142101580156110fe57508042105b6111435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611184573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a89190613e9c565b505090508681036111bd57612710915061123e565b6127106113886111cd8686613cfc565b6111d79190613d0f565b6111e19190613d26565b6111eb8542613cfc565b106112385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061125190600190613cfc565b8154811061126157611261613d48565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190613eeb565b6112ee9190613cfc565b60008a815260078401602052604090205490915060ff16156113525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561139c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c09190613eeb565b905060006127106113d18784613d0f565b6113db9190613d26565b6113e59083613ed8565b60008c8152600686016020526040812054919250908211156114965760008c8152600686016020526040902054349061141e9084613cfc565b116114435760008c815260068601602052604090205461143e9083613cfc565b611445565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161148d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906114c2908490613ed8565b909155505060008c8152600686016020526040812080548392906114e7908490613ed8565b909155505060008c815260068601602052604090205482116115b95760008c815260068601602052604081205460098701805491929091611529908490613ed8565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156117c4578285600901546115d69190613cfc565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116489190613e81565b156116615760028a01805460ff19166001179055611744565b895460038b016000611674876001613ed8565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016116ef91815260200190565b602060405180830381865afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117309190613eeb565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161179193929190613f3e565b6000604051808303818588803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b50505050505b803411156117f257336108fc6117da8334613cfc565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61180a82612cb6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061188857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661187c6000805160206144768339815191525490565b6001600160a01b031614155b156118a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611900575060408051601f3d908101601f191682019092526118fd91810190613eeb565b60015b61192857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b600080516020614476833981519152811461195957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144768339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a24576000836001600160a01b0316836040516119c09190613fdd565b600060405180830381855af49150503d80600081146119fb576040519150601f19603f3d011682016040523d82523d6000602084013e611a00565b606091505b5050905080611a22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a745760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061447683398151915290565b60028181548110611a9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611aca90613f04565b80601f0160208091040260200160405190810160405280929190818152602001828054611af690613f04565b8015611b435780601f10611b1857610100808354040283529160200191611b43565b820191906000526020600020905b815481529060010190602001808311611b2657829003601f168201915b5050505050905083565b611a2284848484612957565b6000818152600360205260408120546002805460609392908110611b7f57611b7f613d48565b60009182526020822060059091020180549092508290611ba190600190613cfc565b81548110611bb157611bb1613d48565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c0f57602002820191906000526020600020905b815481526020019060010190808311611bfb575b505050505092505050919050565b600085815260036020526040812054600280548392908110611c4157611c41613d48565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611c7557611c75613d48565b90600052602060002090600d02016000018681548110611c9757611c97613d48565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d199190613e9c565b506003850154919350915060ff168015611d3d57508183600201541480611d3d5750805b15611d505761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611d9157611d91613d48565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611dc557611dc5613d48565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611e3c57611e3c613d48565b60009182526020822060059091020180549092508290611e5e90600190613cfc565b81548110611e6e57611e6e613d48565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015611ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eed9190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015611f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6c9190613ff9565b5050505050915050600081611f82578354611f88565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b03163314611fc55760405162461bcd60e51b81526004016107cf90614063565b6000836001600160a01b03168383604051611fe09190613fdd565b60006040518083038185875af1925050503d806000811461201d576040519150601f19603f3d011682016040523d82523d6000602084013e612022565b606091505b5050905080611a225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b612075868686868686612ce3565b505050505050565b6000546001600160a01b031633146120a75760405162461bcd60e51b81526004016107cf90614063565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106120f7576120f7613d48565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061212b5761212b613d48565b90600052602060002090600d0201600001878154811061214d5761214d613d48565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146121b95760405162461bcd60e51b81526004016107cf906140a5565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612244858783614131565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561229b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bf9190613eeb565b6122c99190613cfc565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610818908a908a908a90613dbe565b60008381526003602052604081205460028054839290811061237657612376613d48565b600091825260208083208784526003600590930201918201905260408220548154919350839181106123aa576123aa613d48565b90600052602060002090600d020160000184815481106123cc576123cc613d48565b600091825260209091206004909102016003015460ff169695505050505050565b600460006123f9612c5c565b8054909150600160401b900460ff1680612420575080546001600160401b03808416911610155b1561243d5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b6001546000906001600160a01b031633146124cb5760405162461bcd60e51b81526004016107cf906140a5565b6000838152600360205260409020546002805485929081106124ef576124ef613d48565b600091825260209091206002600590920201015460ff16156125235760405162461bcd60e51b81526004016107cf90613d5e565b60008481526003602052604081205460028054909190811061254757612547613d48565b6000918252602082206005909102018054909250829061256990600190613cfc565b8154811061257957612579613d48565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260291906141f1565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126759190613e04565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd91906141f1565b965061270a848a896133a6565b156127a757604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556127ac565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106127dc576127dc613d48565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061281057612810613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190613e9c565b50915091508260040154600014806128c25750801580156128c257506000828152600284016020526040902054155b156128d4576000945050505050612905565b80156128e95750506004015491506129059050565b5060009081526002909101602052604090205491506129059050565b92915050565b6000546001600160a01b031633146129355760405162461bcd60e51b81526004016107cf90614063565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008481526003602052604090205460028054869290811061297b5761297b613d48565b600091825260209091206002600590920201015460ff16156129af5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa1580156129f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1d9190613e04565b5090935060019250612a2d915050565b816004811115612a3f57612a3f613e6b565b14612a9c5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82612ad95760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110612afd57612afd613d48565b60009182526020822060059091020180549092508290612b1f90600190613cfc565b81548110612b2f57612b2f613d48565b90600052602060002090600d0201905060005b86811015612bf5573382898984818110612b5e57612b5e613d48565b9050602002013581548110612b7557612b75613d48565b60009182526020909120600490910201546001600160a01b031614612bac5760405162461bcd60e51b81526004016107cf9061420e565b8582898984818110612bc057612bc0613d48565b9050602002013581548110612bd757612bd7613d48565b60009182526020909120600160049092020181019190915501612b42565b5086869050816005016000828254612c0d9190613ed8565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612c4a908b908b908b90614277565b60405180910390a35050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b612c88613662565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b03163314612ce05760405162461bcd60e51b81526004016107cf90614063565b50565b600086815260036020526040902054600280548892908110612d0757612d07613d48565b600091825260209091206002600590920201015460ff1615612d3b5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612d85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da99190613e04565b5090935060029250612db9915050565b816004811115612dcb57612dcb613e6b565b14612e265760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b85612e685760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b600088815260036020526040812054600280549091908110612e8c57612e8c613d48565b906000526020600020906005020190508060010154861115612ee75760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b80546000908290612efa90600190613cfc565b81548110612f0a57612f0a613d48565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f899190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130089190613ff9565b5050505050915050600061301d8a8a8a610a0f565b905060005b8b81101561326b5733858e8e8481811061303e5761303e613d48565b905060200201358154811061305557613055613d48565b60009182526020909120600490910201546001600160a01b03161461308c5760405162461bcd60e51b81526004016107cf9061420e565b8215806130d3575081858e8e848181106130a8576130a8613d48565b90506020020135815481106130bf576130bf613d48565b906000526020600020906004020160010154145b6131535760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d8381811061316657613166613d48565b905060200201358154811061317d5761317d613d48565b600091825260209091206003600490920201015460ff16156131d65760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e848181106131ea576131ea613d48565b905060200201358154811061320157613201613d48565b60009182526020909120600260049092020101556001858e8e8481811061322a5761322a613d48565b905060200201358154811061324157613241613d48565b60009182526020909120600490910201600301805460ff1916911515919091179055600101613022565b508b8b90508460040160008282546132839190613ed8565b909155505060008a8152600285016020526040812080548d92906132a8908490613ed8565b909155505060018401548a036132d757600384015460ff16156132d25760038401805460ff191690555b613350565b60018401546000908152600285016020526040808220548c83529120540361331957600384015460ff166132d25760038401805460ff19166001179055613350565b60018401546000908152600285016020526040808220548c8352912054111561335057600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161338f9392919061429b565b60405180910390a450505050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156133f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134189190613e04565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015613477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349b9190613eeb565b6134a59190613cfc565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156134e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261350e919081019061435e565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561356a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358e91906141f1565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156135e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613609919061443f565b505091509150828161361b9190613ed8565b60045490831015955060ff16156136575784801561365457506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b61366a613689565b61368757604051631afcd79f60e31b815260040160405180910390fd5b565b6000613693612c5c565b54600160401b900460ff16919050565b6000602082840312156136b557600080fd5b5035919050565b60008083601f8401126136ce57600080fd5b5081356001600160401b038111156136e557600080fd5b6020830191508360208260051b850101111561370057600080fd5b9250929050565b60008083601f84011261371957600080fd5b5081356001600160401b0381111561373057600080fd5b60208301915083602082850101111561370057600080fd5b600080600080600080600060a0888a03121561376357600080fd5b8735965060208801356001600160401b038082111561378157600080fd5b61378d8b838c016136bc565b909850965060408a0135955060608a0135945060808a01359150808211156137b457600080fd5b506137c18a828b01613707565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561380d5761380d6137d4565b60405290565b604051601f8201601f191681016001600160401b038111828210171561383b5761383b6137d4565b604052919050565b600082601f83011261385457600080fd5b81356001600160401b0381111561386d5761386d6137d4565b613880601f8201601f1916602001613813565b81815284602083860101111561389557600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138c757600080fd5b833592506020840135915060408401356001600160401b038111156138eb57600080fd5b6138f786828701613843565b9150509250925092565b6001600160a01b0381168114612ce057600080fd5b6000806000806080858703121561392c57600080fd5b84359350602085013561393e81613901565b93969395505050506040820135916060013590565b6000806040838503121561396657600080fd5b823561397181613901565b9150602083013561398181613901565b809150509250929050565b6000806040838503121561399f57600080fd5b50508035926020909101359150565b600080604083850312156139c157600080fd5b82356139cc81613901565b915060208301356001600160401b038111156139e757600080fd5b6139f385828601613843565b9150509250929050565b60005b83811015613a18578181015183820152602001613a00565b50506000910152565b60008151808452613a398160208601602086016139fd565b601f01601f19169290920160200192915050565b602081526000613a606020830184613a21565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a21565b60008060008060608587031215613a9e57600080fd5b8435935060208501356001600160401b03811115613abb57600080fd5b613ac7878288016136bc565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b1257835183529284019291840191600101613af6565b50909695505050505050565b600080600080600060a08688031215613b3657600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b6e57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613b9a57600080fd5b8335613ba581613901565b92506020840135915060408401356001600160401b038111156138eb57600080fd5b60008060008060008060a08789031215613be057600080fd5b8635955060208701356001600160401b0380821115613bfe57600080fd5b613c0a8a838b016136bc565b909750955060408901359450606089013593506080890135915080821115613c3157600080fd5b50613c3e89828a01613843565b9150509295509295509295565b600060208284031215613c5d57600080fd5b8135613a6081613901565b600080600080600060808688031215613c8057600080fd5b853594506020860135935060408601356001600160401b03811115613ca457600080fd5b613cb088828901613707565b96999598509660600135949350505050565b60008060408385031215613cd557600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561290557612905613ce6565b808202811582820484141761290557612905613ce6565b600082613d4357634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613d95565b80516001600160601b0381168114613def57600080fd5b919050565b80518015158114613def57600080fd5b600080600080600060a08688031215613e1c57600080fd5b613e2586613dd8565b94506020860151613e3581613901565b604087015190945060058110613e4a57600080fd5b9250613e5860608701613df4565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613e9357600080fd5b613a6082613df4565b600080600060608486031215613eb157600080fd5b83519250613ec160208501613df4565b9150613ecf60408501613df4565b90509250925092565b8082018082111561290557612905613ce6565b600060208284031215613efd57600080fd5b5051919050565b600181811c90821680613f1857607f821691505b602082108103613f3857634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613f5f81613f04565b8060608701526080600180841660008114613f815760018114613f9d57613fcd565b60ff19851660808a0152608084151560051b8a01019550613fcd565b89600052602060002060005b85811015613fc45781548b8201860152908301908801613fa9565b8a016080019650505b50939a9950505050505050505050565b60008251613fef8184602087016139fd565b9190910192915050565b600080600080600080600060e0888a03121561401457600080fd5b61401d88613dd8565b965061402b60208901613df4565b955060408801519450606088015193506080880151925060a0880151915061405560c08901613df4565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a24576000816000526020600020601f850160051c810160208610156141125750805b601f850160051c820191505b818110156120755782815560010161411e565b6001600160401b03831115614148576141486137d4565b61415c836141568354613f04565b836140e9565b6000601f84116001811461419057600085156141785750838201355b600019600387901b1c1916600186901b1783556141ea565b600083815260209020601f19861690835b828110156141c157868501358255602094850194600190920191016141a1565b50868210156141de5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561420357600080fd5b8151613a6081613901565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b0383111561425e57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061428b604083018587614245565b9050826020830152949350505050565b6040815260006142af604083018587614245565b82810360208401526142c18185613a21565b9695505050505050565b600082601f8301126142dc57600080fd5b815160206001600160401b038211156142f7576142f76137d4565b8160051b614306828201613813565b928352848101820192828101908785111561432057600080fd5b83870192505b8483101561434857825161433981613901565b82529183019190830190614326565b979650505050505050565b8051613def81613901565b60006020828403121561437057600080fd5b81516001600160401b038082111561438757600080fd5b90830190610160828603121561439c57600080fd5b6143a46137ea565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151828111156143ec57600080fd5b6143f8878286016142cb565b60c08301525060e0838101519082015261010080840151908201526101209150614423828401614353565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561445557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212203ada2f3e13f6acb3c61148590d88e774a75ff8a53adb5bb0bd110996f279319e64736f6c63430008180033", "devdoc": { "errors": { "AlreadyInitialized()": [ @@ -1420,7 +1420,7 @@ "storageLayout": { "storage": [ { - "astId": 3889, + "astId": 3945, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "governor", "offset": 0, @@ -1428,7 +1428,7 @@ "type": "t_address" }, { - "astId": 3892, + "astId": 3948, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "core", "offset": 0, @@ -1436,15 +1436,15 @@ "type": "t_contract(KlerosCore)165" }, { - "astId": 3896, + "astId": 3952, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "disputes", "offset": 0, "slot": "2", - "type": "t_array(t_struct(Dispute)3824_storage)dyn_storage" + "type": "t_array(t_struct(Dispute)3880_storage)dyn_storage" }, { - "astId": 3900, + "astId": 3956, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "coreDisputeIDToLocal", "offset": 0, @@ -1452,7 +1452,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3902, + "astId": 3958, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "singleDrawPerJuror", "offset": 0, @@ -1466,20 +1466,20 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_struct(Dispute)3824_storage)dyn_storage": { - "base": "t_struct(Dispute)3824_storage", + "t_array(t_struct(Dispute)3880_storage)dyn_storage": { + "base": "t_struct(Dispute)3880_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Dispute[]", "numberOfBytes": "32" }, - "t_array(t_struct(Round)3866_storage)dyn_storage": { - "base": "t_struct(Round)3866_storage", + "t_array(t_struct(Round)3922_storage)dyn_storage": { + "base": "t_struct(Round)3922_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Round[]", "numberOfBytes": "32" }, - "t_array(t_struct(Vote)3875_storage)dyn_storage": { - "base": "t_struct(Vote)3875_storage", + "t_array(t_struct(Vote)3931_storage)dyn_storage": { + "base": "t_struct(Vote)3931_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Vote[]", "numberOfBytes": "32" @@ -1538,20 +1538,20 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Dispute)3824_storage": { + "t_struct(Dispute)3880_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Dispute", "members": [ { - "astId": 3813, + "astId": 3869, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "rounds", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Round)3866_storage)dyn_storage" + "type": "t_array(t_struct(Round)3922_storage)dyn_storage" }, { - "astId": 3815, + "astId": 3871, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "numberOfChoices", "offset": 0, @@ -1559,7 +1559,7 @@ "type": "t_uint256" }, { - "astId": 3817, + "astId": 3873, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "jumped", "offset": 0, @@ -1567,7 +1567,7 @@ "type": "t_bool" }, { - "astId": 3821, + "astId": 3877, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "coreRoundIDToLocal", "offset": 0, @@ -1575,7 +1575,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3823, + "astId": 3879, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "extraData", "offset": 0, @@ -1585,20 +1585,20 @@ ], "numberOfBytes": "160" }, - "t_struct(Round)3866_storage": { + "t_struct(Round)3922_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Round", "members": [ { - "astId": 3828, + "astId": 3884, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "votes", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Vote)3875_storage)dyn_storage" + "type": "t_array(t_struct(Vote)3931_storage)dyn_storage" }, { - "astId": 3830, + "astId": 3886, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "winningChoice", "offset": 0, @@ -1606,7 +1606,7 @@ "type": "t_uint256" }, { - "astId": 3834, + "astId": 3890, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "counts", "offset": 0, @@ -1614,7 +1614,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3836, + "astId": 3892, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "tied", "offset": 0, @@ -1622,7 +1622,7 @@ "type": "t_bool" }, { - "astId": 3838, + "astId": 3894, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "totalVoted", "offset": 0, @@ -1630,7 +1630,7 @@ "type": "t_uint256" }, { - "astId": 3840, + "astId": 3896, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "totalCommitted", "offset": 0, @@ -1638,7 +1638,7 @@ "type": "t_uint256" }, { - "astId": 3844, + "astId": 3900, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "paidFees", "offset": 0, @@ -1646,7 +1646,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3848, + "astId": 3904, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "hasPaid", "offset": 0, @@ -1654,7 +1654,7 @@ "type": "t_mapping(t_uint256,t_bool)" }, { - "astId": 3854, + "astId": 3910, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "contributions", "offset": 0, @@ -1662,7 +1662,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 3856, + "astId": 3912, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "feeRewards", "offset": 0, @@ -1670,7 +1670,7 @@ "type": "t_uint256" }, { - "astId": 3859, + "astId": 3915, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "fundedChoices", "offset": 0, @@ -1678,7 +1678,7 @@ "type": "t_array(t_uint256)dyn_storage" }, { - "astId": 3861, + "astId": 3917, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "nbVotes", "offset": 0, @@ -1686,7 +1686,7 @@ "type": "t_uint256" }, { - "astId": 3865, + "astId": 3921, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "alreadyDrawn", "offset": 0, @@ -1696,12 +1696,12 @@ ], "numberOfBytes": "416" }, - "t_struct(Vote)3875_storage": { + "t_struct(Vote)3931_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Vote", "members": [ { - "astId": 3868, + "astId": 3924, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "account", "offset": 0, @@ -1709,7 +1709,7 @@ "type": "t_address" }, { - "astId": 3870, + "astId": 3926, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "commit", "offset": 0, @@ -1717,7 +1717,7 @@ "type": "t_bytes32" }, { - "astId": 3872, + "astId": 3928, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "choice", "offset": 0, @@ -1725,7 +1725,7 @@ "type": "t_uint256" }, { - "astId": 3874, + "astId": 3930, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "voted", "offset": 0, diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol index 6bfb26467..ff9764e4a 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol @@ -11,7 +11,7 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol"; /// - an incentive system: equal split between coherent votes, /// - an appeal system: fund 2 choices only, vote on any choice. contract DisputeKitClassic is DisputeKitClassicBase { - string public constant override version = "0.9.0"; + string public constant override version = "0.9.2"; // ************************************* // // * Constructor * // @@ -29,7 +29,7 @@ contract DisputeKitClassic is DisputeKitClassicBase { __DisputeKitClassicBase_initialize(_governor, _core); } - function initialize3() external reinitializer(3) { + function initialize4() external reinitializer(4) { // NOP } diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol index 85a9cd8cb..576e8bbac 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol @@ -239,11 +239,15 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi /// @param _coreDisputeID The ID of the dispute in Kleros Core. /// @param _voteIDs The IDs of the votes. /// @param _commit The commitment hash. - function castCommit( + function castCommit(uint256 _coreDisputeID, uint256[] calldata _voteIDs, bytes32 _commit) external { + _castCommit(_coreDisputeID, _voteIDs, _commit); + } + + function _castCommit( uint256 _coreDisputeID, uint256[] calldata _voteIDs, bytes32 _commit - ) external notJumped(_coreDisputeID) { + ) internal notJumped(_coreDisputeID) { (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID); require(period == KlerosCoreBase.Period.commit, "The dispute should be in Commit period."); require(_commit != bytes32(0), "Empty commit."); @@ -272,7 +276,17 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi uint256 _choice, uint256 _salt, string memory _justification - ) external notJumped(_coreDisputeID) { + ) external { + _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification); + } + + function _castVote( + uint256 _coreDisputeID, + uint256[] calldata _voteIDs, + uint256 _choice, + uint256 _salt, + string memory _justification + ) internal notJumped(_coreDisputeID) { (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID); require(period == KlerosCoreBase.Period.vote, "The dispute should be in Vote period."); require(_voteIDs.length > 0, "No voteID provided"); diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol b/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol index 1e9165048..7e1589d50 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitGated.sol @@ -27,7 +27,7 @@ interface IBalanceHolderERC1155 { /// - an incentive system: equal split between coherent votes, /// - an appeal system: fund 2 choices only, vote on any choice. contract DisputeKitGated is DisputeKitClassicBase { - string public constant override version = "0.9.0"; + string public constant override version = "0.9.2"; // ************************************* // // * Storage * // diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol index 844e85614..c55d01c78 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol @@ -12,7 +12,7 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol"; /// - an appeal system: fund 2 choices only, vote on any choice. /// Added functionality: an Shutter-specific event emitted when a vote is cast. contract DisputeKitShutter is DisputeKitClassicBase { - string public constant override version = "0.9.1"; + string public constant override version = "0.9.2"; // ************************************* // // * Events * // @@ -40,7 +40,7 @@ contract DisputeKitShutter is DisputeKitClassicBase { __DisputeKitClassicBase_initialize(_governor, _core); } - function initialize2() external reinitializer(2) { + function initialize4() external reinitializer(4) { // NOP } @@ -74,7 +74,7 @@ contract DisputeKitShutter is DisputeKitClassicBase { bytes32 _identity, bytes calldata _encryptedVote ) external notJumped(_coreDisputeID) { - this.castCommit(_coreDisputeID, _voteIDs, _commit); + _castCommit(_coreDisputeID, _voteIDs, _commit); emit CommitCastShutter(_commit, _identity, _encryptedVote); } diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol index d406a2400..42f059c21 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol @@ -18,7 +18,7 @@ interface IProofOfHumanity { /// - an incentive system: equal split between coherent votes, /// - an appeal system: fund 2 choices only, vote on any choice. contract DisputeKitSybilResistant is DisputeKitClassicBase { - string public constant override version = "0.8.0"; + string public constant override version = "0.9.2"; // ************************************* // // * Storage * // From ee2ceb690fdc0e30b84f2e79581592dae3d49079 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Fri, 2 May 2025 20:08:52 +0100 Subject: [PATCH 17/26] chore: enable shutter DK on the devnet general court --- contracts/deploy/00-home-chain-arbitration.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/deploy/00-home-chain-arbitration.ts b/contracts/deploy/00-home-chain-arbitration.ts index 2cdbbb2c0..d581cdc54 100644 --- a/contracts/deploy/00-home-chain-arbitration.ts +++ b/contracts/deploy/00-home-chain-arbitration.ts @@ -103,6 +103,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) log: true, }); await core.addNewDisputeKit(disputeKitShutter.address); + await core.enableDisputeKits(1, [2], true); // enable disputeKitShutter on the General Court await deploy("KlerosCoreSnapshotProxy", { from: deployer, From 317aed6c6f6190011ed783b631b81d57ec81ad59 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Wed, 7 May 2025 00:10:02 +0200 Subject: [PATCH 18/26] feat: support for shutter disputekit in devnet --- subgraph/core/src/DisputeKitClassic.ts | 77 +++++++++++++++---- subgraph/core/src/KlerosCore.ts | 2 +- .../core/src/entities/ClassicContribution.ts | 16 +++- subgraph/core/src/entities/ClassicDispute.ts | 5 +- subgraph/core/src/entities/ClassicRound.ts | 20 ++++- subgraph/core/src/utils.ts | 8 +- subgraph/core/subgraph.yaml | 36 +++++++++ subgraph/package.json | 2 +- 8 files changed, 138 insertions(+), 28 deletions(-) diff --git a/subgraph/core/src/DisputeKitClassic.ts b/subgraph/core/src/DisputeKitClassic.ts index c58147bf1..850b29786 100644 --- a/subgraph/core/src/DisputeKitClassic.ts +++ b/subgraph/core/src/DisputeKitClassic.ts @@ -9,7 +9,15 @@ import { CommitCast, } from "../generated/DisputeKitClassic/DisputeKitClassic"; import { KlerosCore } from "../generated/KlerosCore/KlerosCore"; -import { ClassicDispute, ClassicJustification, ClassicRound, ClassicVote, Dispute } from "../generated/schema"; +import { + ClassicDispute, + ClassicJustification, + ClassicRound, + ClassicVote, + Dispute, + DisputeKit, + Round, +} from "../generated/schema"; import { ensureClassicContributionFromEvent } from "./entities/ClassicContribution"; import { createClassicDisputeFromEvent } from "./entities/ClassicDispute"; import { @@ -19,23 +27,31 @@ import { updateCountsAndGetCurrentRuling, } from "./entities/ClassicRound"; import { ensureClassicVote } from "./entities/ClassicVote"; -import { ONE, ZERO } from "./utils"; - -export const DISPUTEKIT_ID = "1"; +import { ONE, ZERO, extractDisputeKitIDFromExtraData } from "./utils"; export function handleDisputeCreation(event: DisputeCreation): void { const disputeID = event.params._coreDisputeID.toString(); - createClassicDisputeFromEvent(event); + const disputeKitID = extractDisputeKitIDFromExtraData(event.params._extraData); + createClassicDisputeFromEvent(event, disputeKitID); const numberOfChoices = event.params._numberOfChoices; - createClassicRound(disputeID, numberOfChoices, ZERO); + createClassicRound(disputeID, numberOfChoices, ZERO, disputeKitID); } export function handleCommitCast(event: CommitCast): void { - const coreDisputeID = event.params._coreDisputeID; - const coreDispute = Dispute.load(coreDisputeID.toString()); - const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; + const coreDisputeID = event.params._coreDisputeID.toString(); + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const coreCurrentRound = Round.load(coreDispute.currentRound); + if (!coreCurrentRound) return; + + const disputeKitID = coreCurrentRound.disputeKit; + + const classicDisputeID = `${disputeKitID}-${coreDisputeID}`; + const classicDispute = ClassicDispute.load(classicDisputeID); - if (!classicDispute || !coreDispute) return; + if (!classicDispute) return; + const currentLocalRoundID = classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); const voteIDs = event.params._voteIDs; for (let i = 0; i < voteIDs.length; i++) { @@ -55,9 +71,18 @@ export function handleVoteCast(event: VoteCast): void { const juror = event.params._juror.toHexString(); const coreDisputeID = event.params._coreDisputeID.toString(); const coreDispute = Dispute.load(coreDisputeID); - const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; + if (!coreDispute) return; + + const coreCurrentRound = Round.load(coreDispute.currentRound); + if (!coreCurrentRound) return; + + const disputeKitID = coreCurrentRound.disputeKit; + + const classicDisputeID = `${disputeKitID}-${coreDisputeID}`; + const classicDispute = ClassicDispute.load(classicDisputeID); - if (!classicDispute || !coreDispute) return; + if (!classicDispute) return; + const choice = event.params._choice; const currentLocalRoundID = classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); const voteIDs = event.params._voteIDs; @@ -70,6 +95,7 @@ export function handleVoteCast(event: VoteCast): void { justification.transactionHash = event.transaction.hash.toHexString(); justification.timestamp = event.block.timestamp; justification.save(); + const currentRulingInfo = updateCountsAndGetCurrentRuling( currentLocalRoundID, choice, @@ -78,6 +104,7 @@ export function handleVoteCast(event: VoteCast): void { coreDispute.currentRuling = currentRulingInfo.ruling; coreDispute.tied = currentRulingInfo.tied; coreDispute.save(); + let classicVote: ClassicVote; for (let i = 0; i < voteIDs.length; i++) { classicVote = ensureClassicVote(currentLocalRoundID, juror, voteIDs[i], coreDispute); @@ -97,7 +124,16 @@ export function handleChoiceFunded(event: ChoiceFunded): void { const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); const choice = event.params._choice; - const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; + + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return; + const disputeKitID = coreRound.disputeKit; + + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; const localRound = ClassicRound.load(roundID); if (!localRound) return; @@ -123,13 +159,13 @@ export function handleChoiceFunded(event: ChoiceFunded): void { localRound.feeRewards = localRound.feeRewards.minus(appealCost); - const localDispute = ClassicDispute.load(`${DISPUTEKIT_ID}-${coreDisputeID}`); + const localDispute = ClassicDispute.load(`${disputeKitID}-${coreDisputeID}`); if (!localDispute) return; const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); const numberOfChoices = localDispute.numberOfChoices; localDispute.currentLocalRoundIndex = newRoundIndex; localDispute.save(); - createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex); + createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex, disputeKitID); } localRound.save(); @@ -144,7 +180,16 @@ export function handleWithdrawal(event: Withdrawal): void { // check if all appeal fees have been withdrawn const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); - const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; + + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return; + const disputeKitID = coreRound.disputeKit; + + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; const localRound = ClassicRound.load(roundID); if (!localRound) return; diff --git a/subgraph/core/src/KlerosCore.ts b/subgraph/core/src/KlerosCore.ts index 42a54644f..18e9cb45e 100644 --- a/subgraph/core/src/KlerosCore.ts +++ b/subgraph/core/src/KlerosCore.ts @@ -156,7 +156,7 @@ export function handleNewPeriod(event: NewPeriod): void { updateTotalLeaderboardJurors(ONE, event.block.timestamp); } - // Since this is a ClassicVote entity, this will only work for the Classic DisputeKit (which has ID "1"). + // Since this is a ClassicVote entity, this will only work for the ClassicDisputeKit and ShutterDisputeKit. const vote = ClassicVote.load(`${round.disputeKit}-${draw.id}`); if (!vote) { diff --git a/subgraph/core/src/entities/ClassicContribution.ts b/subgraph/core/src/entities/ClassicContribution.ts index c9d11211f..0473d0f39 100644 --- a/subgraph/core/src/entities/ClassicContribution.ts +++ b/subgraph/core/src/entities/ClassicContribution.ts @@ -1,13 +1,23 @@ -import { ClassicContribution } from "../../generated/schema"; +import { ClassicContribution, Dispute, DisputeKit, Round } from "../../generated/schema"; import { Contribution as ContributionEvent, Withdrawal } from "../../generated/DisputeKitClassic/DisputeKitClassic"; -import { DISPUTEKIT_ID } from "../DisputeKitClassic"; import { ensureUser } from "./User"; export function ensureClassicContributionFromEvent(event: T): ClassicContribution | null { if (!(event instanceof ContributionEvent) && !(event instanceof Withdrawal)) return null; const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); - const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; + + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return null; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return null; + + const disputeKitID = coreRound.disputeKit; + + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; + ensureUser(event.params._contributor.toHexString()); const contributor = event.params._contributor.toHexString(); const choice = event.params._choice; diff --git a/subgraph/core/src/entities/ClassicDispute.ts b/subgraph/core/src/entities/ClassicDispute.ts index bc0604517..78bfdc69d 100644 --- a/subgraph/core/src/entities/ClassicDispute.ts +++ b/subgraph/core/src/entities/ClassicDispute.ts @@ -1,10 +1,11 @@ +import { Bytes } from "@graphprotocol/graph-ts"; import { DisputeCreation } from "../../generated/DisputeKitClassic/DisputeKitClassic"; import { ClassicDispute } from "../../generated/schema"; import { ZERO } from "../utils"; -export function createClassicDisputeFromEvent(event: DisputeCreation): void { +export function createClassicDisputeFromEvent(event: DisputeCreation, disputeKitID: string): void { const coreDisputeID = event.params._coreDisputeID.toString(); - const classicDispute = new ClassicDispute(`1-${coreDisputeID}`); + const classicDispute = new ClassicDispute(`${disputeKitID}-${coreDisputeID}`); classicDispute.coreDispute = coreDisputeID; classicDispute.currentLocalRoundIndex = ZERO; classicDispute.numberOfChoices = event.params._numberOfChoices; diff --git a/subgraph/core/src/entities/ClassicRound.ts b/subgraph/core/src/entities/ClassicRound.ts index 86dc57491..57862a347 100644 --- a/subgraph/core/src/entities/ClassicRound.ts +++ b/subgraph/core/src/entities/ClassicRound.ts @@ -1,10 +1,15 @@ import { BigInt } from "@graphprotocol/graph-ts"; import { Contribution } from "../../generated/DisputeKitClassic/DisputeKitClassic"; -import { Answer, ClassicRound } from "../../generated/schema"; +import { Answer, ClassicRound, Dispute, Round } from "../../generated/schema"; import { ZERO } from "../utils"; -export function createClassicRound(disputeID: string, numberOfChoices: BigInt, roundIndex: BigInt): void { - const localDisputeID = `1-${disputeID}`; +export function createClassicRound( + disputeID: string, + numberOfChoices: BigInt, + roundIndex: BigInt, + disputeKitID: string +): void { + const localDisputeID = `${disputeKitID}-${disputeID}`; const id = `${localDisputeID}-${roundIndex.toString()}`; const classicRound = new ClassicRound(id); classicRound.localDispute = localDisputeID; @@ -67,9 +72,16 @@ export function updateCountsAndGetCurrentRuling(id: string, choice: BigInt, delt } export function updateChoiceFundingFromContributionEvent(event: Contribution): void { - const disputeKitID = "1"; const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return; + const disputeKitID = coreRound.disputeKit; + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; const classicRound = ClassicRound.load(roundID); diff --git a/subgraph/core/src/utils.ts b/subgraph/core/src/utils.ts index 73b2f99dc..78d2abaa4 100644 --- a/subgraph/core/src/utils.ts +++ b/subgraph/core/src/utils.ts @@ -1,4 +1,10 @@ -import { BigInt } from "@graphprotocol/graph-ts"; +import { BigInt, Bytes } from "@graphprotocol/graph-ts"; export const ZERO = BigInt.fromI32(0); export const ONE = BigInt.fromI32(1); + +export function extractDisputeKitIDFromExtraData(extraData: Bytes): string { + const start = extraData.length - 32; + const littleEndian = extraData.subarray(start, extraData.length).reverse(); + return BigInt.fromUnsignedBytes(Bytes.fromUint8Array(littleEndian)).toString(); +} diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index d3aff9873..3774eef0d 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -120,6 +120,42 @@ dataSources: - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) handler: handleCommitCast file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: DisputeKitShutter + network: arbitrum-sepolia + source: + address: "0x09F3d00B995186D76Af9AA8627D06351d0d9f950" + abi: DisputeKitShutter + startBlock: 148194178 + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitShutter + file: ../../contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + handler: handleDisputeCreation + - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleContributionEvent + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal + - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts - kind: ethereum name: EvidenceModule network: arbitrum-sepolia diff --git a/subgraph/package.json b/subgraph/package.json index 0a125ee5e..8f4575778 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@kleros/kleros-v2-subgraph", - "version": "0.15.2", + "version": "0.16.0", "drtVersion": "0.12.0", "license": "MIT", "scripts": { From 05dcdb01068183352783ad7a1db6135703d2ef01 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Thu, 8 May 2025 15:25:17 +0200 Subject: [PATCH 19/26] fix: create new classic dispute entity correctly with correct round index --- subgraph/core/src/DisputeKitClassic.ts | 40 +++++++++++--------- subgraph/core/src/entities/ClassicDispute.ts | 7 ++-- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/subgraph/core/src/DisputeKitClassic.ts b/subgraph/core/src/DisputeKitClassic.ts index 850b29786..4df1600c9 100644 --- a/subgraph/core/src/DisputeKitClassic.ts +++ b/subgraph/core/src/DisputeKitClassic.ts @@ -9,15 +9,7 @@ import { CommitCast, } from "../generated/DisputeKitClassic/DisputeKitClassic"; import { KlerosCore } from "../generated/KlerosCore/KlerosCore"; -import { - ClassicDispute, - ClassicJustification, - ClassicRound, - ClassicVote, - Dispute, - DisputeKit, - Round, -} from "../generated/schema"; +import { ClassicDispute, ClassicJustification, ClassicRound, ClassicVote, Dispute, Round } from "../generated/schema"; import { ensureClassicContributionFromEvent } from "./entities/ClassicContribution"; import { createClassicDisputeFromEvent } from "./entities/ClassicDispute"; import { @@ -27,14 +19,19 @@ import { updateCountsAndGetCurrentRuling, } from "./entities/ClassicRound"; import { ensureClassicVote } from "./entities/ClassicVote"; -import { ONE, ZERO, extractDisputeKitIDFromExtraData } from "./utils"; +import { ONE, extractDisputeKitIDFromExtraData } from "./utils"; export function handleDisputeCreation(event: DisputeCreation): void { const disputeID = event.params._coreDisputeID.toString(); const disputeKitID = extractDisputeKitIDFromExtraData(event.params._extraData); - createClassicDisputeFromEvent(event, disputeKitID); - const numberOfChoices = event.params._numberOfChoices; - createClassicRound(disputeID, numberOfChoices, ZERO, disputeKitID); + + const disputeKitClassic = DisputeKitClassic.bind(event.address); + const klerosCore = KlerosCore.bind(disputeKitClassic.core()); + const totalRounds = klerosCore.getNumberOfRounds(event.params._coreDisputeID); + const newRoundIndex = totalRounds.minus(ONE); + + createClassicDisputeFromEvent(event, disputeKitID, newRoundIndex); + createClassicRound(disputeID, event.params._numberOfChoices, newRoundIndex, disputeKitID); } export function handleCommitCast(event: CommitCast): void { @@ -156,16 +153,23 @@ export function handleChoiceFunded(event: ChoiceFunded): void { const numberOfRounds = klerosCore.getNumberOfRounds(BigInt.fromString(coreDisputeID)); const roundInfo = klerosCore.getRoundInfo(BigInt.fromString(coreDisputeID), numberOfRounds.minus(ONE)); const appealCost = roundInfo.totalFeesForJurors; + const currentDisputeKitID = roundInfo.disputeKitID; localRound.feeRewards = localRound.feeRewards.minus(appealCost); + const newRoundInfo = klerosCore.getRoundInfo(BigInt.fromString(coreDisputeID), numberOfRounds); + const newDisputeKitID = newRoundInfo.disputeKitID; + const localDispute = ClassicDispute.load(`${disputeKitID}-${coreDisputeID}`); if (!localDispute) return; - const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); - const numberOfChoices = localDispute.numberOfChoices; - localDispute.currentLocalRoundIndex = newRoundIndex; - localDispute.save(); - createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex, disputeKitID); + + if (currentDisputeKitID === newDisputeKitID) { + const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); + const numberOfChoices = localDispute.numberOfChoices; + localDispute.currentLocalRoundIndex = newRoundIndex; + localDispute.save(); + createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex, disputeKitID); + } } localRound.save(); diff --git a/subgraph/core/src/entities/ClassicDispute.ts b/subgraph/core/src/entities/ClassicDispute.ts index 78bfdc69d..dfdd24532 100644 --- a/subgraph/core/src/entities/ClassicDispute.ts +++ b/subgraph/core/src/entities/ClassicDispute.ts @@ -1,13 +1,12 @@ -import { Bytes } from "@graphprotocol/graph-ts"; +import { BigInt } from "@graphprotocol/graph-ts"; import { DisputeCreation } from "../../generated/DisputeKitClassic/DisputeKitClassic"; import { ClassicDispute } from "../../generated/schema"; -import { ZERO } from "../utils"; -export function createClassicDisputeFromEvent(event: DisputeCreation, disputeKitID: string): void { +export function createClassicDisputeFromEvent(event: DisputeCreation, disputeKitID: string, roundIndex: BigInt): void { const coreDisputeID = event.params._coreDisputeID.toString(); const classicDispute = new ClassicDispute(`${disputeKitID}-${coreDisputeID}`); classicDispute.coreDispute = coreDisputeID; - classicDispute.currentLocalRoundIndex = ZERO; + classicDispute.currentLocalRoundIndex = roundIndex; classicDispute.numberOfChoices = event.params._numberOfChoices; classicDispute.extraData = event.params._extraData; classicDispute.timestamp = event.block.timestamp; From 44ea55e482bd4a3cb851ace3cdf10c0068dbb4d7 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Thu, 8 May 2025 16:12:06 +0200 Subject: [PATCH 20/26] fix: correct round check --- subgraph/core/src/DisputeKitClassic.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/subgraph/core/src/DisputeKitClassic.ts b/subgraph/core/src/DisputeKitClassic.ts index 4df1600c9..894ab9827 100644 --- a/subgraph/core/src/DisputeKitClassic.ts +++ b/subgraph/core/src/DisputeKitClassic.ts @@ -153,17 +153,15 @@ export function handleChoiceFunded(event: ChoiceFunded): void { const numberOfRounds = klerosCore.getNumberOfRounds(BigInt.fromString(coreDisputeID)); const roundInfo = klerosCore.getRoundInfo(BigInt.fromString(coreDisputeID), numberOfRounds.minus(ONE)); const appealCost = roundInfo.totalFeesForJurors; - const currentDisputeKitID = roundInfo.disputeKitID; localRound.feeRewards = localRound.feeRewards.minus(appealCost); - const newRoundInfo = klerosCore.getRoundInfo(BigInt.fromString(coreDisputeID), numberOfRounds); - const newDisputeKitID = newRoundInfo.disputeKitID; + const newDisputeKitID = roundInfo.disputeKitID; const localDispute = ClassicDispute.load(`${disputeKitID}-${coreDisputeID}`); if (!localDispute) return; - if (currentDisputeKitID === newDisputeKitID) { + if (BigInt.fromString(disputeKitID) === newDisputeKitID) { const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); const numberOfChoices = localDispute.numberOfChoices; localDispute.currentLocalRoundIndex = newRoundIndex; From a995e1ea8f3bb98636c5c962d9dbe95b252e10d4 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 8 May 2025 15:37:19 +0100 Subject: [PATCH 21/26] chore: subgraph update scripts now relies on a template and removes data sources not deployed e.g. DisputeKitShutter on testnet --- subgraph/core-neo/subgraph.template.yaml | 202 +++++++++++++++++ subgraph/core-neo/subgraph.yaml | 1 + .../core-university/subgraph.template.yaml | 160 +++++++++++++ subgraph/core-university/subgraph.yaml | 9 +- subgraph/core/subgraph.template.yaml | 214 ++++++++++++++++++ subgraph/core/subgraph.yaml | 1 + .../subgraph.template.yaml | 24 ++ .../dispute-template-registry/subgraph.yaml | 1 + subgraph/scripts/all.sh | 2 +- subgraph/scripts/update.sh | 58 ++++- 10 files changed, 657 insertions(+), 15 deletions(-) create mode 100644 subgraph/core-neo/subgraph.template.yaml create mode 100644 subgraph/core-university/subgraph.template.yaml create mode 100644 subgraph/core/subgraph.template.yaml create mode 100644 subgraph/dispute-template-registry/subgraph.template.yaml diff --git a/subgraph/core-neo/subgraph.template.yaml b/subgraph/core-neo/subgraph.template.yaml new file mode 100644 index 000000000..d2be35a78 --- /dev/null +++ b/subgraph/core-neo/subgraph.template.yaml @@ -0,0 +1,202 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +features: + - fullTextSearch +dataSources: + - kind: ethereum + name: KlerosCore + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: KlerosCore + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - User + - Arbitrable + - TokenAndETHShift + - JurorTokensPerCourt + - Court + - Dispute + - Round + - Draw + - DisputeKit + - Counter + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleNeo.json + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicNeo.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreNeo.json + eventHandlers: + - event: AppealDecision(indexed uint256,indexed address) + handler: handleAppealDecision + - event: DisputeCreation(indexed uint256,indexed address) + handler: handleDisputeCreation + receipt: true + - event: Draw(indexed address,indexed uint256,uint256,uint256) + handler: handleDraw + - event: NewPeriod(indexed uint256,uint8) + handler: handleNewPeriod + - event: CourtCreated(indexed uint256,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + - event: CourtModified(indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4]) + handler: handleCourtModified + - event: DisputeKitCreated(indexed uint256,indexed address) + handler: handleDisputeKitCreated + - event: DisputeKitEnabled(indexed uint96,indexed uint256,indexed bool) + handler: handleDisputeKitEnabled + - event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address) + handler: handleTokenAndETHShift + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling + - event: AcceptedFeeToken(indexed address,indexed bool) + handler: handleAcceptedFeeToken + - event: CourtJump(indexed uint256,indexed uint256,indexed uint96,uint96) + handler: handleCourtJump + file: ./src/KlerosCore.ts + - kind: ethereum + name: PolicyRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: PolicyRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Court + abis: + - name: PolicyRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/PolicyRegistry.json + eventHandlers: + - event: PolicyUpdate(indexed uint256,string,string) + handler: handlePolicyUpdate + file: ./src/PolicyRegistry.ts + - kind: ethereum + name: DisputeKitClassic + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitClassic + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicNeo.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreNeo.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + handler: handleDisputeCreation + - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleContributionEvent + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal + - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: DisputeKitShutter + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitShutter + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitShutter + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitShutter.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + handler: handleDisputeCreation + - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleContributionEvent + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal + - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: EvidenceModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: EvidenceModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicEvidenceGroup + - ClassicEvidence + abis: + - name: EvidenceModule + file: ../../contracts/deployments/_PLACEHOLDER_/EvidenceModule.json + eventHandlers: + - event: Evidence(indexed uint256,indexed address,string) + handler: handleEvidenceEvent + file: ./src/EvidenceModule.ts + - kind: ethereum + name: SortitionModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: SortitionModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - JurorTokensPerCourt + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleNeo.json + eventHandlers: + - event: StakeDelayedAlreadyTransferredDeposited(indexed address,uint256,uint256) + handler: handleStakeDelayedAlreadyTransferredDeposited + - event: StakeDelayedAlreadyTransferredWithdrawn(indexed address,indexed uint96,uint256) + handler: handleStakeDelayedAlreadyTransferredWithdrawn + - event: StakeDelayedNotTransferred(indexed address,uint256,uint256) + handler: handleStakeDelayedNotTransferred + - event: StakeLocked(indexed address,uint256,bool) + handler: handleStakeLocked + - event: StakeSet(indexed address,uint256,uint256,uint256) + handler: handleStakeSet + file: ./src/SortitionModule.ts diff --git a/subgraph/core-neo/subgraph.yaml b/subgraph/core-neo/subgraph.yaml index ff00a883f..ae70065e2 100644 --- a/subgraph/core-neo/subgraph.yaml +++ b/subgraph/core-neo/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: ./schema.graphql diff --git a/subgraph/core-university/subgraph.template.yaml b/subgraph/core-university/subgraph.template.yaml new file mode 100644 index 000000000..06dc82e46 --- /dev/null +++ b/subgraph/core-university/subgraph.template.yaml @@ -0,0 +1,160 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +features: + - fullTextSearch +dataSources: + - kind: ethereum + name: KlerosCore + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: KlerosCore + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - User + - Arbitrable + - TokenAndETHShift + - JurorTokensPerCourt + - Court + - Dispute + - Round + - Draw + - DisputeKit + - Counter + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleUniversity.json + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicUniversity.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreUniversity.json + eventHandlers: + - event: AppealDecision(indexed uint256,indexed address) + handler: handleAppealDecision + - event: DisputeCreation(indexed uint256,indexed address) + handler: handleDisputeCreation + receipt: true + - event: Draw(indexed address,indexed uint256,uint256,uint256) + handler: handleDraw + - event: NewPeriod(indexed uint256,uint8) + handler: handleNewPeriod + - event: CourtCreated(indexed uint256,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + - event: CourtModified(indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4]) + handler: handleCourtModified + - event: DisputeKitCreated(indexed uint256,indexed address) + handler: handleDisputeKitCreated + - event: DisputeKitEnabled(indexed uint96,indexed uint256,indexed bool) + handler: handleDisputeKitEnabled + - event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address) + handler: handleTokenAndETHShift + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling + - event: AcceptedFeeToken(indexed address,indexed bool) + handler: handleAcceptedFeeToken + - event: CourtJump(indexed uint256,indexed uint256,indexed uint96,uint96) + handler: handleCourtJump + file: ./src/KlerosCore.ts + - kind: ethereum + name: PolicyRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: PolicyRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Court + abis: + - name: PolicyRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/PolicyRegistry.json + eventHandlers: + - event: PolicyUpdate(indexed uint256,string,string) + handler: handlePolicyUpdate + file: ./src/PolicyRegistry.ts + - kind: ethereum + name: DisputeKitClassic + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitClassic + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicUniversity.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreUniversity.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + handler: handleDisputeCreation + - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleContributionEvent + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal + - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: EvidenceModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: EvidenceModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicEvidenceGroup + - ClassicEvidence + abis: + - name: EvidenceModule + file: ../../contracts/deployments/_PLACEHOLDER_/EvidenceModule.json + eventHandlers: + - event: Evidence(indexed uint256,indexed address,string) + handler: handleEvidenceEvent + file: ./src/EvidenceModule.ts + - kind: ethereum + name: SortitionModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: SortitionModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - JurorTokensPerCourt + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleUniversity.json + eventHandlers: + - event: StakeLocked(indexed address,uint256,bool) + handler: handleStakeLocked + - event: StakeSet(indexed address,uint256,uint256,uint256) + handler: handleStakeSet + file: ./src/SortitionModule.ts diff --git a/subgraph/core-university/subgraph.yaml b/subgraph/core-university/subgraph.yaml index a0398c2f8..d820954c8 100644 --- a/subgraph/core-university/subgraph.yaml +++ b/subgraph/core-university/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: ./schema.graphql @@ -64,9 +65,9 @@ dataSources: name: PolicyRegistry network: arbitrum-sepolia source: - address: "0x2AC2EdFD336732bc6963f1AD03ED98B22dB949da" + address: "0x31d067405184d7FaA64b0834511cBcFAF32CdC4b" abi: PolicyRegistry - startBlock: 3084568 + startBlock: 141215158 mapping: kind: ethereum/events apiVersion: 0.0.7 @@ -119,9 +120,9 @@ dataSources: name: EvidenceModule network: arbitrum-sepolia source: - address: "0x57fd453FB0d16f8ca174E7386102D7170E17Be09" + address: "0x990f44d19a5F46889801B31bf58e0536fBECf27C" abi: EvidenceModule - startBlock: 3638735 + startBlock: 141215177 mapping: kind: ethereum/events apiVersion: 0.0.7 diff --git a/subgraph/core/subgraph.template.yaml b/subgraph/core/subgraph.template.yaml new file mode 100644 index 000000000..e53b7d3e1 --- /dev/null +++ b/subgraph/core/subgraph.template.yaml @@ -0,0 +1,214 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +features: + - fullTextSearch +dataSources: + - kind: ethereum + name: KlerosCore + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: KlerosCore + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - User + - Arbitrable + - TokenAndETHShift + - JurorTokensPerCourt + - Court + - Dispute + - Round + - Draw + - DisputeKit + - Counter + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModule.json + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassic.json + - name: KlerosCore + # FIX: temporarily point to the abi with event addition. + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: AppealDecision(indexed uint256,indexed address) + handler: handleAppealDecision + - event: DisputeCreation(indexed uint256,indexed address) + handler: handleDisputeCreation + receipt: true + - event: Draw(indexed address,indexed uint256,uint256,uint256) + handler: handleDraw + - event: NewPeriod(indexed uint256,uint8) + handler: handleNewPeriod + - event: CourtCreated(indexed uint96,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + # FIX: This is support for old signature + - event: CourtCreated(indexed uint256,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + - event: CourtModified(indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4]) + handler: handleCourtModified + - event: DisputeKitCreated(indexed uint256,indexed address) + handler: handleDisputeKitCreated + - event: DisputeKitEnabled(indexed uint96,indexed uint256,indexed bool) + handler: handleDisputeKitEnabled + - event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address) + handler: handleTokenAndETHShift + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling + - event: AcceptedFeeToken(indexed address,indexed bool) + handler: handleAcceptedFeeToken + - event: CourtJump(indexed uint256,indexed uint256,indexed uint96,uint96) + handler: handleCourtJump + file: ./src/KlerosCore.ts + - kind: ethereum + name: PolicyRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: PolicyRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Court + abis: + - name: PolicyRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/PolicyRegistry.json + eventHandlers: + - event: PolicyUpdate(indexed uint256,string,string) + handler: handlePolicyUpdate + file: ./src/PolicyRegistry.ts + - kind: ethereum + name: DisputeKitClassic + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitClassic + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassic.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + handler: handleDisputeCreation + - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleContributionEvent + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal + - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: DisputeKitShutter + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitShutter + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitShutter + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitShutter.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + handler: handleDisputeCreation + - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleContributionEvent + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal + - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: EvidenceModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: EvidenceModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicEvidenceGroup + - ClassicEvidence + abis: + - name: EvidenceModule + file: ../../contracts/deployments/_PLACEHOLDER_/EvidenceModule.json + eventHandlers: + - event: Evidence(indexed uint256,indexed address,string) + handler: handleEvidenceEvent + file: ./src/EvidenceModule.ts + - kind: ethereum + name: SortitionModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: SortitionModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - JurorTokensPerCourt + abis: + - name: SortitionModule + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/SortitionModule.json + eventHandlers: + - event: StakeDelayedAlreadyTransferredDeposited(indexed address,uint256,uint256) + handler: handleStakeDelayedAlreadyTransferredDeposited + # FIX: temporarily indexing old event name + - event: StakeDelayedAlreadyTransferred(indexed address,uint256,uint256) + handler: handleStakeDelayedAlreadyTransferred + - event: StakeDelayedAlreadyTransferredWithdrawn(indexed address,indexed uint96,uint256) + handler: handleStakeDelayedAlreadyTransferredWithdrawn + - event: StakeDelayedNotTransferred(indexed address,uint256,uint256) + handler: handleStakeDelayedNotTransferred + - event: StakeLocked(indexed address,uint256,bool) + handler: handleStakeLocked + - event: StakeSet(indexed address,uint256,uint256,uint256) + handler: handleStakeSet + # FIX: old stake set signature + - event: StakeSet(indexed address,uint256,uint256) + handler: handleStakeSet + file: ./src/SortitionModule.ts diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index 3774eef0d..81e080ca7 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: ./schema.graphql diff --git a/subgraph/dispute-template-registry/subgraph.template.yaml b/subgraph/dispute-template-registry/subgraph.template.yaml new file mode 100644 index 000000000..36f784c12 --- /dev/null +++ b/subgraph/dispute-template-registry/subgraph.template.yaml @@ -0,0 +1,24 @@ +specVersion: 0.0.5 +schema: + file: schema.graphql +dataSources: + - kind: ethereum + name: DisputeTemplateRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeTemplateRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - DisputeTemplate + abis: + - name: DisputeTemplateRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeTemplateRegistry.json + eventHandlers: + - event: DisputeTemplate(indexed uint256,indexed string,string,string) + handler: handleDisputeTemplate + file: src/DisputeTemplateRegistry.ts diff --git a/subgraph/dispute-template-registry/subgraph.yaml b/subgraph/dispute-template-registry/subgraph.yaml index 1fdfc46b6..0e57a2280 100644 --- a/subgraph/dispute-template-registry/subgraph.yaml +++ b/subgraph/dispute-template-registry/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: schema.graphql diff --git a/subgraph/scripts/all.sh b/subgraph/scripts/all.sh index 0902ec6f4..3c2b5269b 100755 --- a/subgraph/scripts/all.sh +++ b/subgraph/scripts/all.sh @@ -10,7 +10,7 @@ then exit 1 fi -for subgraph in core drt +for subgraph in core core-neo core-university drt do echo "Running for ${cmdPrefix}:${subgraph}${cmdPostfix:+:}${cmdPostfix}" yarn "${cmdPrefix}:${subgraph}${cmdPostfix:+:}${cmdPostfix}" diff --git a/subgraph/scripts/update.sh b/subgraph/scripts/update.sh index d1223e3ff..3459d30d9 100755 --- a/subgraph/scripts/update.sh +++ b/subgraph/scripts/update.sh @@ -1,9 +1,26 @@ #!/usr/bin/env bash -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -function update() #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex #contract -{ +function isContractDeployed() { #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex #contract + local hardhatNetwork="$1" + local graphNetwork="$2" + local subgraphConfig="$3" + local dataSourceIndex="$4" + local dataSourceName="$5" + + # Get the deployment artifact + local contractName=$(basename $(yq '.dataSources['$dataSourceIndex'].mapping.abis[] | select(.name == "'$dataSourceName'") | .file' "$subgraphConfig") .json) + local artifact="$SCRIPT_DIR/../../contracts/deployments/$hardhatNetwork/$contractName.json" + + if [ -f "$artifact" ]; then + return 0 # success in bash + else + return 1 # failure in bash + fi +} + +function update() { #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex #contract local hardhatNetwork="$1" local graphNetwork="$2" local subgraphConfig="$3" @@ -25,15 +42,14 @@ function update() #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex yq -i ".dataSources[$dataSourceIndex].source.startBlock=$blockNumber" "$subgraphConfig" # Set the Graph network - graphNetwork=$graphNetwork yq -i ".dataSources[$dataSourceIndex].network=env(graphNetwork)" "$subgraphConfig" + graphNetwork=$graphNetwork yq -i ".dataSources[$dataSourceIndex].network=env(graphNetwork)" "$subgraphConfig" # Set the ABIs path for this Hardhat network local abiIndex=0 - for f in $(yq e .dataSources[$dataSourceIndex].mapping.abis[].file "$subgraphConfig" -o json -I 0 | jq -sr '.[]') - do + for f in $(yq e .dataSources[$dataSourceIndex].mapping.abis[].file "$subgraphConfig" -o json -I 0 | jq -sr '.[]'); do f2=$(echo $f | sed "s|\(.*\/deployments\/\).*\/|\1$hardhatNetwork\/|") yq -i ".dataSources[$dataSourceIndex].mapping.abis[$abiIndex].file=\"$f2\"" "$subgraphConfig" - (( ++abiIndex )) + ((++abiIndex)) done } @@ -49,9 +65,31 @@ echo "Updating $subgraphConfig" # backup cp "$subgraphConfig" "$subgraphConfig.bak.$(date +%s)" +# initialize from template +template="${subgraphConfig%.yaml}.template.yaml" +echo '# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST.' > "$subgraphConfig" +cat "$template" >>"$subgraphConfig" + +# find contracts that are not deployed +notDeployedSourceIndices=() +i=0 +for contract in $(yq .dataSources[].name "$subgraphConfig"); do + if ! isContractDeployed $hardhatNetwork $graphNetwork "$subgraphConfig" $i $contract; then + echo -e "\e[1;31mContract $contract is not deployed\e[0m" + notDeployedSourceIndices+=($i) + fi + ((++i)) +done + +# delete the data sources for the contracts that are not deployed +for i in "${notDeployedSourceIndices[@]}"; do + echo -e "\e[1;31mDeleting data source $i\e[0m" + yq -i 'del(.dataSources['$i'])' "$subgraphConfig" +done + +# update the data sources i=0 -for contract in $(yq .dataSources[].name "$subgraphConfig") -do +for contract in $(yq .dataSources[].name "$subgraphConfig"); do update $hardhatNetwork $graphNetwork "$subgraphConfig" $i $contract - (( ++i )) + ((++i)) done From 78b29511387e8e57f7f97cd26ce16f0750c5a635 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 13 May 2025 18:32:33 +0100 Subject: [PATCH 22/26] chore: fix to support deployment to Alchemy --- subgraph/core/subgraph.template.yaml | 2 ++ subgraph/core/subgraph.yaml | 2 ++ subgraph/package.json | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/subgraph/core/subgraph.template.yaml b/subgraph/core/subgraph.template.yaml index e53b7d3e1..19bd8d49d 100644 --- a/subgraph/core/subgraph.template.yaml +++ b/subgraph/core/subgraph.template.yaml @@ -139,6 +139,8 @@ dataSources: abis: - name: DisputeKitShutter file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitShutter.json + - name: DisputeKitClassic # Required on Alchemy + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassic.json - name: KlerosCore # FIX: temporarily point to abi with event addition file: ./abi-migrations/KlerosCore.json diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index 81e080ca7..41d8eb000 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -140,6 +140,8 @@ dataSources: abis: - name: DisputeKitShutter file: ../../contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json + - name: DisputeKitClassic # Testing for Alchemy + file: ../../contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json - name: KlerosCore # FIX: temporarily point to abi with event addition file: ./abi-migrations/KlerosCore.json diff --git a/subgraph/package.json b/subgraph/package.json index 8f4575778..b2599e3e8 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@kleros/kleros-v2-subgraph", - "version": "0.16.0", + "version": "0.16.1", "drtVersion": "0.12.0", "license": "MIT", "scripts": { From 6b32fc3ece20112e8e2f55c8a6948d50f896c427 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 13 May 2025 20:31:05 +0100 Subject: [PATCH 23/26] chore: lock file --- yarn.lock | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index e613461d6..c38896dd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5560,6 +5560,7 @@ __metadata: "@nomiclabs/hardhat-solhint": "npm:^4.0.1" "@openzeppelin/contracts": "npm:^5.2.0" "@openzeppelin/upgrades-core": "npm:^1.42.2" + "@shutter-network/shutter-sdk": "npm:^0.0.1" "@typechain/ethers-v6": "npm:^0.5.1" "@typechain/hardhat": "npm:^9.1.0" "@types/chai": "npm:^4.3.20" @@ -5585,7 +5586,7 @@ __metadata: hardhat-gas-reporter: "npm:^2.2.2" hardhat-tracer: "npm:^3.1.0" hardhat-watcher: "npm:^2.5.0" - node-fetch: "npm:^3.3.2" + isomorphic-fetch: "npm:^3.0.0" pino: "npm:^8.21.0" pino-pretty: "npm:^10.3.1" prettier: "npm:^3.3.3" @@ -6888,6 +6889,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:1.8.2": + version: 1.8.2 + resolution: "@noble/curves@npm:1.8.2" + dependencies: + "@noble/hashes": "npm:1.7.2" + checksum: 10/540e7b7a8fe92ecd5cef846f84d07180662eb7fd7d8e9172b8960c31827e74f148fe4630da962138a6be093ae9f8992d14ab23d3682a2cc32be839aa57c03a46 + languageName: node + linkType: hard + "@noble/curves@npm:^1.7.0": version: 1.7.0 resolution: "@noble/curves@npm:1.7.0" @@ -6946,6 +6956,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.7.2": + version: 1.7.2 + resolution: "@noble/hashes@npm:1.7.2" + checksum: 10/b5af9e4b91543dcc46a811b5b2c57bfdeb41728361979a19d6110a743e2cb0459872553f68d3a46326d21959964db2776b8c8b4db85ac1d9f63ebcaddf7d59b6 + languageName: node + linkType: hard + "@noble/hashes@npm:^1.6.1": version: 1.6.1 resolution: "@noble/hashes@npm:1.6.1" @@ -8561,6 +8578,17 @@ __metadata: languageName: node linkType: hard +"@shutter-network/shutter-sdk@npm:^0.0.1": + version: 0.0.1 + resolution: "@shutter-network/shutter-sdk@npm:0.0.1" + dependencies: + browser-or-node: "npm:^3.0.0" + lodash: "npm:^4.17.21" + viem: "npm:^2.23.2" + checksum: 10/5e021c9dc27cb88dd487e1a289501394302d88fe349a873525610405eb2b351563556b1d0ef2ac789cff99b03ba6019c0a9761a093a0aef5a82941986ca58517 + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.24.1": version: 0.24.51 resolution: "@sinclair/typebox@npm:0.24.51" @@ -12998,6 +13026,13 @@ __metadata: languageName: node linkType: hard +"browser-or-node@npm:^3.0.0": + version: 3.0.0 + resolution: "browser-or-node@npm:3.0.0" + checksum: 10/51d74cc5d0139da3d37e83ff3906fcca20d02c42aa8b81a48d9ea01806f36df1a4b55006670071b1d7423967777275920054ec8b723410534b580b0232c5093d + languageName: node + linkType: hard + "browser-process-hrtime@npm:^1.0.0": version: 1.0.0 resolution: "browser-process-hrtime@npm:1.0.0" @@ -21191,6 +21226,16 @@ __metadata: languageName: node linkType: hard +"isomorphic-fetch@npm:^3.0.0": + version: 3.0.0 + resolution: "isomorphic-fetch@npm:3.0.0" + dependencies: + node-fetch: "npm:^2.6.1" + whatwg-fetch: "npm:^3.4.1" + checksum: 10/568fe0307528c63405c44dd3873b7b6c96c0d19ff795cb15846e728b6823bdbc68cc8c97ac23324509661316f12f551e43dac2929bc7030b8bc4d6aa1158b857 + languageName: node + linkType: hard + "isomorphic-timers-promises@npm:^1.0.1": version: 1.0.1 resolution: "isomorphic-timers-promises@npm:1.0.1" @@ -33432,6 +33477,27 @@ __metadata: languageName: node linkType: hard +"viem@npm:^2.23.2": + version: 2.29.2 + resolution: "viem@npm:2.29.2" + dependencies: + "@noble/curves": "npm:1.8.2" + "@noble/hashes": "npm:1.7.2" + "@scure/bip32": "npm:1.6.2" + "@scure/bip39": "npm:1.5.4" + abitype: "npm:1.0.8" + isows: "npm:1.0.6" + ox: "npm:0.6.9" + ws: "npm:8.18.1" + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/deaddf43517beb44d1f17b6229a8c2a323f99533f27319e8176de071549aa9e6247c68ed915fb0f69bb84e2e85e880f17efc4564f7f23adb34c78f90b56c2c9c + languageName: node + linkType: hard + "vite-node@npm:1.6.1": version: 1.6.1 resolution: "vite-node@npm:1.6.1" @@ -34161,6 +34227,13 @@ __metadata: languageName: node linkType: hard +"whatwg-fetch@npm:^3.4.1": + version: 3.6.20 + resolution: "whatwg-fetch@npm:3.6.20" + checksum: 10/2b4ed92acd6a7ad4f626a6cb18b14ec982bbcaf1093e6fe903b131a9c6decd14d7f9c9ca3532663c2759d1bdf01d004c77a0adfb2716a5105465c20755a8c57c + languageName: node + linkType: hard + "whatwg-fetch@npm:^3.6.2": version: 3.6.2 resolution: "whatwg-fetch@npm:3.6.2" From 14994dbbaaeb7a187ab5a00771eb737b3c1f245e Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Thu, 15 May 2025 17:39:36 +0200 Subject: [PATCH 24/26] fix: bug fix in subgraph --- subgraph/core/src/DisputeKitClassic.ts | 2 +- subgraph/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subgraph/core/src/DisputeKitClassic.ts b/subgraph/core/src/DisputeKitClassic.ts index 894ab9827..2b6e8b2c5 100644 --- a/subgraph/core/src/DisputeKitClassic.ts +++ b/subgraph/core/src/DisputeKitClassic.ts @@ -161,7 +161,7 @@ export function handleChoiceFunded(event: ChoiceFunded): void { const localDispute = ClassicDispute.load(`${disputeKitID}-${coreDisputeID}`); if (!localDispute) return; - if (BigInt.fromString(disputeKitID) === newDisputeKitID) { + if (BigInt.fromString(disputeKitID).equals(newDisputeKitID)) { const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); const numberOfChoices = localDispute.numberOfChoices; localDispute.currentLocalRoundIndex = newRoundIndex; diff --git a/subgraph/package.json b/subgraph/package.json index b2599e3e8..511ff0fa9 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@kleros/kleros-v2-subgraph", - "version": "0.16.1", + "version": "0.16.2", "drtVersion": "0.12.0", "license": "MIT", "scripts": { From 598992825f461ec49fca852d37769d855f2206e4 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Fri, 16 May 2025 12:23:46 +0100 Subject: [PATCH 25/26] chore: subgraphs version bump --- subgraph/core-neo/subgraph.template.yaml | 2 ++ subgraph/core-university/subgraph.template.yaml | 2 ++ subgraph/core/subgraph.template.yaml | 2 ++ subgraph/core/subgraph.yaml | 4 +++- subgraph/dispute-template-registry/subgraph.template.yaml | 2 ++ subgraph/dispute-template-registry/subgraph.yaml | 2 ++ subgraph/package.json | 4 ++-- 7 files changed, 15 insertions(+), 3 deletions(-) diff --git a/subgraph/core-neo/subgraph.template.yaml b/subgraph/core-neo/subgraph.template.yaml index d2be35a78..5a16083d0 100644 --- a/subgraph/core-neo/subgraph.template.yaml +++ b/subgraph/core-neo/subgraph.template.yaml @@ -1,4 +1,6 @@ specVersion: 0.0.5 +description: Kleros v2 Core Neo +repository: https://github.com/kleros/kleros-v2/tree/dev/subgraph/core-neo schema: file: ./schema.graphql features: diff --git a/subgraph/core-university/subgraph.template.yaml b/subgraph/core-university/subgraph.template.yaml index 06dc82e46..9e83ab0ee 100644 --- a/subgraph/core-university/subgraph.template.yaml +++ b/subgraph/core-university/subgraph.template.yaml @@ -1,4 +1,6 @@ specVersion: 0.0.5 +description: Kleros v2 Core University +repository: https://github.com/kleros/kleros-v2/tree/dev/subgraph/core-university schema: file: ./schema.graphql features: diff --git a/subgraph/core/subgraph.template.yaml b/subgraph/core/subgraph.template.yaml index 19bd8d49d..e9373e727 100644 --- a/subgraph/core/subgraph.template.yaml +++ b/subgraph/core/subgraph.template.yaml @@ -1,4 +1,6 @@ specVersion: 0.0.5 +description: Kleros v2 Core +repository: https://github.com/kleros/kleros-v2/tree/dev/subgraph/core schema: file: ./schema.graphql features: diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index 41d8eb000..1a758b234 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -1,5 +1,7 @@ # THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 +description: Kleros v2 Core +repository: https://github.com/kleros/kleros-v2/tree/dev/subgraph/core schema: file: ./schema.graphql features: @@ -140,7 +142,7 @@ dataSources: abis: - name: DisputeKitShutter file: ../../contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json - - name: DisputeKitClassic # Testing for Alchemy + - name: DisputeKitClassic # Required on Alchemy file: ../../contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json - name: KlerosCore # FIX: temporarily point to abi with event addition diff --git a/subgraph/dispute-template-registry/subgraph.template.yaml b/subgraph/dispute-template-registry/subgraph.template.yaml index 36f784c12..b45f5c1f7 100644 --- a/subgraph/dispute-template-registry/subgraph.template.yaml +++ b/subgraph/dispute-template-registry/subgraph.template.yaml @@ -1,4 +1,6 @@ specVersion: 0.0.5 +description: Kleros v2 Dispute Template Registry +repository: https://github.com/kleros/kleros-v2/tree/dev/subgraph/dispute-template-registry schema: file: schema.graphql dataSources: diff --git a/subgraph/dispute-template-registry/subgraph.yaml b/subgraph/dispute-template-registry/subgraph.yaml index 0e57a2280..4186d81c9 100644 --- a/subgraph/dispute-template-registry/subgraph.yaml +++ b/subgraph/dispute-template-registry/subgraph.yaml @@ -1,5 +1,7 @@ # THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 +description: Kleros v2 Dispute Template Registry +repository: https://github.com/kleros/kleros-v2/tree/dev/subgraph/dispute-template-registry schema: file: schema.graphql dataSources: diff --git a/subgraph/package.json b/subgraph/package.json index 511ff0fa9..6b9ebb2cb 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,7 +1,7 @@ { "name": "@kleros/kleros-v2-subgraph", - "version": "0.16.2", - "drtVersion": "0.12.0", + "version": "0.16.3", + "drtVersion": "0.12.2", "license": "MIT", "scripts": { "update:core:arbitrum-sepolia-devnet": "./scripts/update.sh arbitrumSepoliaDevnet arbitrum-sepolia core/subgraph.yaml", From b1d3fa9857eb7a3809e303cccb0229af77376b9b Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 22 May 2025 16:22:07 +0100 Subject: [PATCH 26/26] chore: shutter event tweak, extra dispute kit views --- contracts/README.md | 2 +- .../DisputeKitShutter.json | 132 ++++++++- .../DisputeKitShutter_Implementation.json | 276 +++++++++++++----- .../dispute-kits/DisputeKitClassic.sol | 4 +- .../dispute-kits/DisputeKitClassicBase.sol | 66 +++-- .../dispute-kits/DisputeKitShutter.sol | 30 +- 6 files changed, 415 insertions(+), 95 deletions(-) diff --git a/contracts/README.md b/contracts/README.md index a9257b0a3..617ad6369 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -79,7 +79,7 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments - [DAIFaucet](https://sepolia.arbiscan.io/address/0xB5b39A1bcD2D7097A8824B3cC18Ebd2dFb0D9B5E) - [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x2246821E1313A93e2F8CdF7a3422d078f560b457), [implementation](https://sepolia.arbiscan.io/address/0x8Db69EE93365190FE9CA4d59Ae4Cdd4f3688f1Af) - [DisputeKitClassicUniversity: proxy](https://sepolia.arbiscan.io/address/0xd6E96b7c993763B5CDDa1139C7387B82A7c8B8B5), [implementation](https://sepolia.arbiscan.io/address/0x87e863b94d2CB79A8aB53bD87Dc4A10E11C0918B) -- [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD) +- [DisputeKitShutter: proxy](https://sepolia.arbiscan.io/address/0x09F3d00B995186D76Af9AA8627D06351d0d9f950), [implementation](https://sepolia.arbiscan.io/address/0x6571eE6Ee36d805A8363c09376107844a003073C) - [DisputeResolver](https://sepolia.arbiscan.io/address/0x524C5541f440204E0B4577334c439277018F971f) - [DisputeResolverRuler](https://sepolia.arbiscan.io/address/0x199893232ECC74cC7898B24b5Ff58d613029f6B7) - [DisputeResolverUniversity](https://sepolia.arbiscan.io/address/0x2Aa1a94307E772BeE42E9EfbD137b1053F1fCfd4) diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json index 9a24928d4..21cec2799 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json @@ -110,6 +110,18 @@ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_juror", + "type": "address" + }, { "indexed": true, "internalType": "bytes32", @@ -346,6 +358,35 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "localDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "localRoundID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "drawnAddress", + "type": "address" + } + ], + "name": "alreadyDrawn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -473,6 +514,39 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "castVoteShutter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -764,6 +838,54 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + } + ], + "name": "getLocalDisputeRoundID", + "outputs": [ + { + "internalType": "uint256", + "name": "localDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "localRoundID", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + } + ], + "name": "getNumberOfRounds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -924,7 +1046,7 @@ }, { "inputs": [], - "name": "initialize4", + "name": "initialize8", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1118,16 +1240,16 @@ "0x56b95cD6fd660c6E631c65C0d0F62B33A093D9a4", "0x485cc955000000000000000000000000f1c7c037891525e360c59f708739ac09a7670c590000000000000000000000004838e31e0ea315232c431598110fe677caf2d6e6" ], - "numDeployments": 3, - "solcInputHash": "96b8e3f55478438b6784f67c1730309e", + "numDeployments": 4, + "solcInputHash": "450e0980ffbfcac7e1c189d256d31822", "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/proxy/KlerosProxies.sol\":\"DisputeKitShutterProxy\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"src/proxy/KlerosProxies.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./UUPSProxy.sol\\\";\\n\\n/// Workaround to get meaningful names for the proxy contracts\\n/// Otherwise all the contracts are called `UUPSProxy` on the chain explorers\\n\\ncontract DisputeKitClassicNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitClassicProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitGatedProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitShutterProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeKitSybilResistantProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract DisputeTemplateRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract EvidenceModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract ForeignGatewayOnEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract HomeGatewayToEthereumProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreRulerProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract KlerosCoreProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract PolicyRegistryProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract RandomizerRNGProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleNeoProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleUniversityProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\\ncontract SortitionModuleProxy is UUPSProxy {\\n constructor(address _implementation, bytes memory _data) UUPSProxy(_implementation, _data) {}\\n}\\n\",\"keccak256\":\"0x209228b56d42a8444ca70919e1ded5711fba434a746f26d426e230f57526fc6c\",\"license\":\"MIT\"},\"src/proxy/UUPSProxy.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxy\\n/// @author Simon Malatrait \\n/// @dev This contract implements a UUPS Proxy compliant with ERC-1967 & ERC-1822.\\n/// @dev This contract delegates all calls to another contract (UUPS Proxiable) through a fallback function and the use of the `delegatecall` EVM instruction.\\n/// @dev We refer to the Proxiable contract (as per ERC-1822) with `implementation`.\\n/// @dev Adapted from \\ncontract UUPSProxy {\\n /// @dev Storage slot with the address of the current implementation.\\n /// This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// validated in the constructor.\\n /// NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializes the upgradeable proxy with an initial implementation specified by `_implementation`.\\n /// If `_data` is nonempty, it's used as data in a delegate call to `_implementation`. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n constructor(address _implementation, bytes memory _data) {\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, _implementation)\\n }\\n\\n if (_data.length != 0) {\\n (bool success, ) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy Constructor failed\\\");\\n }\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Delegates the current call to `implementation`.\\n /// NOTE: This function does not return to its internal call site, it will return directly to the external caller.\\n function _delegate(address implementation) internal {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n\\n // ************************************* //\\n // * Fallback * //\\n // ************************************* //\\n\\n /// @dev Fallback function that delegates calls to the address returned by `_implementation()`.\\n /// @dev Will run if no other function in the contract matches the call data.\\n fallback() external payable {\\n _delegate(_getImplementation());\\n }\\n\\n receive() external payable {\\n _delegate(_getImplementation());\\n }\\n}\\n\",\"keccak256\":\"0xc3e0b18f846a62cc6c274680fc10014d1267885f8eefc6767292d3e174a081c0\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x608060405234801561001057600080fd5b5060405161030238038061030283398101604081905261002f91610151565b8181817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55805160001461010e576000826001600160a01b031682604051610077919061021f565b600060405180830381855af49150503d80600081146100b2576040519150601f19603f3d011682016040523d82523d6000602084013e6100b7565b606091505b505090508061010c5760405162461bcd60e51b815260206004820152601860248201527f50726f787920436f6e7374727563746f72206661696c65640000000000000000604482015260640160405180910390fd5b505b5050505061023b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015610148578181015183820152602001610130565b50506000910152565b6000806040838503121561016457600080fd5b82516001600160a01b038116811461017b57600080fd5b60208401519092506001600160401b038082111561019857600080fd5b818501915085601f8301126101ac57600080fd5b8151818111156101be576101be610117565b604051601f8201601f19908116603f011681019083821181831017156101e6576101e6610117565b816040528281528860208487010111156101ff57600080fd5b61021083602083016020880161012d565b80955050505050509250929050565b6000825161023181846020870161012d565b9190910192915050565b60b9806102496000396000f3fe608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", "deployedBytecode": "0x608060405236603757603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6060565b005b603560317f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b3660008037600080366000845af43d6000803e808015607e573d6000f35b3d6000fdfea264697066735822122027e73125daa8b508f0a75ecdac4efb44a8712d5d43b9293019c738684adf472464736f6c63430008180033", "execute": { - "methodName": "initialize4", + "methodName": "initialize8", "args": [] }, - "implementation": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", + "implementation": "0x6571eE6Ee36d805A8363c09376107844a003073C", "devdoc": { "kind": "dev", "methods": {}, diff --git a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json index 2fa91c062..63b9e19e8 100644 --- a/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json +++ b/contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", + "address": "0x6571eE6Ee36d805A8363c09376107844a003073C", "abi": [ { "inputs": [], @@ -107,6 +107,18 @@ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_juror", + "type": "address" + }, { "indexed": true, "internalType": "bytes32", @@ -343,6 +355,35 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "localDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "localRoundID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "drawnAddress", + "type": "address" + } + ], + "name": "alreadyDrawn", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -470,6 +511,39 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "_voteIDs", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_choice", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salt", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_justification", + "type": "string" + } + ], + "name": "castVoteShutter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -761,6 +835,54 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_coreDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_coreRoundID", + "type": "uint256" + } + ], + "name": "getLocalDisputeRoundID", + "outputs": [ + { + "internalType": "uint256", + "name": "localDisputeID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "localRoundID", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_localDisputeID", + "type": "uint256" + } + ], + "name": "getNumberOfRounds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -921,7 +1043,7 @@ }, { "inputs": [], - "name": "initialize4", + "name": "initialize8", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1066,41 +1188,41 @@ "type": "function" } ], - "transactionHash": "0x4652912ebec3fcf633568c2731bcd2ea3f6c38efc4b55757f2c55fcd9a6af4ae", + "transactionHash": "0x99efa3a95e140ab7ae324f50139c07fd1577c21044f202ff1d5bb3378a543c3c", "receipt": { "to": null, "from": "0xf1C7c037891525E360C59f708739Ac09A7670c59", - "contractAddress": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", - "transactionIndex": 1, - "gasUsed": "3906991", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000002000000000000000000000000000000000000000000000", - "blockHash": "0x2c78cd9dcbec549968acacf96d2f6908bf4a606399d6de881daa449defb67bc4", - "transactionHash": "0x4652912ebec3fcf633568c2731bcd2ea3f6c38efc4b55757f2c55fcd9a6af4ae", + "contractAddress": "0x6571eE6Ee36d805A8363c09376107844a003073C", + "transactionIndex": 19, + "gasUsed": "3973192", + "logsBloom": "0x00001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000400000000000000000000", + "blockHash": "0x91d1179313f66b4d1db326c0609b6f8bea50277e5a984d8587a8a5e7d039e0e1", + "transactionHash": "0x99efa3a95e140ab7ae324f50139c07fd1577c21044f202ff1d5bb3378a543c3c", "logs": [ { - "transactionIndex": 1, - "blockNumber": 148226049, - "transactionHash": "0x4652912ebec3fcf633568c2731bcd2ea3f6c38efc4b55757f2c55fcd9a6af4ae", - "address": "0xFbEeF40E23C6B39e5d1190A43d6712B2643fa0dD", + "transactionIndex": 19, + "blockNumber": 155643043, + "transactionHash": "0x99efa3a95e140ab7ae324f50139c07fd1577c21044f202ff1d5bb3378a543c3c", + "address": "0x6571eE6Ee36d805A8363c09376107844a003073C", "topics": [ "0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2" ], "data": "0x000000000000000000000000000000000000000000000000ffffffffffffffff", - "logIndex": 0, - "blockHash": "0x2c78cd9dcbec549968acacf96d2f6908bf4a606399d6de881daa449defb67bc4" + "logIndex": 23, + "blockHash": "0x91d1179313f66b4d1db326c0609b6f8bea50277e5a984d8587a8a5e7d039e0e1" } ], - "blockNumber": 148226049, - "cumulativeGasUsed": "3906991", + "blockNumber": 155643043, + "cumulativeGasUsed": "5340499", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "525260efd109be98dd6a976c1b7235d3", - "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"CommitCastShutter\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"castCommitShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize4\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"CommitCastShutter(bytes32,bytes32,bytes)\":{\"details\":\"Emitted when a vote is cast.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castCommitShutter(uint256,uint256[],bytes32,bytes32,bytes)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash including the justification.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encoding\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":\"DisputeKitShutter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.8.0\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize3() external reinitializer(3) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x697705afc3f93aafded177968d141bfe919b74820f878b97a9d7b590577bf1b0\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xf61bd3332825d5b69e71b57d7c0b3acb5f4c3e64a1755004008ece59db228f56\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // Set to 'true' if the address has already been drawn, so it can't be drawn more than once.\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n round.alreadyDrawn[drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(uint256 _coreDisputeID, uint256[] calldata _voteIDs, bytes32 _commit) external {\\n _castCommit(_coreDisputeID, _voteIDs, _commit);\\n }\\n\\n function _castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external {\\n _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification);\\n }\\n\\n function _castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core\\n .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)\\n .pnkAtStakePerJuror;\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n result = result && !_round.alreadyDrawn[_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf11760d6d9407a37f0d0fc7adc7ec1a5056c167bffc1c1c785247909fcf64cc4\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitShutter\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\n/// Added functionality: an Shutter-specific event emitted when a vote is cast.\\ncontract DisputeKitShutter is DisputeKitClassicBase {\\n string public constant override version = \\\"0.9.2\\\";\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev Emitted when a vote is cast.\\n /// @param _commit The commitment hash.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity, bytes _encryptedVote);\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize4() external reinitializer(4) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash including the justification.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n function castCommitShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit,\\n bytes32 _identity,\\n bytes calldata _encryptedVote\\n ) external notJumped(_coreDisputeID) {\\n _castCommit(_coreDisputeID, _voteIDs, _commit);\\n emit CommitCastShutter(_commit, _identity, _encryptedVote);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure override returns (bytes32) {\\n bytes32 justificationHash = keccak256(bytes(_justification));\\n return keccak256(abi.encode(_choice, _salt, justificationHash));\\n }\\n}\\n\",\"keccak256\":\"0x68706bd6beb162156f5a73c7c9ca4f79bc211169e082b9fbf5747ea67859e5c7\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recepient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0x3e39adb9cdd9f86b0defc8f6e1223533d86f82c804e186193f729c32c10161b1\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6080516144cb62000103600039600081816118150152818161183e0152611a3601526144cb6000f3fe6080604052600436106101c45760003560e01c8063675926f6116100f8578063b6ede54011610090578063b6ede540146105c4578063ba66fde7146105e4578063be46760414610604578063caeb50ed1461061a578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad301461050c578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b8063675926f61461045f57806369f3f0411461047f5780636d4cd8ea146104cc578063751accd0146104ec578063796490f91461050c5780637c04034e146105225780638e42646014610542578063a7cc08fe14610562578063b34bfaa8146105ae57600080fd5b8063362c34791161016b578063362c34791461032a578063485cc9551461034a5780634b2f0ea01461036a5780634f1ef2861461037d57806352d1902d1461039057806354fd4d50146103a5578063564a565d146103e35780635c92e2f61461041257806365540b961461043257600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136a3565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613748565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136a3565b61082a565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136a3565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136a3565b6108a1565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138b2565b610a0f565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613916565b610a4c565b34801561035657600080fd5b5061021e610365366004613953565b610ed2565b61021e61037836600461398c565b610f9a565b61021e61038b3660046139ae565b611801565b34801561039c57600080fd5b506102a5611a29565b3480156103b157600080fd5b506103d66040518060400160405280600581526020016418171c971960d91b81525081565b6040516101f59190613a4d565b3480156103ef57600080fd5b506104036103fe3660046136a3565b611a87565b6040516101f593929190613a67565b34801561041e57600080fd5b5061021e61042d366004613a88565b611b4d565b34801561043e57600080fd5b5061045261044d3660046136a3565b611b59565b6040516101f59190613ada565b34801561046b57600080fd5b506102a561047a366004613b1e565b611c1d565b34801561048b57600080fd5b5061049f61049a366004613b59565b611d60565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104d857600080fd5b506101e96104e73660046136a3565b611e18565b3480156104f857600080fd5b5061021e610507366004613b85565b611f9b565b34801561051857600080fd5b506102a561271081565b34801561052e57600080fd5b5061021e61053d366004613bc7565b612067565b34801561054e57600080fd5b5061021e61055d366004613c4b565b61207d565b34801561056e57600080fd5b5061058261057d366004613b59565b6120c9565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105ba57600080fd5b506102a5614e2081565b3480156105d057600080fd5b5061021e6105df366004613c68565b61218f565b3480156105f057600080fd5b506101e96105ff366004613b59565b612352565b34801561061057600080fd5b506102a561138881565b34801561062657600080fd5b5061021e6123ed565b34801561063b57600080fd5b5061026061064a36600461398c565b61249e565b34801561065b57600080fd5b506102a561066a36600461398c565b6127b8565b34801561067b57600080fd5b5061021e61068a366004613c4b565b61290b565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cc2565b91509150600061072f85611b59565b90508051600014801561076e575061271061138861074d8585613cfc565b6107579190613d0f565b6107619190613d26565b61076b8442613cfc565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d48565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d5e565b60405180910390fd5b6107e488888888612957565b847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161081893929190613dbe565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061084e5761084e613d48565b6000918252602082206005909102018054909250829061087090600190613cfc565b8154811061088057610880613d48565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106108cd576108cd613d48565b600091825260208220600590910201805490925082906108ef90600190613cfc565b815481106108ff576108ff613d48565b60009182526020909120600d90910201600381015460ff16945090508361092a57806001015461092d565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a09190613e04565b50909350600492506109b0915050565b8160048111156109c2576109c2613e6b565b03610a055760006109d288611b59565b90508051600103610a0357806000815181106109f0576109f0613d48565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190613e04565b50935050505080610b115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b889190613e81565b15610bc65760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610bea57610bea613d48565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c1e57610c1e613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190613e9c565b5050600087815260078401602052604090205490915060ff16610ce7576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e2c565b808603610d5c576000868152600683016020526040902054610d0a576000610d55565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d4b9190613d0f565b610d559190613d26565b9450610e2c565b600081815260078301602052604090205460ff16610e2c5781600601600083600a01600181548110610d9057610d90613d48565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610dc657610dc6613d48565b9060005260206000200154815260200190815260200160002054610dea9190613ed8565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e1f9190613d0f565b610e299190613d26565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ec6576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610ede612c5c565b8054909150600160401b900460ff1680610f05575080546001600160401b03808416911610155b15610f225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f4d8484612c80565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fbe57610fbe613d48565b600091825260209091206002600590920201015460ff1615610ff25760405162461bcd60e51b81526004016107cf90613d5e565b60008381526003602052604081205460028054909190811061101657611016613d48565b90600052602060002090600502019050806001015483111561107a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156110c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110eb9190613cc2565b915091508142101580156110fe57508042105b6111435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611184573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a89190613e9c565b505090508681036111bd57612710915061123e565b6127106113886111cd8686613cfc565b6111d79190613d0f565b6111e19190613d26565b6111eb8542613cfc565b106112385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061125190600190613cfc565b8154811061126157611261613d48565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190613eeb565b6112ee9190613cfc565b60008a815260078401602052604090205490915060ff16156113525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561139c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c09190613eeb565b905060006127106113d18784613d0f565b6113db9190613d26565b6113e59083613ed8565b60008c8152600686016020526040812054919250908211156114965760008c8152600686016020526040902054349061141e9084613cfc565b116114435760008c815260068601602052604090205461143e9083613cfc565b611445565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161148d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906114c2908490613ed8565b909155505060008c8152600686016020526040812080548392906114e7908490613ed8565b909155505060008c815260068601602052604090205482116115b95760008c815260068601602052604081205460098701805491929091611529908490613ed8565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156117c4578285600901546115d69190613cfc565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116489190613e81565b156116615760028a01805460ff19166001179055611744565b895460038b016000611674876001613ed8565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016116ef91815260200190565b602060405180830381865afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117309190613eeb565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161179193929190613f3e565b6000604051808303818588803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b50505050505b803411156117f257336108fc6117da8334613cfc565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61180a82612cb6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061188857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661187c6000805160206144768339815191525490565b6001600160a01b031614155b156118a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611900575060408051601f3d908101601f191682019092526118fd91810190613eeb565b60015b61192857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b600080516020614476833981519152811461195957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144768339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a24576000836001600160a01b0316836040516119c09190613fdd565b600060405180830381855af49150503d80600081146119fb576040519150601f19603f3d011682016040523d82523d6000602084013e611a00565b606091505b5050905080611a22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a745760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061447683398151915290565b60028181548110611a9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611aca90613f04565b80601f0160208091040260200160405190810160405280929190818152602001828054611af690613f04565b8015611b435780601f10611b1857610100808354040283529160200191611b43565b820191906000526020600020905b815481529060010190602001808311611b2657829003601f168201915b5050505050905083565b611a2284848484612957565b6000818152600360205260408120546002805460609392908110611b7f57611b7f613d48565b60009182526020822060059091020180549092508290611ba190600190613cfc565b81548110611bb157611bb1613d48565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c0f57602002820191906000526020600020905b815481526020019060010190808311611bfb575b505050505092505050919050565b600085815260036020526040812054600280548392908110611c4157611c41613d48565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611c7557611c75613d48565b90600052602060002090600d02016000018681548110611c9757611c97613d48565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d199190613e9c565b506003850154919350915060ff168015611d3d57508183600201541480611d3d5750805b15611d505761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611d9157611d91613d48565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611dc557611dc5613d48565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611e3c57611e3c613d48565b60009182526020822060059091020180549092508290611e5e90600190613cfc565b81548110611e6e57611e6e613d48565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015611ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eed9190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015611f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6c9190613ff9565b5050505050915050600081611f82578354611f88565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b03163314611fc55760405162461bcd60e51b81526004016107cf90614063565b6000836001600160a01b03168383604051611fe09190613fdd565b60006040518083038185875af1925050503d806000811461201d576040519150601f19603f3d011682016040523d82523d6000602084013e612022565b606091505b5050905080611a225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b612075868686868686612ce3565b505050505050565b6000546001600160a01b031633146120a75760405162461bcd60e51b81526004016107cf90614063565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106120f7576120f7613d48565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061212b5761212b613d48565b90600052602060002090600d0201600001878154811061214d5761214d613d48565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146121b95760405162461bcd60e51b81526004016107cf906140a5565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612244858783614131565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561229b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bf9190613eeb565b6122c99190613cfc565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610818908a908a908a90613dbe565b60008381526003602052604081205460028054839290811061237657612376613d48565b600091825260208083208784526003600590930201918201905260408220548154919350839181106123aa576123aa613d48565b90600052602060002090600d020160000184815481106123cc576123cc613d48565b600091825260209091206004909102016003015460ff169695505050505050565b600460006123f9612c5c565b8054909150600160401b900460ff1680612420575080546001600160401b03808416911610155b1561243d5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b6001546000906001600160a01b031633146124cb5760405162461bcd60e51b81526004016107cf906140a5565b6000838152600360205260409020546002805485929081106124ef576124ef613d48565b600091825260209091206002600590920201015460ff16156125235760405162461bcd60e51b81526004016107cf90613d5e565b60008481526003602052604081205460028054909190811061254757612547613d48565b6000918252602082206005909102018054909250829061256990600190613cfc565b8154811061257957612579613d48565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260291906141f1565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126759190613e04565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd91906141f1565b965061270a848a896133a6565b156127a757604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556127ac565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106127dc576127dc613d48565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061281057612810613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190613e9c565b50915091508260040154600014806128c25750801580156128c257506000828152600284016020526040902054155b156128d4576000945050505050612905565b80156128e95750506004015491506129059050565b5060009081526002909101602052604090205491506129059050565b92915050565b6000546001600160a01b031633146129355760405162461bcd60e51b81526004016107cf90614063565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008481526003602052604090205460028054869290811061297b5761297b613d48565b600091825260209091206002600590920201015460ff16156129af5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa1580156129f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1d9190613e04565b5090935060019250612a2d915050565b816004811115612a3f57612a3f613e6b565b14612a9c5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82612ad95760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110612afd57612afd613d48565b60009182526020822060059091020180549092508290612b1f90600190613cfc565b81548110612b2f57612b2f613d48565b90600052602060002090600d0201905060005b86811015612bf5573382898984818110612b5e57612b5e613d48565b9050602002013581548110612b7557612b75613d48565b60009182526020909120600490910201546001600160a01b031614612bac5760405162461bcd60e51b81526004016107cf9061420e565b8582898984818110612bc057612bc0613d48565b9050602002013581548110612bd757612bd7613d48565b60009182526020909120600160049092020181019190915501612b42565b5086869050816005016000828254612c0d9190613ed8565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612c4a908b908b908b90614277565b60405180910390a35050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b612c88613662565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b03163314612ce05760405162461bcd60e51b81526004016107cf90614063565b50565b600086815260036020526040902054600280548892908110612d0757612d07613d48565b600091825260209091206002600590920201015460ff1615612d3b5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612d85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da99190613e04565b5090935060029250612db9915050565b816004811115612dcb57612dcb613e6b565b14612e265760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b85612e685760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b600088815260036020526040812054600280549091908110612e8c57612e8c613d48565b906000526020600020906005020190508060010154861115612ee75760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b80546000908290612efa90600190613cfc565b81548110612f0a57612f0a613d48565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f899190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130089190613ff9565b5050505050915050600061301d8a8a8a610a0f565b905060005b8b81101561326b5733858e8e8481811061303e5761303e613d48565b905060200201358154811061305557613055613d48565b60009182526020909120600490910201546001600160a01b03161461308c5760405162461bcd60e51b81526004016107cf9061420e565b8215806130d3575081858e8e848181106130a8576130a8613d48565b90506020020135815481106130bf576130bf613d48565b906000526020600020906004020160010154145b6131535760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d8381811061316657613166613d48565b905060200201358154811061317d5761317d613d48565b600091825260209091206003600490920201015460ff16156131d65760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e848181106131ea576131ea613d48565b905060200201358154811061320157613201613d48565b60009182526020909120600260049092020101556001858e8e8481811061322a5761322a613d48565b905060200201358154811061324157613241613d48565b60009182526020909120600490910201600301805460ff1916911515919091179055600101613022565b508b8b90508460040160008282546132839190613ed8565b909155505060008a8152600285016020526040812080548d92906132a8908490613ed8565b909155505060018401548a036132d757600384015460ff16156132d25760038401805460ff191690555b613350565b60018401546000908152600285016020526040808220548c83529120540361331957600384015460ff166132d25760038401805460ff19166001179055613350565b60018401546000908152600285016020526040808220548c8352912054111561335057600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161338f9392919061429b565b60405180910390a450505050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156133f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134189190613e04565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015613477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349b9190613eeb565b6134a59190613cfc565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156134e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261350e919081019061435e565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561356a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358e91906141f1565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156135e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613609919061443f565b505091509150828161361b9190613ed8565b60045490831015955060ff16156136575784801561365457506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b61366a613689565b61368757604051631afcd79f60e31b815260040160405180910390fd5b565b6000613693612c5c565b54600160401b900460ff16919050565b6000602082840312156136b557600080fd5b5035919050565b60008083601f8401126136ce57600080fd5b5081356001600160401b038111156136e557600080fd5b6020830191508360208260051b850101111561370057600080fd5b9250929050565b60008083601f84011261371957600080fd5b5081356001600160401b0381111561373057600080fd5b60208301915083602082850101111561370057600080fd5b600080600080600080600060a0888a03121561376357600080fd5b8735965060208801356001600160401b038082111561378157600080fd5b61378d8b838c016136bc565b909850965060408a0135955060608a0135945060808a01359150808211156137b457600080fd5b506137c18a828b01613707565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561380d5761380d6137d4565b60405290565b604051601f8201601f191681016001600160401b038111828210171561383b5761383b6137d4565b604052919050565b600082601f83011261385457600080fd5b81356001600160401b0381111561386d5761386d6137d4565b613880601f8201601f1916602001613813565b81815284602083860101111561389557600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138c757600080fd5b833592506020840135915060408401356001600160401b038111156138eb57600080fd5b6138f786828701613843565b9150509250925092565b6001600160a01b0381168114612ce057600080fd5b6000806000806080858703121561392c57600080fd5b84359350602085013561393e81613901565b93969395505050506040820135916060013590565b6000806040838503121561396657600080fd5b823561397181613901565b9150602083013561398181613901565b809150509250929050565b6000806040838503121561399f57600080fd5b50508035926020909101359150565b600080604083850312156139c157600080fd5b82356139cc81613901565b915060208301356001600160401b038111156139e757600080fd5b6139f385828601613843565b9150509250929050565b60005b83811015613a18578181015183820152602001613a00565b50506000910152565b60008151808452613a398160208601602086016139fd565b601f01601f19169290920160200192915050565b602081526000613a606020830184613a21565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a21565b60008060008060608587031215613a9e57600080fd5b8435935060208501356001600160401b03811115613abb57600080fd5b613ac7878288016136bc565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b1257835183529284019291840191600101613af6565b50909695505050505050565b600080600080600060a08688031215613b3657600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b6e57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613b9a57600080fd5b8335613ba581613901565b92506020840135915060408401356001600160401b038111156138eb57600080fd5b60008060008060008060a08789031215613be057600080fd5b8635955060208701356001600160401b0380821115613bfe57600080fd5b613c0a8a838b016136bc565b909750955060408901359450606089013593506080890135915080821115613c3157600080fd5b50613c3e89828a01613843565b9150509295509295509295565b600060208284031215613c5d57600080fd5b8135613a6081613901565b600080600080600060808688031215613c8057600080fd5b853594506020860135935060408601356001600160401b03811115613ca457600080fd5b613cb088828901613707565b96999598509660600135949350505050565b60008060408385031215613cd557600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561290557612905613ce6565b808202811582820484141761290557612905613ce6565b600082613d4357634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613d95565b80516001600160601b0381168114613def57600080fd5b919050565b80518015158114613def57600080fd5b600080600080600060a08688031215613e1c57600080fd5b613e2586613dd8565b94506020860151613e3581613901565b604087015190945060058110613e4a57600080fd5b9250613e5860608701613df4565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613e9357600080fd5b613a6082613df4565b600080600060608486031215613eb157600080fd5b83519250613ec160208501613df4565b9150613ecf60408501613df4565b90509250925092565b8082018082111561290557612905613ce6565b600060208284031215613efd57600080fd5b5051919050565b600181811c90821680613f1857607f821691505b602082108103613f3857634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613f5f81613f04565b8060608701526080600180841660008114613f815760018114613f9d57613fcd565b60ff19851660808a0152608084151560051b8a01019550613fcd565b89600052602060002060005b85811015613fc45781548b8201860152908301908801613fa9565b8a016080019650505b50939a9950505050505050505050565b60008251613fef8184602087016139fd565b9190910192915050565b600080600080600080600060e0888a03121561401457600080fd5b61401d88613dd8565b965061402b60208901613df4565b955060408801519450606088015193506080880151925060a0880151915061405560c08901613df4565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a24576000816000526020600020601f850160051c810160208610156141125750805b601f850160051c820191505b818110156120755782815560010161411e565b6001600160401b03831115614148576141486137d4565b61415c836141568354613f04565b836140e9565b6000601f84116001811461419057600085156141785750838201355b600019600387901b1c1916600186901b1783556141ea565b600083815260209020601f19861690835b828110156141c157868501358255602094850194600190920191016141a1565b50868210156141de5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561420357600080fd5b8151613a6081613901565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b0383111561425e57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061428b604083018587614245565b9050826020830152949350505050565b6040815260006142af604083018587614245565b82810360208401526142c18185613a21565b9695505050505050565b600082601f8301126142dc57600080fd5b815160206001600160401b038211156142f7576142f76137d4565b8160051b614306828201613813565b928352848101820192828101908785111561432057600080fd5b83870192505b8483101561434857825161433981613901565b82529183019190830190614326565b979650505050505050565b8051613def81613901565b60006020828403121561437057600080fd5b81516001600160401b038082111561438757600080fd5b90830190610160828603121561439c57600080fd5b6143a46137ea565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151828111156143ec57600080fd5b6143f8878286016142cb565b60c08301525060e0838101519082015261010080840151908201526101209150614423828401614353565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561445557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212203ada2f3e13f6acb3c61148590d88e774a75ff8a53adb5bb0bd110996f279319e64736f6c63430008180033", - "deployedBytecode": "0x6080604052600436106101c45760003560e01c8063675926f6116100f8578063b6ede54011610090578063b6ede540146105c4578063ba66fde7146105e4578063be46760414610604578063caeb50ed1461061a578063d2b8035a1461062f578063da3beb8c1461064f578063e349ad301461050c578063e4c0aaf41461066f578063f2f4eb261461068f57600080fd5b8063675926f61461045f57806369f3f0411461047f5780636d4cd8ea146104cc578063751accd0146104ec578063796490f91461050c5780637c04034e146105225780638e42646014610542578063a7cc08fe14610562578063b34bfaa8146105ae57600080fd5b8063362c34791161016b578063362c34791461032a578063485cc9551461034a5780634b2f0ea01461036a5780634f1ef2861461037d57806352d1902d1461039057806354fd4d50146103a5578063564a565d146103e35780635c92e2f61461041257806365540b961461043257600080fd5b80630855bbe9146101c957806309cc41b8146101fe5780630baa64d1146102205780630c340a24146102405780631200aabc146102785780631c3db16d146102b35780631cc3423a146102f05780632621b9a214610310575b600080fd5b3480156101d557600080fd5b506101e96101e43660046136a3565b6106af565b60405190151581526020015b60405180910390f35b34801561020a57600080fd5b5061021e610219366004613748565b610777565b005b34801561022c57600080fd5b506101e961023b3660046136a3565b61082a565b34801561024c57600080fd5b50600054610260906001600160a01b031681565b6040516001600160a01b0390911681526020016101f5565b34801561028457600080fd5b506102a56102933660046136a3565b60036020526000908152604090205481565b6040519081526020016101f5565b3480156102bf57600080fd5b506102d36102ce3660046136a3565b6108a1565b6040805193845291151560208401521515908201526060016101f5565b3480156102fc57600080fd5b506102a561030b3660046138b2565b610a0f565b34801561031c57600080fd5b506004546101e99060ff1681565b34801561033657600080fd5b506102a5610345366004613916565b610a4c565b34801561035657600080fd5b5061021e610365366004613953565b610ed2565b61021e61037836600461398c565b610f9a565b61021e61038b3660046139ae565b611801565b34801561039c57600080fd5b506102a5611a29565b3480156103b157600080fd5b506103d66040518060400160405280600581526020016418171c971960d91b81525081565b6040516101f59190613a4d565b3480156103ef57600080fd5b506104036103fe3660046136a3565b611a87565b6040516101f593929190613a67565b34801561041e57600080fd5b5061021e61042d366004613a88565b611b4d565b34801561043e57600080fd5b5061045261044d3660046136a3565b611b59565b6040516101f59190613ada565b34801561046b57600080fd5b506102a561047a366004613b1e565b611c1d565b34801561048b57600080fd5b5061049f61049a366004613b59565b611d60565b604080519687529415156020870152938501929092526060840152608083015260a082015260c0016101f5565b3480156104d857600080fd5b506101e96104e73660046136a3565b611e18565b3480156104f857600080fd5b5061021e610507366004613b85565b611f9b565b34801561051857600080fd5b506102a561271081565b34801561052e57600080fd5b5061021e61053d366004613bc7565b612067565b34801561054e57600080fd5b5061021e61055d366004613c4b565b61207d565b34801561056e57600080fd5b5061058261057d366004613b59565b6120c9565b604080516001600160a01b039095168552602085019390935291830152151560608201526080016101f5565b3480156105ba57600080fd5b506102a5614e2081565b3480156105d057600080fd5b5061021e6105df366004613c68565b61218f565b3480156105f057600080fd5b506101e96105ff366004613b59565b612352565b34801561061057600080fd5b506102a561138881565b34801561062657600080fd5b5061021e6123ed565b34801561063b57600080fd5b5061026061064a36600461398c565b61249e565b34801561065b57600080fd5b506102a561066a36600461398c565b6127b8565b34801561067b57600080fd5b5061021e61068a366004613c4b565b61290b565b34801561069b57600080fd5b50600154610260906001600160a01b031681565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190613cc2565b91509150600061072f85611b59565b90508051600014801561076e575061271061138861074d8585613cfc565b6107579190613d0f565b6107619190613d26565b61076b8442613cfc565b10155b95945050505050565b60008781526003602052604090205460028054899290811061079b5761079b613d48565b600091825260209091206002600590920201015460ff16156107d85760405162461bcd60e51b81526004016107cf90613d5e565b60405180910390fd5b6107e488888888612957565b847f053dc5fd28575f5a9be86157f2079ab29d3aec5096f11b17e81b50409b88781c85858560405161081893929190613dbe565b60405180910390a25050505050505050565b60008181526003602052604081205460028054839290811061084e5761084e613d48565b6000918252602082206005909102018054909250829061087090600190613cfc565b8154811061088057610880613d48565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106108cd576108cd613d48565b600091825260208220600590910201805490925082906108ef90600190613cfc565b815481106108ff576108ff613d48565b60009182526020909120600d90910201600381015460ff16945090508361092a57806001015461092d565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a09190613e04565b50909350600492506109b0915050565b8160048111156109c2576109c2613e6b565b03610a055760006109d288611b59565b90508051600103610a0357806000815181106109f0576109f0613d48565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190613e04565b50935050505080610b115760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016107cf565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b889190613e81565b15610bc65760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016107cf565b600086815260036020526040812054600280549091908110610bea57610bea613d48565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610c1e57610c1e613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190613e9c565b5050600087815260078401602052604090205490915060ff16610ce7576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610e2c565b808603610d5c576000868152600683016020526040902054610d0a576000610d55565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610d4b9190613d0f565b610d559190613d26565b9450610e2c565b600081815260078301602052604090205460ff16610e2c5781600601600083600a01600181548110610d9057610d90613d48565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610dc657610dc6613d48565b9060005260206000200154815260200190815260200160002054610dea9190613ed8565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610e1f9190613d0f565b610e299190613d26565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610ec6576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60016000610ede612c5c565b8054909150600160401b900460ff1680610f05575080546001600160401b03808416911610155b15610f225760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610f4d8484612c80565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b600082815260036020526040902054600280548492908110610fbe57610fbe613d48565b600091825260209091206002600590920201015460ff1615610ff25760405162461bcd60e51b81526004016107cf90613d5e565b60008381526003602052604081205460028054909190811061101657611016613d48565b90600052602060002090600502019050806001015483111561107a5760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016107cf565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa1580156110c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110eb9190613cc2565b915091508142101580156110fe57508042105b6111435760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016107cf565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611184573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a89190613e9c565b505090508681036111bd57612710915061123e565b6127106113886111cd8686613cfc565b6111d79190613d0f565b6111e19190613d26565b6111eb8542613cfc565b106112385760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016107cf565b614e2091505b8454600090869061125190600190613cfc565b8154811061126157611261613d48565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e49190613eeb565b6112ee9190613cfc565b60008a815260078401602052604090205490915060ff16156113525760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016107cf565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561139c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c09190613eeb565b905060006127106113d18784613d0f565b6113db9190613d26565b6113e59083613ed8565b60008c8152600686016020526040812054919250908211156114965760008c8152600686016020526040902054349061141e9084613cfc565b116114435760008c815260068601602052604090205461143e9083613cfc565b611445565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161148d929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f8452909152812080548392906114c2908490613ed8565b909155505060008c8152600686016020526040812080548392906114e7908490613ed8565b909155505060008c815260068601602052604090205482116115b95760008c815260068601602052604081205460098701805491929091611529908490613ed8565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a850154600110156117c4578285600901546115d69190613cfc565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa158015611624573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116489190613e81565b156116615760028a01805460ff19166001179055611744565b895460038b016000611674876001613ed8565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016116ef91815260200190565b602060405180830381865afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117309190613eeb565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b815260040161179193929190613f3e565b6000604051808303818588803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b50505050505b803411156117f257336108fc6117da8334613cfc565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b61180a82612cb6565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061188857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661187c6000805160206144768339815191525490565b6001600160a01b031614155b156118a65760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611900575060408051601f3d908101601f191682019092526118fd91810190613eeb565b60015b61192857604051630c76093760e01b81526001600160a01b03831660048201526024016107cf565b600080516020614476833981519152811461195957604051632a87526960e21b8152600481018290526024016107cf565b6000805160206144768339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611a24576000836001600160a01b0316836040516119c09190613fdd565b600060405180830381855af49150503d80600081146119fb576040519150601f19603f3d011682016040523d82523d6000602084013e611a00565b606091505b5050905080611a22576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a745760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061447683398151915290565b60028181548110611a9757600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611aca90613f04565b80601f0160208091040260200160405190810160405280929190818152602001828054611af690613f04565b8015611b435780601f10611b1857610100808354040283529160200191611b43565b820191906000526020600020905b815481529060010190602001808311611b2657829003601f168201915b5050505050905083565b611a2284848484612957565b6000818152600360205260408120546002805460609392908110611b7f57611b7f613d48565b60009182526020822060059091020180549092508290611ba190600190613cfc565b81548110611bb157611bb1613d48565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611c0f57602002820191906000526020600020905b815481526020019060010190808311611bfb575b505050505092505050919050565b600085815260036020526040812054600280548392908110611c4157611c41613d48565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611c7557611c75613d48565b90600052602060002090600d02016000018681548110611c9757611c97613d48565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d199190613e9c565b506003850154919350915060ff168015611d3d57508183600201541480611d3d5750805b15611d505761271094505050505061076e565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611d9157611d91613d48565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611dc557611dc5613d48565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b600081815260036020526040812054600280548392908110611e3c57611e3c613d48565b60009182526020822060059091020180549092508290611e5e90600190613cfc565b81548110611e6e57611e6e613d48565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015611ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eed9190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015611f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f6c9190613ff9565b5050505050915050600081611f82578354611f88565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b03163314611fc55760405162461bcd60e51b81526004016107cf90614063565b6000836001600160a01b03168383604051611fe09190613fdd565b60006040518083038185875af1925050503d806000811461201d576040519150601f19603f3d011682016040523d82523d6000602084013e612022565b606091505b5050905080611a225760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016107cf565b612075868686868686612ce3565b505050505050565b6000546001600160a01b031633146120a75760405162461bcd60e51b81526004016107cf90614063565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008060008060006002600360008a815260200190815260200160002054815481106120f7576120f7613d48565b600091825260208083208a845260036005909302019182019052604082205481549193508391811061212b5761212b613d48565b90600052602060002090600d0201600001878154811061214d5761214d613d48565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b031633146121b95760405162461bcd60e51b81526004016107cf906140a5565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad201612244858783614131565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561229b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122bf9190613eeb565b6122c99190613cfc565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab5810890610818908a908a908a90613dbe565b60008381526003602052604081205460028054839290811061237657612376613d48565b600091825260208083208784526003600590930201918201905260408220548154919350839181106123aa576123aa613d48565b90600052602060002090600d020160000184815481106123cc576123cc613d48565b600091825260209091206004909102016003015460ff169695505050505050565b600460006123f9612c5c565b8054909150600160401b900460ff1680612420575080546001600160401b03808416911610155b1561243d5760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b6001546000906001600160a01b031633146124cb5760405162461bcd60e51b81526004016107cf906140a5565b6000838152600360205260409020546002805485929081106124ef576124ef613d48565b600091825260209091206002600590920201015460ff16156125235760405162461bcd60e51b81526004016107cf90613d5e565b60008481526003602052604081205460028054909190811061254757612547613d48565b6000918252602082206005909102018054909250829061256990600190613cfc565b8154811061257957612579613d48565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260291906141f1565b60015460405163564a565d60e01b8152600481018a90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126759190613e04565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018d9052604482018c90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156126d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126fd91906141f1565b965061270a848a896133a6565b156127a757604080516080810182526001600160a01b03808a1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff19958616179055918152600c89019091529290922080549092161790556127ac565b600096505b50505050505092915050565b6000828152600360205260408120546002805483929081106127dc576127dc613d48565b6000918252602080832086845260036005909302019182019052604082205481549193508391811061281057612810613d48565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa15801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190613e9c565b50915091508260040154600014806128c25750801580156128c257506000828152600284016020526040902054155b156128d4576000945050505050612905565b80156128e95750506004015491506129059050565b5060009081526002909101602052604090205491506129059050565b92915050565b6000546001600160a01b031633146129355760405162461bcd60e51b81526004016107cf90614063565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008481526003602052604090205460028054869290811061297b5761297b613d48565b600091825260209091206002600590920201015460ff16156129af5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa1580156129f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1d9190613e04565b5090935060019250612a2d915050565b816004811115612a3f57612a3f613e6b565b14612a9c5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016107cf565b82612ad95760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016107cf565b600086815260036020526040812054600280549091908110612afd57612afd613d48565b60009182526020822060059091020180549092508290612b1f90600190613cfc565b81548110612b2f57612b2f613d48565b90600052602060002090600d0201905060005b86811015612bf5573382898984818110612b5e57612b5e613d48565b9050602002013581548110612b7557612b75613d48565b60009182526020909120600490910201546001600160a01b031614612bac5760405162461bcd60e51b81526004016107cf9061420e565b8582898984818110612bc057612bc0613d48565b9050602002013581548110612bd757612bd7613d48565b60009182526020909120600160049092020181019190915501612b42565b5086869050816005016000828254612c0d9190613ed8565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612c4a908b908b908b90614277565b60405180910390a35050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b612c88613662565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b03163314612ce05760405162461bcd60e51b81526004016107cf90614063565b50565b600086815260036020526040902054600280548892908110612d0757612d07613d48565b600091825260209091206002600590920201015460ff1615612d3b5760405162461bcd60e51b81526004016107cf90613d5e565b60015460405163564a565d60e01b8152600481018990526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612d85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da99190613e04565b5090935060029250612db9915050565b816004811115612dcb57612dcb613e6b565b14612e265760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016107cf565b85612e685760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016107cf565b600088815260036020526040812054600280549091908110612e8c57612e8c613d48565b906000526020600020906005020190508060010154861115612ee75760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016107cf565b80546000908290612efa90600190613cfc565b81548110612f0a57612f0a613d48565b60009182526020822060015460405163564a565d60e01b8152600481018f9052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f899190613e04565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130089190613ff9565b5050505050915050600061301d8a8a8a610a0f565b905060005b8b81101561326b5733858e8e8481811061303e5761303e613d48565b905060200201358154811061305557613055613d48565b60009182526020909120600490910201546001600160a01b03161461308c5760405162461bcd60e51b81526004016107cf9061420e565b8215806130d3575081858e8e848181106130a8576130a8613d48565b90506020020135815481106130bf576130bf613d48565b906000526020600020906004020160010154145b6131535760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016107cf565b848d8d8381811061316657613166613d48565b905060200201358154811061317d5761317d613d48565b600091825260209091206003600490920201015460ff16156131d65760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016107cf565b8a858e8e848181106131ea576131ea613d48565b905060200201358154811061320157613201613d48565b60009182526020909120600260049092020101556001858e8e8481811061322a5761322a613d48565b905060200201358154811061324157613241613d48565b60009182526020909120600490910201600301805460ff1916911515919091179055600101613022565b508b8b90508460040160008282546132839190613ed8565b909155505060008a8152600285016020526040812080548d92906132a8908490613ed8565b909155505060018401548a036132d757600384015460ff16156132d25760038401805460ff191690555b613350565b60018401546000908152600285016020526040808220548c83529120540361331957600384015460ff166132d25760038401805460ff19166001179055613350565b60018401546000908152600285016020526040808220548c8352912054111561335057600184018a905560038401805460ff191690555b89336001600160a01b03168e7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48f8f8d60405161338f9392919061429b565b60405180910390a450505050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156133f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134189190613e04565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b039091169350638a9bb02a9250889190849063fc6f8f1690602401602060405180830381865afa158015613477573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061349b9190613eeb565b6134a59190613cfc565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381865afa1580156134e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261350e919081019061435e565b602001519050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561356a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358e91906141f1565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156135e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613609919061443f565b505091509150828161361b9190613ed8565b60045490831015955060ff16156136575784801561365457506001600160a01b0386166000908152600c8901602052604090205460ff16155b94505b505050509392505050565b61366a613689565b61368757604051631afcd79f60e31b815260040160405180910390fd5b565b6000613693612c5c565b54600160401b900460ff16919050565b6000602082840312156136b557600080fd5b5035919050565b60008083601f8401126136ce57600080fd5b5081356001600160401b038111156136e557600080fd5b6020830191508360208260051b850101111561370057600080fd5b9250929050565b60008083601f84011261371957600080fd5b5081356001600160401b0381111561373057600080fd5b60208301915083602082850101111561370057600080fd5b600080600080600080600060a0888a03121561376357600080fd5b8735965060208801356001600160401b038082111561378157600080fd5b61378d8b838c016136bc565b909850965060408a0135955060608a0135945060808a01359150808211156137b457600080fd5b506137c18a828b01613707565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b038111828210171561380d5761380d6137d4565b60405290565b604051601f8201601f191681016001600160401b038111828210171561383b5761383b6137d4565b604052919050565b600082601f83011261385457600080fd5b81356001600160401b0381111561386d5761386d6137d4565b613880601f8201601f1916602001613813565b81815284602083860101111561389557600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156138c757600080fd5b833592506020840135915060408401356001600160401b038111156138eb57600080fd5b6138f786828701613843565b9150509250925092565b6001600160a01b0381168114612ce057600080fd5b6000806000806080858703121561392c57600080fd5b84359350602085013561393e81613901565b93969395505050506040820135916060013590565b6000806040838503121561396657600080fd5b823561397181613901565b9150602083013561398181613901565b809150509250929050565b6000806040838503121561399f57600080fd5b50508035926020909101359150565b600080604083850312156139c157600080fd5b82356139cc81613901565b915060208301356001600160401b038111156139e757600080fd5b6139f385828601613843565b9150509250929050565b60005b83811015613a18578181015183820152602001613a00565b50506000910152565b60008151808452613a398160208601602086016139fd565b601f01601f19169290920160200192915050565b602081526000613a606020830184613a21565b9392505050565b838152821515602082015260606040820152600061076e6060830184613a21565b60008060008060608587031215613a9e57600080fd5b8435935060208501356001600160401b03811115613abb57600080fd5b613ac7878288016136bc565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613b1257835183529284019291840191600101613af6565b50909695505050505050565b600080600080600060a08688031215613b3657600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613b6e57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613b9a57600080fd5b8335613ba581613901565b92506020840135915060408401356001600160401b038111156138eb57600080fd5b60008060008060008060a08789031215613be057600080fd5b8635955060208701356001600160401b0380821115613bfe57600080fd5b613c0a8a838b016136bc565b909750955060408901359450606089013593506080890135915080821115613c3157600080fd5b50613c3e89828a01613843565b9150509295509295509295565b600060208284031215613c5d57600080fd5b8135613a6081613901565b600080600080600060808688031215613c8057600080fd5b853594506020860135935060408601356001600160401b03811115613ca457600080fd5b613cb088828901613707565b96999598509660600135949350505050565b60008060408385031215613cd557600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b8181038181111561290557612905613ce6565b808202811582820484141761290557612905613ce6565b600082613d4357634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b83815260406020820152600061076e604083018486613d95565b80516001600160601b0381168114613def57600080fd5b919050565b80518015158114613def57600080fd5b600080600080600060a08688031215613e1c57600080fd5b613e2586613dd8565b94506020860151613e3581613901565b604087015190945060058110613e4a57600080fd5b9250613e5860608701613df4565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b600060208284031215613e9357600080fd5b613a6082613df4565b600080600060608486031215613eb157600080fd5b83519250613ec160208501613df4565b9150613ecf60408501613df4565b90509250925092565b8082018082111561290557612905613ce6565b600060208284031215613efd57600080fd5b5051919050565b600181811c90821680613f1857607f821691505b602082108103613f3857634e487b7160e01b600052602260045260246000fd5b50919050565b838152600060208460208401526060604084015260008454613f5f81613f04565b8060608701526080600180841660008114613f815760018114613f9d57613fcd565b60ff19851660808a0152608084151560051b8a01019550613fcd565b89600052602060002060005b85811015613fc45781548b8201860152908301908801613fa9565b8a016080019650505b50939a9950505050505050505050565b60008251613fef8184602087016139fd565b9190910192915050565b600080600080600080600060e0888a03121561401457600080fd5b61401d88613dd8565b965061402b60208901613df4565b955060408801519450606088015193506080880151925060a0880151915061405560c08901613df4565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611a24576000816000526020600020601f850160051c810160208610156141125750805b601f850160051c820191505b818110156120755782815560010161411e565b6001600160401b03831115614148576141486137d4565b61415c836141568354613f04565b836140e9565b6000601f84116001811461419057600085156141785750838201355b600019600387901b1c1916600186901b1783556141ea565b600083815260209020601f19861690835b828110156141c157868501358255602094850194600190920191016141a1565b50868210156141de5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561420357600080fd5b8151613a6081613901565b6020808252601f908201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e00604082015260600190565b81835260006001600160fb1b0383111561425e57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061428b604083018587614245565b9050826020830152949350505050565b6040815260006142af604083018587614245565b82810360208401526142c18185613a21565b9695505050505050565b600082601f8301126142dc57600080fd5b815160206001600160401b038211156142f7576142f76137d4565b8160051b614306828201613813565b928352848101820192828101908785111561432057600080fd5b83870192505b8483101561434857825161433981613901565b82529183019190830190614326565b979650505050505050565b8051613def81613901565b60006020828403121561437057600080fd5b81516001600160401b038082111561438757600080fd5b90830190610160828603121561439c57600080fd5b6143a46137ea565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151828111156143ec57600080fd5b6143f8878286016142cb565b60c08301525060e0838101519082015261010080840151908201526101209150614423828401614353565b9181019190915261014091820151918101919091529392505050565b6000806000806080858703121561445557600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca26469706673582212203ada2f3e13f6acb3c61148590d88e774a75ff8a53adb5bb0bd110996f279319e64736f6c63430008180033", + "numDeployments": 4, + "solcInputHash": "450e0980ffbfcac7e1c189d256d31822", + "metadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedDelegateCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"InvalidImplementation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitializing\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UUPSUnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"slot\",\"type\":\"bytes32\"}],\"name\":\"UUPSUnsupportedProxiableUUID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"ChoiceFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"CommitCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"CommitCastShutter\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Contribution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"DisputeCreation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"version\",\"type\":\"uint64\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_juror\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"VoteCast\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_contributor\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"LOSER_APPEAL_PERIOD_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LOSER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ONE_BASIS_POINT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WINNER_STAKE_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"localDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"localRoundID\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"name\":\"alreadyDrawn\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areCommitsAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"areVotesAllCast\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"}],\"name\":\"castCommit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes32\",\"name\":\"_commit\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_identity\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_encryptedVote\",\"type\":\"bytes\"}],\"name\":\"castCommitShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_voteIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"castVoteShutter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"changeCore\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_governor\",\"type\":\"address\"}],\"name\":\"changeGovernor\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"core\",\"outputs\":[{\"internalType\":\"contract KlerosCore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"coreDisputeIDToLocal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_extraData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_nbVotes\",\"type\":\"uint256\"}],\"name\":\"createDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"currentRuling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ruling\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"overridden\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"disputes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"numberOfChoices\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"jumped\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"}],\"name\":\"draw\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"drawnAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_destination\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"executeGovernorProposal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"fundAppeal\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getCoherentCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getDegreeOfCoherence\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"getFundedChoices\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"fundedChoices\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"}],\"name\":\"getLocalDisputeRoundID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"localDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"localRoundID\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_localDisputeID\",\"type\":\"uint256\"}],\"name\":\"getNumberOfRounds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"getRoundInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"winningChoice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"tied\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"totalVoted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalCommited\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nbVoters\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"choiceCount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"getVoteInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"commit\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"choice\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"voted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"governor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_justification\",\"type\":\"string\"}],\"name\":\"hashVote\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_governor\",\"type\":\"address\"},{\"internalType\":\"contract KlerosCore\",\"name\":\"_core\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize8\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"}],\"name\":\"isAppealFunded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_voteID\",\"type\":\"uint256\"}],\"name\":\"isVoteActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"singleDrawPerJuror\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_coreDisputeID\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"_beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_coreRoundID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_choice\",\"type\":\"uint256\"}],\"name\":\"withdrawFeesAndRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"AlreadyInitialized()\":[{\"details\":\"The contract is already initialized.\"}],\"InvalidImplementation(address)\":[{\"details\":\"The `implementation` is not UUPS-compliant\"}],\"NotInitializing()\":[{\"details\":\"The contract is not initializing.\"}],\"UUPSUnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized context.\"}],\"UUPSUnsupportedProxiableUUID(bytes32)\":[{\"details\":\"The storage `slot` is unsupported as a UUID.\"}]},\"events\":{\"ChoiceFunded(uint256,uint256,uint256)\":{\"details\":\"To be emitted when a choice is fully funded for an appeal.\",\"params\":{\"_choice\":\"The choice that is being funded.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"CommitCast(uint256,address,uint256[],bytes32)\":{\"details\":\"To be emitted when a vote commitment is cast.\",\"params\":{\"_commit\":\"The commitment of the juror.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"The address of the juror casting the vote commitment.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"CommitCastShutter(uint256,address,bytes32,bytes32,bytes)\":{\"details\":\"Emitted when a vote is cast.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_juror\":\"The address of the juror casting the vote commitment.\"}},\"Contribution(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when a funding contribution is made.\",\"params\":{\"_amount\":\"The amount contributed.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}},\"DisputeCreation(uint256,uint256,bytes)\":{\"details\":\"To be emitted when a dispute is created.\",\"params\":{\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_extraData\":\"The extra data for the dispute.\",\"_numberOfChoices\":\"The number of choices available in the dispute.\"}},\"Initialized(uint64)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Upgraded(address)\":{\"details\":\"Emitted when the `implementation` has been successfully upgraded.\",\"params\":{\"newImplementation\":\"Address of the new implementation the proxy is now forwarding calls to.\"}},\"VoteCast(uint256,address,uint256[],uint256,string)\":{\"details\":\"Emitted when casting a vote to provide the justification of juror's choice.\",\"params\":{\"_choice\":\"The choice juror voted for.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_juror\":\"Address of the juror.\",\"_justification\":\"Justification of the choice.\",\"_voteIDs\":\"The identifiers of the votes in the dispute.\"}},\"Withdrawal(uint256,uint256,uint256,address,uint256)\":{\"details\":\"To be emitted when the contributed funds are withdrawn.\",\"params\":{\"_amount\":\"The amount withdrawn.\",\"_choice\":\"The choice that is being funded.\",\"_contributor\":\"The address of the contributor.\",\"_coreDisputeID\":\"The identifier of the dispute in the Arbitrator contract.\",\"_coreRoundID\":\"The identifier of the round in the Arbitrator contract.\"}}},\"kind\":\"dev\",\"methods\":{\"areCommitsAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their commits for the last round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their commits for the last round.\"}},\"areVotesAllCast(uint256)\":{\"details\":\"Returns true if all of the jurors have cast their votes for the last round. Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"_0\":\"Whether all of the jurors have cast their votes for the last round.\"}},\"castCommit(uint256,uint256[],bytes32)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castCommitShutter(uint256,uint256[],bytes32,bytes32,bytes)\":{\"details\":\"Sets the caller's commit for the specified votes. It can be called multiple times during the commit period, each call overrides the commits of the previous one. `O(n)` where `n` is the number of votes.\",\"params\":{\"_commit\":\"The commitment hash including the justification.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_encryptedVote\":\"The Shutter encrypted vote.\",\"_identity\":\"The Shutter identity used for encryption.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"castVote(uint256,uint256[],uint256,uint256,string)\":{\"details\":\"Sets the caller's choices for the specified votes. `O(n)` where `n` is the number of votes.\",\"params\":{\"_choice\":\"The choice.\",\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_justification\":\"Justification of the choice.\",\"_salt\":\"The salt for the commit if the votes were hidden.\",\"_voteIDs\":\"The IDs of the votes.\"}},\"changeCore(address)\":{\"details\":\"Changes the `core` storage variable.\",\"params\":{\"_core\":\"The new value for the `core` storage variable.\"}},\"changeGovernor(address)\":{\"details\":\"Changes the `governor` storage variable.\",\"params\":{\"_governor\":\"The new value for the `governor` storage variable.\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createDispute(uint256,uint256,bytes,uint256)\":{\"details\":\"Creates a local dispute and maps it to the dispute ID in the Core contract. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_extraData\":\"Additional info about the dispute, for possible use in future dispute kits.\",\"_nbVotes\":\"Number of votes for this dispute.\",\"_numberOfChoices\":\"Number of choices of the dispute\"}},\"currentRuling(uint256)\":{\"details\":\"Gets the current ruling of a specified dispute.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\"},\"returns\":{\"overridden\":\"Whether the ruling was overridden by appeal funding or not.\",\"ruling\":\"The current ruling.\",\"tied\":\"Whether it's a tie or not.\"}},\"draw(uint256,uint256)\":{\"details\":\"Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core. Note: Access restricted to Kleros Core only.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core.\",\"_nonce\":\"Nonce of the drawing iteration.\"},\"returns\":{\"drawnAddress\":\"The drawn address.\"}},\"executeGovernorProposal(address,uint256,bytes)\":{\"details\":\"Allows the governor to call anything on behalf of the contract.\",\"params\":{\"_amount\":\"The value sent with the call.\",\"_data\":\"The data sent with the call.\",\"_destination\":\"The destination of the call.\"}},\"fundAppeal(uint256,uint256)\":{\"details\":\"Manages contributions, and appeals a dispute if at least two choices are fully funded. Note that the surplus deposit will be reimbursed.\",\"params\":{\"_choice\":\"A choice that receives funding.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core.\"}},\"getCoherentCount(uint256,uint256)\":{\"details\":\"Gets the number of jurors who are eligible to a reward in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"The number of coherent jurors.\"}},\"getDegreeOfCoherence(uint256,uint256,uint256,uint256,uint256)\":{\"details\":\"Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the vote.\"},\"returns\":{\"_0\":\"The degree of coherence in basis points.\"}},\"hashVote(uint256,uint256,string)\":{\"details\":\"Computes the hash of a vote using ABI encoding\",\"params\":{\"_choice\":\"The choice being voted for\",\"_justification\":\"The justification for the vote\",\"_salt\":\"A random salt for commitment\"},\"returns\":{\"_0\":\"bytes32 The hash of the encoded vote parameters\"}},\"initialize(address,address)\":{\"details\":\"Initializer.\",\"params\":{\"_core\":\"The KlerosCore arbitrator.\",\"_governor\":\"The governor's address.\"}},\"isAppealFunded(uint256)\":{\"details\":\"Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund). Note that this function is to be called directly by the core contract and is not for off-chain usage.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\"},\"returns\":{\"_0\":\"Whether the appeal funding is finished.\"}},\"isVoteActive(uint256,uint256,uint256)\":{\"details\":\"Returns true if the specified voter was active in this round.\",\"params\":{\"_coreDisputeID\":\"The ID of the dispute in Kleros Core, not in the Dispute Kit.\",\"_coreRoundID\":\"The ID of the round in Kleros Core, not in the Dispute Kit.\",\"_voteID\":\"The ID of the voter.\"},\"returns\":{\"_0\":\"Whether the voter was active or not.\"}},\"proxiableUUID()\":{\"details\":\"Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the implementation. It is used to validate the implementation's compatibility when performing an upgrade. IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this function revert if invoked through a proxy. This is guaranteed by the if statement.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade mechanism including access control and UUPS-compliance.Reverts if the execution is not performed via delegatecall or the execution context is not of a proxy with an ERC1967-compliant implementation pointing to self.\",\"params\":{\"data\":\"Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\",\"newImplementation\":\"Address of the new implementation contract.\"}},\"withdrawFeesAndRewards(uint256,address,uint256,uint256)\":{\"details\":\"Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved. Note that withdrawals are not possible if the core contract is paused.\",\"params\":{\"_beneficiary\":\"The address whose rewards to withdraw.\",\"_choice\":\"The ruling option that the caller wants to withdraw from.\",\"_coreDisputeID\":\"Index of the dispute in Kleros Core contract.\",\"_coreRoundID\":\"The round in the Kleros Core contract the caller wants to withdraw from.\"},\"returns\":{\"amount\":\"The withdrawn amount.\"}}},\"stateVariables\":{\"version\":{\"details\":\"Returns the version of the implementation.\",\"return\":\"Version string.\",\"returns\":{\"_0\":\"Version string.\"}}},\"title\":\"DisputeKitShutter Dispute kit implementation of the Kleros v1 features including: - a drawing system: proportional to staked PNK, - a vote aggregation system: plurality, - an incentive system: equal split between coherent votes, - an appeal system: fund 2 choices only, vote on any choice. Added functionality: an Shutter-specific event emitted when a vote is cast.\",\"version\":1},\"userdoc\":{\"errors\":{\"FailedDelegateCall()\":[{\"notice\":\"Failed Delegated call\"}]},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":\"DisputeKitShutter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":100},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC-20 standard as defined in the ERC.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\\n * caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\"},\"src/arbitration/KlerosCore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCoreBase, IDisputeKit, ISortitionModule, IERC20} from \\\"./KlerosCoreBase.sol\\\";\\n\\n/// @title KlerosCore\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\ncontract KlerosCore is KlerosCoreBase {\\n string public constant override version = \\\"0.9.3\\\";\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer (constructor equivalent for upgradable contracts).\\n /// @param _governor The governor's address.\\n /// @param _guardian The guardian's address.\\n /// @param _pinakion The address of the token contract.\\n /// @param _jurorProsecutionModule The address of the juror prosecution module.\\n /// @param _disputeKit The address of the default dispute kit.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the general court.\\n /// @param _courtParameters Numeric parameters of General court (minStake, alpha, feeForJuror and jurorsForCourtJump respectively).\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court.\\n /// @param _sortitionExtraData The extra data for sortition module.\\n /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors.\\n function initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) external reinitializer(1) {\\n __KlerosCoreBase_initialize(\\n _governor,\\n _guardian,\\n _pinakion,\\n _jurorProsecutionModule,\\n _disputeKit,\\n _hiddenVotes,\\n _courtParameters,\\n _timesPerPeriod,\\n _sortitionExtraData,\\n _sortitionModuleAddress\\n );\\n }\\n\\n function initialize4() external reinitializer(4) {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n}\\n\",\"keccak256\":\"0x4b14cc3e4b51b3c86f7e42d8b48ecb8bec4e8709b347610720c00a305428f3fc\",\"license\":\"MIT\"},\"src/arbitration/KlerosCoreBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {IArbitrableV2, IArbitratorV2} from \\\"./interfaces/IArbitratorV2.sol\\\";\\nimport {IDisputeKit} from \\\"./interfaces/IDisputeKit.sol\\\";\\nimport {ISortitionModule} from \\\"./interfaces/ISortitionModule.sol\\\";\\nimport {Initializable} from \\\"../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../proxy/UUPSProxiable.sol\\\";\\nimport {SafeERC20, IERC20} from \\\"../libraries/SafeERC20.sol\\\";\\nimport \\\"../libraries/Constants.sol\\\";\\n\\n/// @title KlerosCoreBase\\n/// Core arbitrator contract for Kleros v2.\\n/// Note that this contract trusts the PNK token, the dispute kit and the sortition module contracts.\\nabstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable {\\n using SafeERC20 for IERC20;\\n\\n // ************************************* //\\n // * Enums / Structs * //\\n // ************************************* //\\n\\n enum Period {\\n evidence, // Evidence can be submitted. This is also when drawing has to take place.\\n commit, // Jurors commit a hashed vote. This is skipped for courts without hidden votes.\\n vote, // Jurors reveal/cast their vote depending on whether the court has hidden votes or not.\\n appeal, // The dispute can be appealed.\\n execution // Tokens are redistributed and the ruling is executed.\\n }\\n\\n struct Court {\\n uint96 parent; // The parent court.\\n bool hiddenVotes; // Whether to use commit and reveal or not.\\n uint256[] children; // List of child courts.\\n uint256 minStake; // Minimum PNKs needed to stake in the court.\\n uint256 alpha; // Basis point of PNKs that are lost when incoherent.\\n uint256 feeForJuror; // Arbitration fee paid per juror.\\n uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.\\n uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.\\n mapping(uint256 disputeKitId => bool) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.\\n bool disabled; // True if the court is disabled. Unused for now, will be implemented later.\\n }\\n\\n struct Dispute {\\n uint96 courtID; // The ID of the court the dispute is in.\\n IArbitrableV2 arbitrated; // The arbitrable contract.\\n Period period; // The current period of the dispute.\\n bool ruled; // True if the ruling has been executed, false otherwise.\\n uint256 lastPeriodChange; // The last time the period was changed.\\n Round[] rounds;\\n }\\n\\n struct Round {\\n uint256 disputeKitID; // Index of the dispute kit in the array.\\n uint256 pnkAtStakePerJuror; // The amount of PNKs at stake for each juror in this round.\\n uint256 totalFeesForJurors; // The total juror fees paid in this round.\\n uint256 nbVotes; // The total number of votes the dispute can possibly have in the current round. Former votes[_round].length.\\n uint256 repartitions; // A counter of reward repartitions made in this round.\\n uint256 pnkPenalties; // The amount of PNKs collected from penalties in this round.\\n address[] drawnJurors; // Addresses of the jurors that were drawn in this round.\\n uint256 sumFeeRewardPaid; // Total sum of arbitration fees paid to coherent jurors as a reward in this round.\\n uint256 sumPnkRewardPaid; // Total sum of PNK paid to coherent jurors as a reward in this round.\\n IERC20 feeToken; // The token used for paying fees in this round.\\n uint256 drawIterations; // The number of iterations passed drawing the jurors for this round.\\n }\\n\\n // Workaround \\\"stack too deep\\\" errors\\n struct ExecuteParams {\\n uint256 disputeID; // The ID of the dispute to execute.\\n uint256 round; // The round to execute.\\n uint256 coherentCount; // The number of coherent votes in the round.\\n uint256 numberOfVotesInRound; // The number of votes in the round.\\n uint256 feePerJurorInRound; // The fee per juror in the round.\\n uint256 pnkAtStakePerJurorInRound; // The amount of PNKs at stake for each juror in the round.\\n uint256 pnkPenaltiesInRound; // The amount of PNKs collected from penalties in the round.\\n uint256 repartition; // The index of the repartition to execute.\\n }\\n\\n struct CurrencyRate {\\n bool feePaymentAccepted;\\n uint64 rateInEth;\\n uint8 rateDecimals;\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.\\n uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.\\n\\n address public governor; // The governor of the contract.\\n address public guardian; // The guardian able to pause asset withdrawals.\\n IERC20 public pinakion; // The Pinakion token contract.\\n address public jurorProsecutionModule; // The module for juror's prosecution.\\n ISortitionModule public sortitionModule; // Sortition module for drawing.\\n Court[] public courts; // The courts.\\n IDisputeKit[] public disputeKits; // Array of dispute kits.\\n Dispute[] public disputes; // The disputes.\\n mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.\\n bool public paused; // Whether asset withdrawals are paused.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n event NewPeriod(uint256 indexed _disputeID, Period _period);\\n event AppealPossible(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event AppealDecision(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n event Draw(address indexed _address, uint256 indexed _disputeID, uint256 _roundID, uint256 _voteID);\\n event CourtCreated(\\n uint96 indexed _courtID,\\n uint96 indexed _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod,\\n uint256[] _supportedDisputeKits\\n );\\n event CourtModified(\\n uint96 indexed _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] _timesPerPeriod\\n );\\n event DisputeKitCreated(uint256 indexed _disputeKitID, IDisputeKit indexed _disputeKitAddress);\\n event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);\\n event CourtJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint96 indexed _fromCourtID,\\n uint96 _toCourtID\\n );\\n event DisputeKitJump(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 indexed _fromDisputeKitID,\\n uint256 _toDisputeKitID\\n );\\n event TokenAndETHShift(\\n address indexed _account,\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _degreeOfCoherency,\\n int256 _pnkAmount,\\n int256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event LeftoverRewardSent(\\n uint256 indexed _disputeID,\\n uint256 indexed _roundID,\\n uint256 _pnkAmount,\\n uint256 _feeAmount,\\n IERC20 _feeToken\\n );\\n event Paused();\\n event Unpaused();\\n\\n // ************************************* //\\n // * Function Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n if (governor != msg.sender) revert GovernorOnly();\\n _;\\n }\\n\\n modifier onlyByGuardianOrGovernor() {\\n if (guardian != msg.sender && governor != msg.sender) revert GuardianOrGovernorOnly();\\n _;\\n }\\n\\n modifier whenPaused() {\\n if (!paused) revert WhenPausedOnly();\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n if (paused) revert WhenNotPausedOnly();\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n function __KlerosCoreBase_initialize(\\n address _governor,\\n address _guardian,\\n IERC20 _pinakion,\\n address _jurorProsecutionModule,\\n IDisputeKit _disputeKit,\\n bool _hiddenVotes,\\n uint256[4] memory _courtParameters,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n ISortitionModule _sortitionModuleAddress\\n ) internal onlyInitializing {\\n governor = _governor;\\n guardian = _guardian;\\n pinakion = _pinakion;\\n jurorProsecutionModule = _jurorProsecutionModule;\\n sortitionModule = _sortitionModuleAddress;\\n\\n // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported.\\n disputeKits.push();\\n\\n // DISPUTE_KIT_CLASSIC\\n disputeKits.push(_disputeKit);\\n\\n emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit);\\n\\n // FORKING_COURT\\n // TODO: Fill the properties for the Forking court, emit CourtCreated.\\n courts.push();\\n sortitionModule.createTree(bytes32(uint256(FORKING_COURT)), _sortitionExtraData);\\n\\n // GENERAL_COURT\\n Court storage court = courts.push();\\n court.parent = FORKING_COURT;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _courtParameters[0];\\n court.alpha = _courtParameters[1];\\n court.feeForJuror = _courtParameters[2];\\n court.jurorsForCourtJump = _courtParameters[3];\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(uint256(GENERAL_COURT)), _sortitionExtraData);\\n\\n uint256[] memory supportedDisputeKits = new uint256[](1);\\n supportedDisputeKits[0] = DISPUTE_KIT_CLASSIC;\\n emit CourtCreated(\\n GENERAL_COURT,\\n court.parent,\\n _hiddenVotes,\\n _courtParameters[0],\\n _courtParameters[1],\\n _courtParameters[2],\\n _courtParameters[3],\\n _timesPerPeriod,\\n supportedDisputeKits\\n );\\n _enableDisputeKit(GENERAL_COURT, DISPUTE_KIT_CLASSIC, true);\\n }\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Pause staking and reward execution. Can only be done by guardian or governor.\\n function pause() external onlyByGuardianOrGovernor whenNotPaused {\\n paused = true;\\n emit Paused();\\n }\\n\\n /// @dev Unpause staking and reward execution. Can only be done by governor.\\n function unpause() external onlyByGovernor whenPaused {\\n paused = false;\\n emit Unpaused();\\n }\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n if (!success) revert UnsuccessfulCall();\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `guardian` storage variable.\\n /// @param _guardian The new value for the `guardian` storage variable.\\n function changeGuardian(address _guardian) external onlyByGovernor {\\n guardian = _guardian;\\n }\\n\\n /// @dev Changes the `pinakion` storage variable.\\n /// @param _pinakion The new value for the `pinakion` storage variable.\\n function changePinakion(IERC20 _pinakion) external onlyByGovernor {\\n pinakion = _pinakion;\\n }\\n\\n /// @dev Changes the `jurorProsecutionModule` storage variable.\\n /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable.\\n function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor {\\n jurorProsecutionModule = _jurorProsecutionModule;\\n }\\n\\n /// @dev Changes the `_sortitionModule` storage variable.\\n /// Note that the new module should be initialized for all courts.\\n /// @param _sortitionModule The new value for the `sortitionModule` storage variable.\\n function changeSortitionModule(ISortitionModule _sortitionModule) external onlyByGovernor {\\n sortitionModule = _sortitionModule;\\n }\\n\\n /// @dev Add a new supported dispute kit module to the court.\\n /// @param _disputeKitAddress The address of the dispute kit contract.\\n function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {\\n uint256 disputeKitID = disputeKits.length;\\n disputeKits.push(_disputeKitAddress);\\n emit DisputeKitCreated(disputeKitID, _disputeKitAddress);\\n }\\n\\n /// @dev Creates a court under a specified parent court.\\n /// @param _parent The `parent` property value of the court.\\n /// @param _hiddenVotes The `hiddenVotes` property value of the court.\\n /// @param _minStake The `minStake` property value of the court.\\n /// @param _alpha The `alpha` property value of the court.\\n /// @param _feeForJuror The `feeForJuror` property value of the court.\\n /// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.\\n /// @param _timesPerPeriod The `timesPerPeriod` property value of the court.\\n /// @param _sortitionExtraData Extra data for sortition module.\\n /// @param _supportedDisputeKits Indexes of dispute kits that this court will support.\\n function createCourt(\\n uint96 _parent,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod,\\n bytes memory _sortitionExtraData,\\n uint256[] memory _supportedDisputeKits\\n ) external onlyByGovernor {\\n if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();\\n if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();\\n if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();\\n\\n uint256 courtID = courts.length;\\n Court storage court = courts.push();\\n\\n for (uint256 i = 0; i < _supportedDisputeKits.length; i++) {\\n if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(uint96(courtID), _supportedDisputeKits[i], true);\\n }\\n // Check that Classic DK support was added.\\n if (!court.supportedDisputeKits[DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();\\n\\n court.parent = _parent;\\n court.children = new uint256[](0);\\n court.hiddenVotes = _hiddenVotes;\\n court.minStake = _minStake;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n\\n sortitionModule.createTree(bytes32(courtID), _sortitionExtraData);\\n\\n // Update the parent.\\n courts[_parent].children.push(courtID);\\n emit CourtCreated(\\n uint96(courtID),\\n _parent,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod,\\n _supportedDisputeKits\\n );\\n }\\n\\n function changeCourtParameters(\\n uint96 _courtID,\\n bool _hiddenVotes,\\n uint256 _minStake,\\n uint256 _alpha,\\n uint256 _feeForJuror,\\n uint256 _jurorsForCourtJump,\\n uint256[4] memory _timesPerPeriod\\n ) external onlyByGovernor {\\n Court storage court = courts[_courtID];\\n if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n for (uint256 i = 0; i < court.children.length; i++) {\\n if (courts[court.children[i]].minStake < _minStake) {\\n revert MinStakeLowerThanParentCourt();\\n }\\n }\\n court.minStake = _minStake;\\n court.hiddenVotes = _hiddenVotes;\\n court.alpha = _alpha;\\n court.feeForJuror = _feeForJuror;\\n court.jurorsForCourtJump = _jurorsForCourtJump;\\n court.timesPerPeriod = _timesPerPeriod;\\n emit CourtModified(\\n _courtID,\\n _hiddenVotes,\\n _minStake,\\n _alpha,\\n _feeForJuror,\\n _jurorsForCourtJump,\\n _timesPerPeriod\\n );\\n }\\n\\n /// @dev Adds/removes court's support for specified dispute kits.\\n /// @param _courtID The ID of the court.\\n /// @param _disputeKitIDs The IDs of dispute kits which support should be added/removed.\\n /// @param _enable Whether add or remove the dispute kits from the court.\\n function enableDisputeKits(uint96 _courtID, uint256[] memory _disputeKitIDs, bool _enable) external onlyByGovernor {\\n for (uint256 i = 0; i < _disputeKitIDs.length; i++) {\\n if (_enable) {\\n if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits.length) {\\n revert WrongDisputeKitIndex();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], true);\\n } else {\\n // Classic dispute kit must be supported by all courts.\\n if (_disputeKitIDs[i] == DISPUTE_KIT_CLASSIC) {\\n revert CannotDisableClassicDK();\\n }\\n _enableDisputeKit(_courtID, _disputeKitIDs[i], false);\\n }\\n }\\n }\\n\\n /// @dev Changes the supported fee tokens.\\n /// @param _feeToken The fee token.\\n /// @param _accepted Whether the token is supported or not as a method of fee payment.\\n function changeAcceptedFeeTokens(IERC20 _feeToken, bool _accepted) external onlyByGovernor {\\n currencyRates[_feeToken].feePaymentAccepted = _accepted;\\n emit AcceptedFeeToken(_feeToken, _accepted);\\n }\\n\\n /// @dev Changes the currency rate of a fee token.\\n /// @param _feeToken The fee token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n function changeCurrencyRates(IERC20 _feeToken, uint64 _rateInEth, uint8 _rateDecimals) external onlyByGovernor {\\n currencyRates[_feeToken].rateInEth = _rateInEth;\\n currencyRates[_feeToken].rateDecimals = _rateDecimals;\\n emit NewCurrencyRate(_feeToken, _rateInEth, _rateDecimals);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's stake in a court.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// Note that the existing delayed stake will be nullified as non-relevant.\\n function setStake(uint96 _courtID, uint256 _newStake) external virtual whenNotPaused {\\n _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert);\\n }\\n\\n /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.\\n /// @param _account The account whose stake is being set.\\n /// @param _courtID The ID of the court.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.\\n function setStakeBySortitionModule(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external {\\n if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly();\\n _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData\\n ) external payable override returns (uint256 disputeID) {\\n if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();\\n\\n return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);\\n }\\n\\n /// @inheritdoc IArbitratorV2\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external override returns (uint256 disputeID) {\\n if (!currencyRates[_feeToken].feePaymentAccepted) revert TokenNotAccepted();\\n if (_feeAmount < arbitrationCost(_extraData, _feeToken)) revert ArbitrationFeesNotEnough();\\n\\n if (!_feeToken.safeTransferFrom(msg.sender, address(this), _feeAmount)) revert TransferFailed();\\n return _createDispute(_numberOfChoices, _extraData, _feeToken, _feeAmount);\\n }\\n\\n function _createDispute(\\n uint256 _numberOfChoices,\\n bytes memory _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) internal virtual returns (uint256 disputeID) {\\n (uint96 courtID, , uint256 disputeKitID) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n if (!courts[courtID].supportedDisputeKits[disputeKitID]) revert DisputeKitNotSupportedByCourt();\\n\\n disputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.courtID = courtID;\\n dispute.arbitrated = IArbitrableV2(msg.sender);\\n dispute.lastPeriodChange = block.timestamp;\\n\\n IDisputeKit disputeKit = disputeKits[disputeKitID];\\n Court storage court = courts[courtID];\\n Round storage round = dispute.rounds.push();\\n\\n // Obtain the feeForJuror in the same currency as the _feeAmount\\n uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)\\n ? court.feeForJuror\\n : convertEthToTokenAmount(_feeToken, court.feeForJuror);\\n round.nbVotes = _feeAmount / feeForJuror;\\n round.disputeKitID = disputeKitID;\\n round.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n round.totalFeesForJurors = _feeAmount;\\n round.feeToken = IERC20(_feeToken);\\n\\n sortitionModule.createDisputeHook(disputeID, 0); // Default round ID.\\n\\n disputeKit.createDispute(disputeID, _numberOfChoices, _extraData, round.nbVotes);\\n emit DisputeCreation(disputeID, IArbitrableV2(msg.sender));\\n }\\n\\n /// @dev Passes the period of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n function passPeriod(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n Court storage court = courts[dispute.courtID];\\n\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period == Period.evidence) {\\n if (\\n currentRound == 0 &&\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)]\\n ) {\\n revert EvidenceNotPassedAndNotAppeal();\\n }\\n if (round.drawnJurors.length != round.nbVotes) revert DisputeStillDrawing();\\n dispute.period = court.hiddenVotes ? Period.commit : Period.vote;\\n } else if (dispute.period == Period.commit) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areCommitsAllCast(_disputeID)\\n ) {\\n revert CommitPeriodNotPassed();\\n }\\n dispute.period = Period.vote;\\n } else if (dispute.period == Period.vote) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].areVotesAllCast(_disputeID)\\n ) {\\n revert VotePeriodNotPassed();\\n }\\n dispute.period = Period.appeal;\\n emit AppealPossible(_disputeID, dispute.arbitrated);\\n } else if (dispute.period == Period.appeal) {\\n if (\\n block.timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256(dispute.period)] &&\\n !disputeKits[round.disputeKitID].isAppealFunded(_disputeID)\\n ) {\\n revert AppealPeriodNotPassed();\\n }\\n dispute.period = Period.execution;\\n } else if (dispute.period == Period.execution) {\\n revert DisputePeriodIsFinal();\\n }\\n\\n dispute.lastPeriodChange = block.timestamp;\\n emit NewPeriod(_disputeID, dispute.period);\\n }\\n\\n /// @dev Draws jurors for the dispute. Can be called in parts.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _iterations The number of iterations to run.\\n function draw(uint256 _disputeID, uint256 _iterations) external {\\n Dispute storage dispute = disputes[_disputeID];\\n uint256 currentRound = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[currentRound];\\n if (dispute.period != Period.evidence) revert NotEvidencePeriod();\\n\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n uint256 startIndex = round.drawIterations; // for gas: less storage reads\\n uint256 i;\\n while (i < _iterations && round.drawnJurors.length < round.nbVotes) {\\n address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);\\n if (drawnAddress == address(0)) {\\n continue;\\n }\\n sortitionModule.lockStake(drawnAddress, round.pnkAtStakePerJuror);\\n emit Draw(drawnAddress, _disputeID, currentRound, round.drawnJurors.length);\\n round.drawnJurors.push(drawnAddress);\\n if (round.drawnJurors.length == round.nbVotes) {\\n sortitionModule.postDrawHook(_disputeID, currentRound);\\n }\\n }\\n round.drawIterations += i;\\n }\\n\\n /// @dev Appeals the ruling of a specified dispute.\\n /// Note: Access restricted to the Dispute Kit for this `disputeID`.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _numberOfChoices Number of choices for the dispute. Can be required during court jump.\\n /// @param _extraData Extradata for the dispute. Can be required during court jump.\\n function appeal(uint256 _disputeID, uint256 _numberOfChoices, bytes memory _extraData) external payable {\\n if (msg.value < appealCost(_disputeID)) revert AppealFeesNotEnough();\\n\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.appeal) revert DisputeNotAppealable();\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();\\n\\n uint96 newCourtID = dispute.courtID;\\n uint256 newDisputeKitID = round.disputeKitID;\\n\\n // Warning: the extra round must be created before calling disputeKit.createDispute()\\n Round storage extraRound = dispute.rounds.push();\\n\\n if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {\\n // Jump to parent court.\\n newCourtID = courts[newCourtID].parent;\\n\\n if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {\\n // Switch to classic dispute kit if parent court doesn't support the current one.\\n newDisputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n\\n if (newCourtID != dispute.courtID) {\\n emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);\\n }\\n }\\n\\n dispute.courtID = newCourtID;\\n dispute.period = Period.evidence;\\n dispute.lastPeriodChange = block.timestamp;\\n\\n Court storage court = courts[newCourtID];\\n extraRound.nbVotes = msg.value / court.feeForJuror; // As many votes that can be afforded by the provided funds.\\n extraRound.pnkAtStakePerJuror = (court.minStake * court.alpha) / ALPHA_DIVISOR;\\n extraRound.totalFeesForJurors = msg.value;\\n extraRound.disputeKitID = newDisputeKitID;\\n\\n sortitionModule.createDisputeHook(_disputeID, dispute.rounds.length - 1);\\n\\n // Dispute kit was changed, so create a dispute in the new DK contract.\\n if (extraRound.disputeKitID != round.disputeKitID) {\\n emit DisputeKitJump(_disputeID, dispute.rounds.length - 1, round.disputeKitID, extraRound.disputeKitID);\\n disputeKits[extraRound.disputeKitID].createDispute(\\n _disputeID,\\n _numberOfChoices,\\n _extraData,\\n extraRound.nbVotes\\n );\\n }\\n\\n emit AppealDecision(_disputeID, dispute.arbitrated);\\n emit NewPeriod(_disputeID, Period.evidence);\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute. Can be called in parts.\\n /// Note: Reward distributions are forbidden during pause.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The appeal round.\\n /// @param _iterations The number of iterations to run.\\n function execute(uint256 _disputeID, uint256 _round, uint256 _iterations) external whenNotPaused {\\n Round storage round;\\n {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n\\n round = dispute.rounds[_round];\\n } // stack too deep workaround\\n\\n uint256 start = round.repartitions;\\n uint256 end = round.repartitions + _iterations;\\n\\n uint256 pnkPenaltiesInRound = round.pnkPenalties; // Keep in memory to save gas.\\n uint256 numberOfVotesInRound = round.drawnJurors.length;\\n uint256 feePerJurorInRound = round.totalFeesForJurors / numberOfVotesInRound;\\n uint256 pnkAtStakePerJurorInRound = round.pnkAtStakePerJuror;\\n uint256 coherentCount;\\n {\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n coherentCount = disputeKit.getCoherentCount(_disputeID, _round); // Total number of jurors that are eligible to a reward in this round.\\n } // stack too deep workaround\\n\\n if (coherentCount == 0) {\\n // We loop over the votes once as there are no rewards because it is not a tie and no one in this round is coherent with the final outcome.\\n if (end > numberOfVotesInRound) end = numberOfVotesInRound;\\n } else {\\n // We loop over the votes twice, first to collect the PNK penalties, and second to distribute them as rewards along with arbitration fees.\\n if (end > numberOfVotesInRound * 2) end = numberOfVotesInRound * 2;\\n }\\n round.repartitions = end;\\n\\n for (uint256 i = start; i < end; i++) {\\n if (i < numberOfVotesInRound) {\\n pnkPenaltiesInRound = _executePenalties(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n } else {\\n _executeRewards(\\n ExecuteParams({\\n disputeID: _disputeID,\\n round: _round,\\n coherentCount: coherentCount,\\n numberOfVotesInRound: numberOfVotesInRound,\\n feePerJurorInRound: feePerJurorInRound,\\n pnkAtStakePerJurorInRound: pnkAtStakePerJurorInRound,\\n pnkPenaltiesInRound: pnkPenaltiesInRound,\\n repartition: i\\n })\\n );\\n }\\n }\\n if (round.pnkPenalties != pnkPenaltiesInRound) {\\n round.pnkPenalties = pnkPenaltiesInRound; // Reentrancy risk: breaks Check-Effect-Interact\\n }\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, penalties only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n /// @return pnkPenaltiesInRoundCache The updated penalties in round cache.\\n function _executePenalties(ExecuteParams memory _params) internal returns (uint256) {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n // Fully coherent jurors won't be penalized.\\n uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;\\n _params.pnkPenaltiesInRound += penalty;\\n\\n // Unlock the PNKs affected by the penalty\\n address account = round.drawnJurors[_params.repartition];\\n sortitionModule.unlockStake(account, penalty);\\n\\n // Apply the penalty to the staked PNKs.\\n sortitionModule.penalizeStake(account, penalty);\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n -int256(penalty),\\n 0,\\n round.feeToken\\n );\\n\\n if (!disputeKit.isVoteActive(_params.disputeID, _params.round, _params.repartition)) {\\n // The juror is inactive, unstake them.\\n sortitionModule.setJurorInactive(account);\\n }\\n if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {\\n // No one was coherent, send the rewards to the governor.\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(round.totalFeesForJurors);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, round.totalFeesForJurors);\\n }\\n pinakion.safeTransfer(governor, _params.pnkPenaltiesInRound);\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n _params.pnkPenaltiesInRound,\\n round.totalFeesForJurors,\\n round.feeToken\\n );\\n }\\n return _params.pnkPenaltiesInRound;\\n }\\n\\n /// @dev Distribute the PNKs at stake and the dispute fees for the specific round of the dispute, rewards only.\\n /// @param _params The parameters for the execution, see `ExecuteParams`.\\n function _executeRewards(ExecuteParams memory _params) internal {\\n Dispute storage dispute = disputes[_params.disputeID];\\n Round storage round = dispute.rounds[_params.round];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n\\n // [0, 1] value that determines how coherent the juror was in this round, in basis points.\\n uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence(\\n _params.disputeID,\\n _params.round,\\n _params.repartition % _params.numberOfVotesInRound,\\n _params.feePerJurorInRound,\\n _params.pnkAtStakePerJurorInRound\\n );\\n\\n // Make sure the degree doesn't exceed 1, though it should be ensured by the dispute kit.\\n if (degreeOfCoherence > ALPHA_DIVISOR) {\\n degreeOfCoherence = ALPHA_DIVISOR;\\n }\\n\\n address account = round.drawnJurors[_params.repartition % _params.numberOfVotesInRound];\\n uint256 pnkLocked = (round.pnkAtStakePerJuror * degreeOfCoherence) / ALPHA_DIVISOR;\\n\\n // Release the rest of the PNKs of the juror for this round.\\n sortitionModule.unlockStake(account, pnkLocked);\\n\\n // Give back the locked PNKs in case the juror fully unstaked earlier.\\n if (!sortitionModule.isJurorStaked(account)) {\\n pinakion.safeTransfer(account, pnkLocked);\\n }\\n\\n // Transfer the rewards\\n uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumPnkRewardPaid += pnkReward;\\n uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;\\n round.sumFeeRewardPaid += feeReward;\\n pinakion.safeTransfer(account, pnkReward);\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(account).send(feeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(account, feeReward);\\n }\\n emit TokenAndETHShift(\\n account,\\n _params.disputeID,\\n _params.round,\\n degreeOfCoherence,\\n int256(pnkReward),\\n int256(feeReward),\\n round.feeToken\\n );\\n\\n // Transfer any residual rewards to the governor. It may happen due to partial coherence of the jurors.\\n if (_params.repartition == _params.numberOfVotesInRound * 2 - 1) {\\n uint256 leftoverPnkReward = _params.pnkPenaltiesInRound - round.sumPnkRewardPaid;\\n uint256 leftoverFeeReward = round.totalFeesForJurors - round.sumFeeRewardPaid;\\n if (leftoverPnkReward != 0 || leftoverFeeReward != 0) {\\n if (leftoverPnkReward != 0) {\\n pinakion.safeTransfer(governor, leftoverPnkReward);\\n }\\n if (leftoverFeeReward != 0) {\\n if (round.feeToken == NATIVE_CURRENCY) {\\n // The dispute fees were paid in ETH\\n payable(governor).send(leftoverFeeReward);\\n } else {\\n // The dispute fees were paid in ERC20\\n round.feeToken.safeTransfer(governor, leftoverFeeReward);\\n }\\n }\\n emit LeftoverRewardSent(\\n _params.disputeID,\\n _params.round,\\n leftoverPnkReward,\\n leftoverFeeReward,\\n round.feeToken\\n );\\n }\\n }\\n }\\n\\n /// @dev Executes a specified dispute's ruling.\\n /// @param _disputeID The ID of the dispute.\\n function executeRuling(uint256 _disputeID) external {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period != Period.execution) revert NotExecutionPeriod();\\n if (dispute.ruled) revert RulingAlreadyExecuted();\\n\\n (uint256 winningChoice, , ) = currentRuling(_disputeID);\\n dispute.ruled = true;\\n emit Ruling(dispute.arbitrated, _disputeID, winningChoice);\\n dispute.arbitrated.rule(_disputeID, winningChoice);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Compute the cost of arbitration denominated in ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes memory _extraData) public view override returns (uint256 cost) {\\n (uint96 courtID, uint256 minJurors, ) = _extraDataToCourtIDMinJurorsDisputeKit(_extraData);\\n cost = courts[courtID].feeForJuror * minJurors;\\n }\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) public view override returns (uint256 cost) {\\n cost = convertEthToTokenAmount(_feeToken, arbitrationCost(_extraData));\\n }\\n\\n /// @dev Gets the cost of appealing a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return cost The appeal cost.\\n function appealCost(uint256 _disputeID) public view returns (uint256 cost) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n if (round.nbVotes >= court.jurorsForCourtJump) {\\n // Jump to parent court.\\n if (dispute.courtID == GENERAL_COURT) {\\n // TODO: Handle the forking when appealed in General court.\\n cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.\\n } else {\\n cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n } else {\\n // Stay in current court.\\n cost = court.feeForJuror * ((round.nbVotes * 2) + 1);\\n }\\n }\\n\\n /// @dev Gets the start and the end of a specified dispute's current appeal period.\\n /// @param _disputeID The ID of the dispute.\\n /// @return start The start of the appeal period.\\n /// @return end The end of the appeal period.\\n function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {\\n Dispute storage dispute = disputes[_disputeID];\\n if (dispute.period == Period.appeal) {\\n start = dispute.lastPeriodChange;\\n end = dispute.lastPeriodChange + courts[dispute.courtID].timesPerPeriod[uint256(Period.appeal)];\\n } else {\\n start = 0;\\n end = 0;\\n }\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) public view returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n IDisputeKit disputeKit = disputeKits[round.disputeKitID];\\n (ruling, tied, overridden) = disputeKit.currentRuling(_disputeID);\\n }\\n\\n /// @dev Gets the round info for a specified dispute and round.\\n /// @dev This function must not be called from a non-view function because it returns a dynamic array which might be very large, theoretically exceeding the block gas limit.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The round to get the info for.\\n /// @return round The round info.\\n function getRoundInfo(uint256 _disputeID, uint256 _round) external view returns (Round memory) {\\n return disputes[_disputeID].rounds[_round];\\n }\\n\\n /// @dev Gets the PNK at stake per juror for a specified dispute and round.\\n /// @param _disputeID The ID of the dispute.\\n /// @param _round The round to get the info for.\\n /// @return pnkAtStakePerJuror The PNK at stake per juror.\\n function getPnkAtStakePerJuror(uint256 _disputeID, uint256 _round) external view returns (uint256) {\\n return disputes[_disputeID].rounds[_round].pnkAtStakePerJuror;\\n }\\n\\n /// @dev Gets the number of rounds for a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return The number of rounds.\\n function getNumberOfRounds(uint256 _disputeID) external view returns (uint256) {\\n return disputes[_disputeID].rounds.length;\\n }\\n\\n /// @dev Checks if a given dispute kit is supported by a given court.\\n /// @param _courtID The ID of the court to check the support for.\\n /// @param _disputeKitID The ID of the dispute kit to check the support for.\\n /// @return Whether the dispute kit is supported or not.\\n function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {\\n return courts[_courtID].supportedDisputeKits[_disputeKitID];\\n }\\n\\n /// @dev Gets the timesPerPeriod array for a given court.\\n /// @param _courtID The ID of the court to get the times from.\\n /// @return timesPerPeriod The timesPerPeriod array for the given court.\\n function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory timesPerPeriod) {\\n timesPerPeriod = courts[_courtID].timesPerPeriod;\\n }\\n\\n // ************************************* //\\n // * Public Views for Dispute Kits * //\\n // ************************************* //\\n\\n /// @dev Gets the number of votes permitted for the specified dispute in the latest round.\\n /// @param _disputeID The ID of the dispute.\\n function getNumberOfVotes(uint256 _disputeID) external view returns (uint256) {\\n Dispute storage dispute = disputes[_disputeID];\\n return dispute.rounds[dispute.rounds.length - 1].nbVotes;\\n }\\n\\n /// @dev Returns true if the dispute kit will be switched to a parent DK.\\n /// @param _disputeID The ID of the dispute.\\n /// @return Whether DK will be switched or not.\\n function isDisputeKitJumping(uint256 _disputeID) external view returns (bool) {\\n Dispute storage dispute = disputes[_disputeID];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n Court storage court = courts[dispute.courtID];\\n\\n if (round.nbVotes < court.jurorsForCourtJump) {\\n return false;\\n }\\n\\n // Jump if the parent court doesn't support the current DK.\\n return !courts[court.parent].supportedDisputeKits[round.disputeKitID];\\n }\\n\\n function getDisputeKitsLength() external view returns (uint256) {\\n return disputeKits.length;\\n }\\n\\n function convertEthToTokenAmount(IERC20 _toToken, uint256 _amountInEth) public view returns (uint256) {\\n return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Toggles the dispute kit support for a given court.\\n /// @param _courtID The ID of the court to toggle the support for.\\n /// @param _disputeKitID The ID of the dispute kit to toggle the support for.\\n /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.\\n function _enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) internal {\\n courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;\\n emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);\\n }\\n\\n /// @dev If called only once then set _onError to Revert, otherwise set it to Return\\n /// @param _account The account to set the stake for.\\n /// @param _courtID The ID of the court to set the stake for.\\n /// @param _newStake The new stake.\\n /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.\\n /// @param _onError Whether to revert or return false on error.\\n /// @return Whether the stake was successfully set or not.\\n function _setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred,\\n OnError _onError\\n ) internal returns (bool) {\\n if (_courtID == FORKING_COURT || _courtID >= courts.length) {\\n _stakingFailed(_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.\\n return false;\\n }\\n if (_newStake != 0 && _newStake < courts[_courtID].minStake) {\\n _stakingFailed(_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.\\n return false;\\n }\\n (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult) = sortitionModule.setStake(\\n _account,\\n _courtID,\\n _newStake,\\n _alreadyTransferred\\n );\\n if (stakingResult != StakingResult.Successful) {\\n _stakingFailed(_onError, stakingResult);\\n return false;\\n }\\n if (pnkDeposit > 0) {\\n if (!pinakion.safeTransferFrom(_account, address(this), pnkDeposit)) {\\n _stakingFailed(_onError, StakingResult.StakingTransferFailed);\\n return false;\\n }\\n }\\n if (pnkWithdrawal > 0) {\\n if (!pinakion.safeTransfer(_account, pnkWithdrawal)) {\\n _stakingFailed(_onError, StakingResult.UnstakingTransferFailed);\\n return false;\\n }\\n }\\n return true;\\n }\\n\\n /// @dev It may revert depending on the _onError parameter.\\n function _stakingFailed(OnError _onError, StakingResult _result) internal pure virtual {\\n if (_onError == OnError.Return) return;\\n if (_result == StakingResult.StakingTransferFailed) revert StakingTransferFailed();\\n if (_result == StakingResult.UnstakingTransferFailed) revert UnstakingTransferFailed();\\n if (_result == StakingResult.CannotStakeInMoreCourts) revert StakingInTooManyCourts();\\n if (_result == StakingResult.CannotStakeInThisCourt) revert StakingNotPossibleInThisCourt();\\n if (_result == StakingResult.CannotStakeLessThanMinStake) revert StakingLessThanCourtMinStake();\\n if (_result == StakingResult.CannotStakeZeroWhenNoStake) revert StakingZeroWhenNoStake();\\n }\\n\\n /// @dev Gets a court ID, the minimum number of jurors and an ID of a dispute kit from a specified extra data bytes array.\\n /// Note that if extradata contains an incorrect value then this value will be switched to default.\\n /// @param _extraData The extra data bytes array. The first 32 bytes are the court ID, the next are the minimum number of jurors and the last are the dispute kit ID.\\n /// @return courtID The court ID.\\n /// @return minJurors The minimum number of jurors required.\\n /// @return disputeKitID The ID of the dispute kit.\\n function _extraDataToCourtIDMinJurorsDisputeKit(\\n bytes memory _extraData\\n ) internal view returns (uint96 courtID, uint256 minJurors, uint256 disputeKitID) {\\n // Note that if the extradata doesn't contain 32 bytes for the dispute kit ID it'll return the default 0 index.\\n if (_extraData.length >= 64) {\\n assembly {\\n // solium-disable-line security/no-inline-assembly\\n courtID := mload(add(_extraData, 0x20))\\n minJurors := mload(add(_extraData, 0x40))\\n disputeKitID := mload(add(_extraData, 0x60))\\n }\\n if (courtID == FORKING_COURT || courtID >= courts.length) {\\n courtID = GENERAL_COURT;\\n }\\n if (minJurors == 0) {\\n minJurors = DEFAULT_NB_OF_JURORS;\\n }\\n if (disputeKitID == NULL_DISPUTE_KIT || disputeKitID >= disputeKits.length) {\\n disputeKitID = DISPUTE_KIT_CLASSIC; // 0 index is not used.\\n }\\n } else {\\n courtID = GENERAL_COURT;\\n minJurors = DEFAULT_NB_OF_JURORS;\\n disputeKitID = DISPUTE_KIT_CLASSIC;\\n }\\n }\\n\\n // ************************************* //\\n // * Errors * //\\n // ************************************* //\\n\\n error GovernorOnly();\\n error GuardianOrGovernorOnly();\\n error DisputeKitOnly();\\n error SortitionModuleOnly();\\n error UnsuccessfulCall();\\n error InvalidDisputKitParent();\\n error MinStakeLowerThanParentCourt();\\n error UnsupportedDisputeKit();\\n error InvalidForkingCourtAsParent();\\n error WrongDisputeKitIndex();\\n error CannotDisableClassicDK();\\n error StakingInTooManyCourts();\\n error StakingNotPossibleInThisCourt();\\n error StakingLessThanCourtMinStake();\\n error StakingTransferFailed();\\n error UnstakingTransferFailed();\\n error ArbitrationFeesNotEnough();\\n error DisputeKitNotSupportedByCourt();\\n error MustSupportDisputeKitClassic();\\n error TokenNotAccepted();\\n error EvidenceNotPassedAndNotAppeal();\\n error DisputeStillDrawing();\\n error CommitPeriodNotPassed();\\n error VotePeriodNotPassed();\\n error AppealPeriodNotPassed();\\n error NotEvidencePeriod();\\n error AppealFeesNotEnough();\\n error DisputeNotAppealable();\\n error NotExecutionPeriod();\\n error RulingAlreadyExecuted();\\n error DisputePeriodIsFinal();\\n error TransferFailed();\\n error WhenNotPausedOnly();\\n error WhenPausedOnly();\\n error StakingZeroWhenNoStake();\\n}\\n\",\"keccak256\":\"0xd5995a460b6ceca0ceea5ea4887fe729b8ee4c6f71d39f413db7f12946a269a5\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitClassicBase.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from \\\"../KlerosCore.sol\\\";\\nimport {Initializable} from \\\"../../proxy/Initializable.sol\\\";\\nimport {UUPSProxiable} from \\\"../../proxy/UUPSProxiable.sol\\\";\\n\\n/// @title DisputeKitClassicBase\\n/// Abstract Dispute kit classic implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\nabstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxiable {\\n // ************************************* //\\n // * Structs * //\\n // ************************************* //\\n\\n struct Dispute {\\n Round[] rounds; // Rounds of the dispute. 0 is the default round, and [1, ..n] are the appeal rounds.\\n uint256 numberOfChoices; // The number of choices jurors have when voting. This does not include choice `0` which is reserved for \\\"refuse to arbitrate\\\".\\n bool jumped; // True if dispute jumped to a parent dispute kit and won't be handled by this DK anymore.\\n mapping(uint256 => uint256) coreRoundIDToLocal; // Maps id of the round in the core contract to the index of the round of related local dispute.\\n bytes extraData; // Extradata for the dispute.\\n }\\n\\n struct Round {\\n Vote[] votes; // Former votes[_appeal][].\\n uint256 winningChoice; // The choice with the most votes. Note that in the case of a tie, it is the choice that reached the tied number of votes first.\\n mapping(uint256 => uint256) counts; // The sum of votes for each choice in the form `counts[choice]`.\\n bool tied; // True if there is a tie, false otherwise.\\n uint256 totalVoted; // Former uint[_appeal] votesInEachRound.\\n uint256 totalCommitted; // Former commitsInRound.\\n mapping(uint256 choiceId => uint256) paidFees; // Tracks the fees paid for each choice in this round.\\n mapping(uint256 choiceId => bool) hasPaid; // True if this choice was fully funded, false otherwise.\\n mapping(address account => mapping(uint256 choiceId => uint256)) contributions; // Maps contributors to their contributions for each choice.\\n uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute.\\n uint256[] fundedChoices; // Stores the choices that are fully funded.\\n uint256 nbVotes; // Maximal number of votes this dispute can get.\\n mapping(address drawnAddress => bool) alreadyDrawn; // DEPRECATED: DO NOT COMMIT\\n }\\n\\n struct Vote {\\n address account; // The address of the juror.\\n bytes32 commit; // The commit of the juror. For courts with hidden votes.\\n uint256 choice; // The choice of the juror.\\n bool voted; // True if the vote has been cast.\\n }\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n uint256 public constant WINNER_STAKE_MULTIPLIER = 10000; // Multiplier of the appeal cost that the winner has to pay as fee stake for a round in basis points. Default is 1x of appeal fee.\\n uint256 public constant LOSER_STAKE_MULTIPLIER = 20000; // Multiplier of the appeal cost that the loser has to pay as fee stake for a round in basis points. Default is 2x of appeal fee.\\n uint256 public constant LOSER_APPEAL_PERIOD_MULTIPLIER = 5000; // Multiplier of the appeal period for the choice that wasn't voted for in the previous round, in basis points. Default is 1/2 of original appeal period.\\n uint256 public constant ONE_BASIS_POINT = 10000; // One basis point, for scaling.\\n\\n address public governor; // The governor of the contract.\\n KlerosCore public core; // The Kleros Core arbitrator\\n Dispute[] public disputes; // Array of the locally created disputes.\\n mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.\\n bool public singleDrawPerJuror; // Whether each juror can only draw once per dispute, false by default.\\n mapping(uint256 localDisputeID => mapping(uint256 localRoundID => mapping(address drawnAddress => bool)))\\n public alreadyDrawn; // 'true' if the address has already been drawn, false by default. To be added to the Round struct when fully redeploying rather than upgrading.\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev To be emitted when a dispute is created.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _numberOfChoices The number of choices available in the dispute.\\n /// @param _extraData The extra data for the dispute.\\n event DisputeCreation(uint256 indexed _coreDisputeID, uint256 _numberOfChoices, bytes _extraData);\\n\\n /// @dev To be emitted when a vote commitment is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _commit The commitment of the juror.\\n event CommitCast(uint256 indexed _coreDisputeID, address indexed _juror, uint256[] _voteIDs, bytes32 _commit);\\n\\n /// @dev To be emitted when a funding contribution is made.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount contributed.\\n event Contribution(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when the contributed funds are withdrawn.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n /// @param _contributor The address of the contributor.\\n /// @param _amount The amount withdrawn.\\n event Withdrawal(\\n uint256 indexed _coreDisputeID,\\n uint256 indexed _coreRoundID,\\n uint256 _choice,\\n address indexed _contributor,\\n uint256 _amount\\n );\\n\\n /// @dev To be emitted when a choice is fully funded for an appeal.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _coreRoundID The identifier of the round in the Arbitrator contract.\\n /// @param _choice The choice that is being funded.\\n event ChoiceFunded(uint256 indexed _coreDisputeID, uint256 indexed _coreRoundID, uint256 indexed _choice);\\n\\n // ************************************* //\\n // * Modifiers * //\\n // ************************************* //\\n\\n modifier onlyByGovernor() {\\n require(governor == msg.sender, \\\"Access not allowed: Governor only.\\\");\\n _;\\n }\\n\\n modifier onlyByCore() {\\n require(address(core) == msg.sender, \\\"Access not allowed: KlerosCore only.\\\");\\n _;\\n }\\n\\n modifier notJumped(uint256 _coreDisputeID) {\\n require(!disputes[coreDisputeIDToLocal[_coreDisputeID]].jumped, \\\"Dispute jumped to a parent DK!\\\");\\n _;\\n }\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function __DisputeKitClassicBase_initialize(address _governor, KlerosCore _core) internal onlyInitializing {\\n governor = _governor;\\n core = _core;\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Allows the governor to call anything on behalf of the contract.\\n /// @param _destination The destination of the call.\\n /// @param _amount The value sent with the call.\\n /// @param _data The data sent with the call.\\n function executeGovernorProposal(\\n address _destination,\\n uint256 _amount,\\n bytes memory _data\\n ) external onlyByGovernor {\\n (bool success, ) = _destination.call{value: _amount}(_data);\\n require(success, \\\"Unsuccessful call\\\");\\n }\\n\\n /// @dev Changes the `governor` storage variable.\\n /// @param _governor The new value for the `governor` storage variable.\\n function changeGovernor(address payable _governor) external onlyByGovernor {\\n governor = _governor;\\n }\\n\\n /// @dev Changes the `core` storage variable.\\n /// @param _core The new value for the `core` storage variable.\\n function changeCore(address _core) external onlyByGovernor {\\n core = KlerosCore(_core);\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Number of votes for this dispute.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external override onlyByCore {\\n uint256 localDisputeID = disputes.length;\\n Dispute storage dispute = disputes.push();\\n dispute.numberOfChoices = _numberOfChoices;\\n dispute.extraData = _extraData;\\n\\n // New round in the Core should be created before the dispute creation in DK.\\n dispute.coreRoundIDToLocal[core.getNumberOfRounds(_coreDisputeID) - 1] = dispute.rounds.length;\\n\\n Round storage round = dispute.rounds.push();\\n round.nbVotes = _nbVotes;\\n round.tied = true;\\n\\n coreDisputeIDToLocal[_coreDisputeID] = localDisputeID;\\n emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);\\n }\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _nonce Nonce of the drawing iteration.\\n /// @return drawnAddress The drawn address.\\n function draw(\\n uint256 _coreDisputeID,\\n uint256 _nonce\\n ) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {\\n uint256 localDisputeID = coreDisputeIDToLocal[_coreDisputeID];\\n Dispute storage dispute = disputes[localDisputeID];\\n uint256 localRoundID = dispute.rounds.length - 1;\\n Round storage round = dispute.rounds[localRoundID];\\n\\n ISortitionModule sortitionModule = core.sortitionModule();\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.\\n\\n drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);\\n\\n if (_postDrawCheck(round, _coreDisputeID, drawnAddress)) {\\n round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));\\n alreadyDrawn[localDisputeID][localRoundID][drawnAddress] = true;\\n } else {\\n drawnAddress = address(0);\\n }\\n }\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash.\\n function castCommit(uint256 _coreDisputeID, uint256[] calldata _voteIDs, bytes32 _commit) external {\\n _castCommit(_coreDisputeID, _voteIDs, _commit);\\n }\\n\\n function _castCommit(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.commit, \\\"The dispute should be in Commit period.\\\");\\n require(_commit != bytes32(0), \\\"Empty commit.\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == msg.sender, \\\"The caller has to own the vote.\\\");\\n round.votes[_voteIDs[i]].commit = _commit;\\n }\\n round.totalCommitted += _voteIDs.length;\\n emit CommitCast(_coreDisputeID, msg.sender, _voteIDs, _commit);\\n }\\n\\n /// @dev Sets the caller's choices for the specified votes.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _choice The choice.\\n /// @param _salt The salt for the commit if the votes were hidden.\\n /// @param _justification Justification of the choice.\\n function castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external {\\n _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification, msg.sender);\\n }\\n\\n function _castVote(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification,\\n address _juror\\n ) internal notJumped(_coreDisputeID) {\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n require(period == KlerosCoreBase.Period.vote, \\\"The dispute should be in Vote period.\\\");\\n require(_voteIDs.length > 0, \\\"No voteID provided\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"Choice out of bounds\\\");\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n bytes32 voteHash = hashVote(_choice, _salt, _justification);\\n\\n // Save the votes.\\n for (uint256 i = 0; i < _voteIDs.length; i++) {\\n require(round.votes[_voteIDs[i]].account == _juror, \\\"The juror has to own the vote.\\\");\\n require(\\n !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash,\\n \\\"The vote hash must match the commitment in courts with hidden votes.\\\"\\n );\\n require(!round.votes[_voteIDs[i]].voted, \\\"Vote already cast.\\\");\\n round.votes[_voteIDs[i]].choice = _choice;\\n round.votes[_voteIDs[i]].voted = true;\\n }\\n } // Workaround stack too deep\\n\\n round.totalVoted += _voteIDs.length;\\n\\n round.counts[_choice] += _voteIDs.length;\\n if (_choice == round.winningChoice) {\\n if (round.tied) round.tied = false;\\n } else {\\n // Voted for another choice.\\n if (round.counts[_choice] == round.counts[round.winningChoice]) {\\n // Tie.\\n if (!round.tied) round.tied = true;\\n } else if (round.counts[_choice] > round.counts[round.winningChoice]) {\\n // New winner.\\n round.winningChoice = _choice;\\n round.tied = false;\\n }\\n }\\n emit VoteCast(_coreDisputeID, _juror, _voteIDs, _choice, _justification);\\n }\\n\\n /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.\\n /// Note that the surplus deposit will be reimbursed.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core.\\n /// @param _choice A choice that receives funding.\\n function fundAppeal(uint256 _coreDisputeID, uint256 _choice) external payable notJumped(_coreDisputeID) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n require(_choice <= dispute.numberOfChoices, \\\"There is no such ruling to fund.\\\");\\n\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, \\\"Appeal period is over.\\\");\\n\\n uint256 multiplier;\\n (uint256 ruling, , ) = this.currentRuling(_coreDisputeID);\\n if (ruling == _choice) {\\n multiplier = WINNER_STAKE_MULTIPLIER;\\n } else {\\n require(\\n block.timestamp - appealPeriodStart <\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT,\\n \\\"Appeal period is over for loser\\\"\\n );\\n multiplier = LOSER_STAKE_MULTIPLIER;\\n }\\n\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n uint256 coreRoundID = core.getNumberOfRounds(_coreDisputeID) - 1;\\n\\n require(!round.hasPaid[_choice], \\\"Appeal fee is already paid.\\\");\\n uint256 appealCost = core.appealCost(_coreDisputeID);\\n uint256 totalCost = appealCost + (appealCost * multiplier) / ONE_BASIS_POINT;\\n\\n // Take up to the amount necessary to fund the current round at the current costs.\\n uint256 contribution;\\n if (totalCost > round.paidFees[_choice]) {\\n contribution = totalCost - round.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.\\n ? msg.value\\n : totalCost - round.paidFees[_choice];\\n emit Contribution(_coreDisputeID, coreRoundID, _choice, msg.sender, contribution);\\n }\\n\\n round.contributions[msg.sender][_choice] += contribution;\\n round.paidFees[_choice] += contribution;\\n if (round.paidFees[_choice] >= totalCost) {\\n round.feeRewards += round.paidFees[_choice];\\n round.fundedChoices.push(_choice);\\n round.hasPaid[_choice] = true;\\n emit ChoiceFunded(_coreDisputeID, coreRoundID, _choice);\\n }\\n\\n if (round.fundedChoices.length > 1) {\\n // At least two sides are fully funded.\\n round.feeRewards = round.feeRewards - appealCost;\\n\\n if (core.isDisputeKitJumping(_coreDisputeID)) {\\n // Don't create a new round in case of a jump, and remove local dispute from the flow.\\n dispute.jumped = true;\\n } else {\\n // Don't subtract 1 from length since both round arrays haven't been updated yet.\\n dispute.coreRoundIDToLocal[coreRoundID + 1] = dispute.rounds.length;\\n\\n Round storage newRound = dispute.rounds.push();\\n newRound.nbVotes = core.getNumberOfVotes(_coreDisputeID);\\n newRound.tied = true;\\n }\\n core.appeal{value: appealCost}(_coreDisputeID, dispute.numberOfChoices, dispute.extraData);\\n }\\n\\n if (msg.value > contribution) payable(msg.sender).send(msg.value - contribution);\\n }\\n\\n /// @dev Allows those contributors who attempted to fund an appeal round to withdraw any reimbursable fees or rewards after the dispute gets resolved.\\n /// Note that withdrawals are not possible if the core contract is paused.\\n /// @param _coreDisputeID Index of the dispute in Kleros Core contract.\\n /// @param _beneficiary The address whose rewards to withdraw.\\n /// @param _coreRoundID The round in the Kleros Core contract the caller wants to withdraw from.\\n /// @param _choice The ruling option that the caller wants to withdraw from.\\n /// @return amount The withdrawn amount.\\n function withdrawFeesAndRewards(\\n uint256 _coreDisputeID,\\n address payable _beneficiary,\\n uint256 _coreRoundID,\\n uint256 _choice\\n ) external returns (uint256 amount) {\\n (, , , bool isRuled, ) = core.disputes(_coreDisputeID);\\n require(isRuled, \\\"Dispute should be resolved.\\\");\\n require(!core.paused(), \\\"Core is paused\\\");\\n\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 finalRuling, , ) = core.currentRuling(_coreDisputeID);\\n\\n if (!round.hasPaid[_choice]) {\\n // Allow to reimburse if funding was unsuccessful for this ruling option.\\n amount = round.contributions[_beneficiary][_choice];\\n } else {\\n // Funding was successful for this ruling option.\\n if (_choice == finalRuling) {\\n // This ruling option is the ultimate winner.\\n amount = round.paidFees[_choice] > 0\\n ? (round.contributions[_beneficiary][_choice] * round.feeRewards) / round.paidFees[_choice]\\n : 0;\\n } else if (!round.hasPaid[finalRuling]) {\\n // The ultimate winner was not funded in this round. In this case funded ruling option(s) are reimbursed.\\n amount =\\n (round.contributions[_beneficiary][_choice] * round.feeRewards) /\\n (round.paidFees[round.fundedChoices[0]] + round.paidFees[round.fundedChoices[1]]);\\n }\\n }\\n round.contributions[_beneficiary][_choice] = 0;\\n\\n if (amount != 0) {\\n _beneficiary.send(amount); // Deliberate use of send to prevent reverting fallback. It's the user's responsibility to accept ETH.\\n emit Withdrawal(_coreDisputeID, _coreRoundID, _choice, _beneficiary, amount);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @dev The unused parameters may be used by overriding contracts.\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure virtual returns (bytes32) {\\n return keccak256(abi.encodePacked(_choice, _salt));\\n }\\n\\n function getFundedChoices(uint256 _coreDisputeID) public view returns (uint256[] memory fundedChoices) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage lastRound = dispute.rounds[dispute.rounds.length - 1];\\n return lastRound.fundedChoices;\\n }\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(\\n uint256 _coreDisputeID\\n ) external view override returns (uint256 ruling, bool tied, bool overridden) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n tied = round.tied;\\n ruling = tied ? 0 : round.winningChoice;\\n (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID);\\n // Override the final ruling if only one side funded the appeals.\\n if (period == KlerosCoreBase.Period.execution) {\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n if (fundedChoices.length == 1) {\\n ruling = fundedChoices[0];\\n tied = false;\\n overridden = true;\\n }\\n }\\n }\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 /* _feePerJuror */,\\n uint256 /* _pnkAtStakePerJuror */\\n ) external view override returns (uint256) {\\n // In this contract this degree can be either 0 or 1, but in other dispute kits this value can be something in between.\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (vote.voted && (vote.choice == winningChoice || tied)) {\\n return ONE_BASIS_POINT;\\n } else {\\n return 0;\\n }\\n }\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view override returns (uint256) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage currentRound = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n (uint256 winningChoice, bool tied, ) = core.currentRuling(_coreDisputeID);\\n\\n if (currentRound.totalVoted == 0 || (!tied && currentRound.counts[winningChoice] == 0)) {\\n return 0;\\n } else if (tied) {\\n return currentRound.totalVoted;\\n } else {\\n return currentRound.counts[winningChoice];\\n }\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n return round.totalCommitted == round.votes.length;\\n }\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.rounds.length - 1];\\n\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n (, bool hiddenVotes, , , , , ) = core.courts(courtID);\\n uint256 expectedTotalVoted = hiddenVotes ? round.totalCommitted : round.votes.length;\\n\\n return round.totalVoted == expectedTotalVoted;\\n }\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// Note that this function is to be called directly by the core contract and is not for off-chain usage.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view override returns (bool) {\\n (uint256 appealPeriodStart, uint256 appealPeriodEnd) = core.appealPeriod(_coreDisputeID);\\n\\n uint256[] memory fundedChoices = getFundedChoices(_coreDisputeID);\\n // Uses block.timestamp from the current tx when called by the core contract.\\n return (fundedChoices.length == 0 &&\\n block.timestamp - appealPeriodStart >=\\n ((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);\\n }\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (bool) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return vote.voted;\\n }\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n override\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n )\\n {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Round storage round = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]];\\n return (\\n round.winningChoice,\\n round.tied,\\n round.totalVoted,\\n round.totalCommitted,\\n round.votes.length,\\n round.counts[_choice]\\n );\\n }\\n\\n function getNumberOfRounds(uint256 _localDisputeID) external view returns (uint256) {\\n return disputes[_localDisputeID].rounds.length;\\n }\\n\\n function getLocalDisputeRoundID(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID\\n ) external view returns (uint256 localDisputeID, uint256 localRoundID) {\\n localDisputeID = coreDisputeIDToLocal[_coreDisputeID];\\n localRoundID = disputes[localDisputeID].coreRoundIDToLocal[_coreRoundID];\\n }\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view override returns (address account, bytes32 commit, uint256 choice, bool voted) {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n Vote storage vote = dispute.rounds[dispute.coreRoundIDToLocal[_coreRoundID]].votes[_voteID];\\n return (vote.account, vote.commit, vote.choice, vote.voted);\\n }\\n\\n // ************************************* //\\n // * Internal * //\\n // ************************************* //\\n\\n /// @dev Checks that the chosen address satisfies certain conditions for being drawn.\\n /// Note that we don't check the minStake requirement here because of the implicit staking in parent courts.\\n /// minStake is checked directly during staking process however it's possible for the juror to get drawn\\n /// while having < minStake if it is later increased by governance.\\n /// This issue is expected and harmless since we check for insolvency anyway.\\n /// @param _round The round in which the juror is being drawn.\\n /// @param _coreDisputeID ID of the dispute in the core contract.\\n /// @param _juror Chosen address.\\n /// @return result Whether the address passes the check or not.\\n function _postDrawCheck(\\n Round storage _round,\\n uint256 _coreDisputeID,\\n address _juror\\n ) internal view virtual returns (bool result) {\\n (uint96 courtID, , , , ) = core.disputes(_coreDisputeID);\\n uint256 lockedAmountPerJuror = core.getPnkAtStakePerJuror(\\n _coreDisputeID,\\n core.getNumberOfRounds(_coreDisputeID) - 1\\n );\\n (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);\\n result = totalStaked >= totalLocked + lockedAmountPerJuror;\\n\\n if (singleDrawPerJuror) {\\n uint256 localDisputeID = coreDisputeIDToLocal[_coreDisputeID];\\n Dispute storage dispute = disputes[localDisputeID];\\n uint256 localRoundID = dispute.rounds.length - 1;\\n result = result && !alreadyDrawn[localDisputeID][localRoundID][_juror];\\n }\\n }\\n}\\n\",\"keccak256\":\"0x31fa34c8d6071846c7c61e762476fa5bdf6f58670513a426294d49fdb15a7f84\",\"license\":\"MIT\"},\"src/arbitration/dispute-kits/DisputeKitShutter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport {DisputeKitClassicBase, KlerosCore} from \\\"./DisputeKitClassicBase.sol\\\";\\n\\n/// @title DisputeKitShutter\\n/// Dispute kit implementation of the Kleros v1 features including:\\n/// - a drawing system: proportional to staked PNK,\\n/// - a vote aggregation system: plurality,\\n/// - an incentive system: equal split between coherent votes,\\n/// - an appeal system: fund 2 choices only, vote on any choice.\\n/// Added functionality: an Shutter-specific event emitted when a vote is cast.\\ncontract DisputeKitShutter is DisputeKitClassicBase {\\n string public constant override version = \\\"0.11.1\\\";\\n\\n // ************************************* //\\n // * Events * //\\n // ************************************* //\\n\\n /// @dev Emitted when a vote is cast.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror The address of the juror casting the vote commitment.\\n /// @param _commit The commitment hash.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n event CommitCastShutter(uint256 indexed _coreDisputeID, address indexed _juror,bytes32 indexed _commit, bytes32 _identity, bytes _encryptedVote);\\n\\n // ************************************* //\\n // * Constructor * //\\n // ************************************* //\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @dev Initializer.\\n /// @param _governor The governor's address.\\n /// @param _core The KlerosCore arbitrator.\\n function initialize(address _governor, KlerosCore _core) external reinitializer(1) {\\n __DisputeKitClassicBase_initialize(_governor, _core);\\n }\\n\\n function initialize8() external reinitializer(8) {\\n // NOP\\n }\\n\\n // ************************ //\\n // * Governance * //\\n // ************************ //\\n\\n /// @dev Access Control to perform implementation upgrades (UUPS Proxiable)\\n /// Only the governor can perform upgrades (`onlyByGovernor`)\\n function _authorizeUpgrade(address) internal view override onlyByGovernor {\\n // NOP\\n }\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Sets the caller's commit for the specified votes. It can be called multiple times during the\\n /// commit period, each call overrides the commits of the previous one.\\n /// `O(n)` where\\n /// `n` is the number of votes.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core.\\n /// @param _voteIDs The IDs of the votes.\\n /// @param _commit The commitment hash including the justification.\\n /// @param _identity The Shutter identity used for encryption.\\n /// @param _encryptedVote The Shutter encrypted vote.\\n function castCommitShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n bytes32 _commit,\\n bytes32 _identity,\\n bytes calldata _encryptedVote\\n ) external notJumped(_coreDisputeID) {\\n _castCommit(_coreDisputeID, _voteIDs, _commit);\\n emit CommitCastShutter(_coreDisputeID, msg.sender, _commit, _identity, _encryptedVote);\\n }\\n\\n function castVoteShutter(\\n uint256 _coreDisputeID,\\n uint256[] calldata _voteIDs,\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) external {\\n Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];\\n address juror = dispute.rounds[dispute.rounds.length - 1].votes[_voteIDs[0]].account;\\n\\n // _castVote() ensures that all the _voteIDs do belong to `juror`\\n _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification, juror);\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /**\\n * @dev Computes the hash of a vote using ABI encoding\\n * @param _choice The choice being voted for\\n * @param _justification The justification for the vote\\n * @param _salt A random salt for commitment\\n * @return bytes32 The hash of the encoded vote parameters\\n */\\n function hashVote(\\n uint256 _choice,\\n uint256 _salt,\\n string memory _justification\\n ) public pure override returns (bytes32) {\\n bytes32 justificationHash = keccak256(bytes(_justification));\\n return keccak256(abi.encode(_choice, _salt, justificationHash));\\n }\\n}\\n\",\"keccak256\":\"0x8e427fca1f1b67cd97a4b1dc0965684dd86a920323f519fc74ec67b17a05c9de\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitrableV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IArbitrableV2\\n/// @notice Arbitrable interface.\\n/// @dev When developing arbitrable contracts, we need to:\\n/// - Define the action taken when a ruling is received by the contract.\\n/// - Allow dispute creation. For this a function must call arbitrator.createDispute{value: _fee}(_choices,_extraData);\\ninterface IArbitrableV2 {\\n /// @dev To be emitted when a dispute is created to link the correct meta-evidence to the disputeID.\\n /// @param _arbitrator The arbitrator of the contract.\\n /// @param _arbitratorDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _externalDisputeID An identifier created outside Kleros by the protocol requesting arbitration.\\n /// @param _templateId The identifier of the dispute template. Should not be used with _templateUri.\\n /// @param _templateUri The URI to the dispute template. For example on IPFS: starting with '/ipfs/'. Should not be used with _templateId.\\n event DisputeRequest(\\n IArbitratorV2 indexed _arbitrator,\\n uint256 indexed _arbitratorDisputeID,\\n uint256 _externalDisputeID,\\n uint256 _templateId,\\n string _templateUri\\n );\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrator The arbitrator giving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitratorV2 indexed _arbitrator, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev Give a ruling for a dispute.\\n /// Must be called by the arbitrator.\\n /// The purpose of this function is to ensure that the address calling it has the right to rule on the contract.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling Ruling given by the arbitrator.\\n /// Note that 0 is reserved for \\\"Not able/wanting to make a decision\\\".\\n function rule(uint256 _disputeID, uint256 _ruling) external;\\n}\\n\",\"keccak256\":\"0xe841a4fe8ec109ce17dde4457bf1583c8b499109b05887c53a49a3207fc6e80b\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IArbitratorV2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"./IArbitrableV2.sol\\\";\\n\\n/// @title Arbitrator\\n/// Arbitrator interface that implements the new arbitration standard.\\n/// Unlike the ERC-792 this standard is not concerned with appeals, so each arbitrator can implement an appeal system that suits it the most.\\n/// When developing arbitrator contracts we need to:\\n/// - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).\\n/// - Define the functions for cost display (arbitrationCost).\\n/// - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).\\ninterface IArbitratorV2 {\\n /// @dev To be emitted when a dispute is created.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _arbitrable The contract which created the dispute.\\n event DisputeCreation(uint256 indexed _disputeID, IArbitrableV2 indexed _arbitrable);\\n\\n /// @dev To be raised when a ruling is given.\\n /// @param _arbitrable The arbitrable receiving the ruling.\\n /// @param _disputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _ruling The ruling which was given.\\n event Ruling(IArbitrableV2 indexed _arbitrable, uint256 indexed _disputeID, uint256 _ruling);\\n\\n /// @dev To be emitted when an ERC20 token is added or removed as a method to pay fees.\\n /// @param _token The ERC20 token.\\n /// @param _accepted Whether the token is accepted or not.\\n event AcceptedFeeToken(IERC20 indexed _token, bool indexed _accepted);\\n\\n /// @dev To be emitted when the fee for a particular ERC20 token is updated.\\n /// @param _feeToken The ERC20 token.\\n /// @param _rateInEth The new rate of the fee token in ETH.\\n /// @param _rateDecimals The new decimals of the fee token rate.\\n event NewCurrencyRate(IERC20 indexed _feeToken, uint64 _rateInEth, uint8 _rateDecimals);\\n\\n /// @dev Create a dispute and pay for the fees in the native currency, typically ETH.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData\\n ) external payable returns (uint256 disputeID);\\n\\n /// @dev Create a dispute and pay for the fees in a supported ERC20 token.\\n /// Must be called by the arbitrable contract.\\n /// Must pay at least arbitrationCost(_extraData).\\n /// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @param _feeAmount Amount of the ERC20 token used to pay fees.\\n /// @return disputeID The identifier of the dispute created.\\n function createDispute(\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n IERC20 _feeToken,\\n uint256 _feeAmount\\n ) external returns (uint256 disputeID);\\n\\n /// @dev Compute the cost of arbitration denominated in the native currency, typically ETH.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @return cost The arbitration cost in ETH.\\n function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);\\n\\n /// @dev Compute the cost of arbitration denominated in `_feeToken`.\\n /// It is recommended not to increase it often, as it can be highly time and gas consuming for the arbitrated contracts to cope with fee augmentation.\\n /// @param _extraData Additional info about the dispute. We use it to pass the ID of the dispute's court (first 32 bytes), the minimum number of jurors required (next 32 bytes) and the ID of the specific dispute kit (last 32 bytes).\\n /// @param _feeToken The ERC20 token used to pay fees.\\n /// @return cost The arbitration cost in `_feeToken`.\\n function arbitrationCost(bytes calldata _extraData, IERC20 _feeToken) external view returns (uint256 cost);\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _disputeID The ID of the dispute.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _disputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n}\\n\",\"keccak256\":\"0xa4dc6b958197adead238de4246cd04e7389c3dc1b9f968acd10985f8fc5b74cf\",\"license\":\"MIT\"},\"src/arbitration/interfaces/IDisputeKit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"./IArbitratorV2.sol\\\";\\n\\n/// @title IDisputeKit\\n/// An abstraction of the Dispute Kits intended for interfacing with KlerosCore.\\n/// It does not intend to abstract the interactions with the user (such as voting or appeal funding) to allow for implementation-specific parameters.\\ninterface IDisputeKit {\\n // ************************************ //\\n // * Events * //\\n // ************************************ //\\n\\n /// @dev Emitted when casting a vote to provide the justification of juror's choice.\\n /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract.\\n /// @param _juror Address of the juror.\\n /// @param _voteIDs The identifiers of the votes in the dispute.\\n /// @param _choice The choice juror voted for.\\n /// @param _justification Justification of the choice.\\n event VoteCast(\\n uint256 indexed _coreDisputeID,\\n address indexed _juror,\\n uint256[] _voteIDs,\\n uint256 indexed _choice,\\n string _justification\\n );\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Creates a local dispute and maps it to the dispute ID in the Core contract.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _numberOfChoices Number of choices of the dispute\\n /// @param _extraData Additional info about the dispute, for possible use in future dispute kits.\\n /// @param _nbVotes Maximal number of votes this dispute can get. DEPRECATED as we don't need to pass it now. KC handles the count.\\n function createDispute(\\n uint256 _coreDisputeID,\\n uint256 _numberOfChoices,\\n bytes calldata _extraData,\\n uint256 _nbVotes\\n ) external;\\n\\n /// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.\\n /// Note: Access restricted to Kleros Core only.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _nonce Nonce.\\n /// @return drawnAddress The drawn address.\\n function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Gets the current ruling of a specified dispute.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return ruling The current ruling.\\n /// @return tied Whether it's a tie or not.\\n /// @return overridden Whether the ruling was overridden by appeal funding or not.\\n function currentRuling(uint256 _coreDisputeID) external view returns (uint256 ruling, bool tied, bool overridden);\\n\\n /// @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the vote.\\n /// @param _feePerJuror The fee per juror.\\n /// @param _pnkAtStakePerJuror The PNK at stake per juror.\\n /// @return The degree of coherence in basis points.\\n function getDegreeOfCoherence(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID,\\n uint256 _feePerJuror,\\n uint256 _pnkAtStakePerJuror\\n ) external view returns (uint256);\\n\\n /// @dev Gets the number of jurors who are eligible to a reward in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @return The number of coherent jurors.\\n function getCoherentCount(uint256 _coreDisputeID, uint256 _coreRoundID) external view returns (uint256);\\n\\n /// @dev Returns true if all of the jurors have cast their commits for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their commits for the last round.\\n function areCommitsAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if all of the jurors have cast their votes for the last round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether all of the jurors have cast their votes for the last round.\\n function areVotesAllCast(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the appeal funding is finished prematurely (e.g. when losing side didn't fund).\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @return Whether the appeal funding is finished.\\n function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);\\n\\n /// @dev Returns true if the specified voter was active in this round.\\n /// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.\\n /// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.\\n /// @param _voteID The ID of the voter.\\n /// @return Whether the voter was active or not.\\n function isVoteActive(uint256 _coreDisputeID, uint256 _coreRoundID, uint256 _voteID) external view returns (bool);\\n\\n function getRoundInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _choice\\n )\\n external\\n view\\n returns (\\n uint256 winningChoice,\\n bool tied,\\n uint256 totalVoted,\\n uint256 totalCommited,\\n uint256 nbVoters,\\n uint256 choiceCount\\n );\\n\\n function getVoteInfo(\\n uint256 _coreDisputeID,\\n uint256 _coreRoundID,\\n uint256 _voteID\\n ) external view returns (address account, bytes32 commit, uint256 choice, bool voted);\\n}\\n\",\"keccak256\":\"0xa505a76fe06515f6fd2feb1e8a8e7e6d1522038c8ed02438409bc06a29d520ce\",\"license\":\"MIT\"},\"src/arbitration/interfaces/ISortitionModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.24;\\n\\nimport \\\"../../libraries/Constants.sol\\\";\\n\\ninterface ISortitionModule {\\n enum Phase {\\n staking, // Stake sum trees can be updated. Pass after `minStakingTime` passes and there is at least one dispute without jurors.\\n generating, // Waiting for a random number. Pass as soon as it is ready.\\n drawing // Jurors can be drawn. Pass after all disputes have jurors or `maxDrawingTime` passes.\\n }\\n\\n event NewPhase(Phase _phase);\\n\\n function createTree(bytes32 _key, bytes memory _extraData) external;\\n\\n function setStake(\\n address _account,\\n uint96 _courtID,\\n uint256 _newStake,\\n bool _alreadyTransferred\\n ) external returns (uint256 pnkDeposit, uint256 pnkWithdrawal, StakingResult stakingResult);\\n\\n function setJurorInactive(address _account) external;\\n\\n function lockStake(address _account, uint256 _relativeAmount) external;\\n\\n function unlockStake(address _account, uint256 _relativeAmount) external;\\n\\n function penalizeStake(address _account, uint256 _relativeAmount) external;\\n\\n function notifyRandomNumber(uint256 _drawnNumber) external;\\n\\n function draw(bytes32 _court, uint256 _coreDisputeID, uint256 _nonce) external view returns (address);\\n\\n function getJurorBalance(\\n address _juror,\\n uint96 _courtID\\n ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts);\\n\\n function getJurorCourtIDs(address _juror) external view returns (uint96[] memory);\\n\\n function isJurorStaked(address _juror) external view returns (bool);\\n\\n function createDisputeHook(uint256 _disputeID, uint256 _roundID) external;\\n\\n function postDrawHook(uint256 _disputeID, uint256 _roundID) external;\\n}\\n\",\"keccak256\":\"0x18a4ff126bb51e7b5b0e3fbff7cf0dbbcfff7195ad79307e69cdbc9226e63502\",\"license\":\"MIT\"},\"src/libraries/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n// Courts\\nuint96 constant FORKING_COURT = 0; // Index of the forking court.\\nuint96 constant GENERAL_COURT = 1; // Index of the default (general) court.\\n\\n// Dispute Kits\\nuint256 constant NULL_DISPUTE_KIT = 0; // Null pattern to indicate a top-level DK which has no parent. DEPRECATED, as its main purpose was to accommodate forest structure which is not used now.\\nuint256 constant DISPUTE_KIT_CLASSIC = 1; // Index of the default DK. 0 index is skipped.\\n\\n// Sortition Module\\nuint256 constant MAX_STAKE_PATHS = 4; // The maximum number of stake paths a juror can have.\\nuint256 constant DEFAULT_K = 6; // Default number of children per node.\\n\\n// Defaults\\nuint256 constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.\\nIERC20 constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.\\n\\nenum OnError {\\n Revert,\\n Return\\n}\\n\\nenum StakingResult {\\n Successful,\\n StakingTransferFailed,\\n UnstakingTransferFailed,\\n CannotStakeInMoreCourts,\\n CannotStakeInThisCourt,\\n CannotStakeLessThanMinStake,\\n CannotStakeMoreThanMaxStakePerJuror,\\n CannotStakeMoreThanMaxTotalStaked,\\n CannotStakeZeroWhenNoStake\\n}\\n\",\"keccak256\":\"0x5bbda7c304b3681b90feae33be694d04dc129edd60e1d07cb593b895fdc9cd4e\",\"license\":\"MIT\"},\"src/libraries/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/a7a94c77463acea95d979aae1580fb0ddc3b6a1e/contracts/token/ERC20/utils/SafeERC20.sol\\n\\npragma solidity 0.8.24;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/// @title SafeERC20\\n/// @dev Wrappers around ERC20 operations that throw on failure (when the token\\n/// contract returns false). Tokens that return no value (and instead revert or\\n/// throw on failure) are also supported, non-reverting calls are assumed to be\\n/// successful.\\n/// To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n/// which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\nlibrary SafeERC20 {\\n /// @dev Increases the allowance granted to `spender` by the caller.\\n /// @param _token Token to transfer.\\n /// @param _spender The address which will spend the funds.\\n /// @param _addedValue The amount of tokens to increase the allowance by.\\n function increaseAllowance(IERC20 _token, address _spender, uint256 _addedValue) internal returns (bool) {\\n _token.approve(_spender, _token.allowance(address(this), _spender) + _addedValue);\\n return true;\\n }\\n\\n /// @dev Calls transfer() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _to Recipient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransfer(IERC20 _token, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(abi.encodeCall(IERC20.transfer, (_to, _value)));\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n\\n /// @dev Calls transferFrom() without reverting.\\n /// @param _token Token to transfer.\\n /// @param _from Sender address.\\n /// @param _to Recipient address.\\n /// @param _value Amount transferred.\\n /// @return Whether transfer succeeded or not.\\n function safeTransferFrom(IERC20 _token, address _from, address _to, uint256 _value) internal returns (bool) {\\n (bool success, bytes memory data) = address(_token).call(\\n abi.encodeCall(IERC20.transferFrom, (_from, _to, _value))\\n );\\n return (success && (data.length == 0 || abi.decode(data, (bool))));\\n }\\n}\\n\",\"keccak256\":\"0xb3002e6c7cc3607b586e7c931ab290c949c1d166db1f9c48836aa31730170f56\",\"license\":\"MIT\"},\"src/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) \\n\\npragma solidity 0.8.24;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to the proxy constructor\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1))\\n bytes32 private constant _INITIALIZABLE_STORAGE =\\n 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error AlreadyInitialized();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert AlreadyInitialized();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert AlreadyInitialized();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := _INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x560ea64115636ecd6b3596248817125551c038ce1648019fde3cbe02d9759a30\",\"license\":\"MIT\"},\"src/proxy/UUPSProxiable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.24;\\n\\n/// @title UUPS Proxiable\\n/// @author Simon Malatrait \\n/// @dev This contract implements an upgradeability mechanism designed for UUPS proxies.\\n/// @dev Adapted from \\n/// The functions included here can perform an upgrade of an UUPS Proxy, when this contract is set as the implementation behind such a proxy.\\n///\\n/// IMPORTANT: A UUPS proxy requires its upgradeability functions to be in the implementation as opposed to the transparent proxy.\\n/// This means that if the proxy is upgraded to an implementation that does not support this interface, it will no longer be upgradeable.\\n///\\n/// A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n/// reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n/// `UUPSProxiable` with a custom implementation of upgrades.\\n///\\n/// The `_authorizeUpgrade` function must be overridden to include access restriction to the upgrade mechanism.\\nabstract contract UUPSProxiable {\\n // ************************************* //\\n // * Event * //\\n // ************************************* //\\n\\n /// @dev Emitted when the `implementation` has been successfully upgraded.\\n /// @param newImplementation Address of the new implementation the proxy is now forwarding calls to.\\n event Upgraded(address indexed newImplementation);\\n\\n // ************************************* //\\n // * Error * //\\n // ************************************* //\\n\\n /// @dev The call is from an unauthorized context.\\n error UUPSUnauthorizedCallContext();\\n\\n /// @dev The storage `slot` is unsupported as a UUID.\\n error UUPSUnsupportedProxiableUUID(bytes32 slot);\\n\\n /// @dev The `implementation` is not UUPS-compliant\\n error InvalidImplementation(address implementation);\\n\\n /// Failed Delegated call\\n error FailedDelegateCall();\\n\\n // ************************************* //\\n // * Storage * //\\n // ************************************* //\\n\\n /// @dev Storage slot with the address of the current implementation.\\n /// @dev This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n /// @dev validated in the constructor.\\n /// @dev NOTE: bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /// @dev Storage variable of the proxiable contract address.\\n /// @dev It is used to check whether or not the current call is from the proxy.\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n address private immutable __self = address(this);\\n\\n // ************************************* //\\n // * Governance * //\\n // ************************************* //\\n\\n /// @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract.\\n /// @dev Called by {upgradeToAndCall}.\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n\\n // ************************************* //\\n // * State Modifiers * //\\n // ************************************* //\\n\\n /// @dev Upgrade mechanism including access control and UUPS-compliance.\\n /// @param newImplementation Address of the new implementation contract.\\n /// @param data Data used in a delegate call to `newImplementation` if non-empty. This will typically be an encoded\\n /// function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n /// @dev Reverts if the execution is not performed via delegatecall or the execution\\n /// context is not of a proxy with an ERC1967-compliant implementation pointing to self.\\n function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual {\\n _authorizeUpgrade(newImplementation);\\n\\n // Check that the execution is being performed through a delegatecall call and that the execution context is\\n // a proxy contract with an implementation (as defined in ERC1967) pointing to self.\\n if (address(this) == __self || _getImplementation() != __self) {\\n revert UUPSUnauthorizedCallContext();\\n }\\n\\n try UUPSProxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n if (slot != IMPLEMENTATION_SLOT) {\\n revert UUPSUnsupportedProxiableUUID(slot);\\n }\\n // Store the new implementation address to the implementation storage slot.\\n assembly {\\n sstore(IMPLEMENTATION_SLOT, newImplementation)\\n }\\n emit Upgraded(newImplementation);\\n\\n if (data.length != 0) {\\n // The return data is not checked (checking, in case of success, that the newImplementation code is non-empty if the return data is empty) because the authorized callee is trusted.\\n /// @custom:oz-upgrades-unsafe-allow delegatecall\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n revert FailedDelegateCall();\\n }\\n }\\n } catch {\\n revert InvalidImplementation(newImplementation);\\n }\\n }\\n\\n // ************************************* //\\n // * Public Views * //\\n // ************************************* //\\n\\n /// @dev Implementation of the ERC1822 `proxiableUUID` function. This returns the storage slot used by the\\n /// implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n ///\\n /// IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n /// bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n /// function revert if invoked through a proxy. This is guaranteed by the if statement.\\n function proxiableUUID() external view virtual returns (bytes32) {\\n if (address(this) != __self) {\\n // Must not be called through delegatecall\\n revert UUPSUnauthorizedCallContext();\\n }\\n return IMPLEMENTATION_SLOT;\\n }\\n\\n /// @dev Returns the version of the implementation.\\n /// @return Version string.\\n function version() external view virtual returns (string memory);\\n\\n // ************************************* //\\n // * Internal Views * //\\n // ************************************* //\\n\\n function _getImplementation() internal view returns (address implementation) {\\n assembly {\\n implementation := sload(IMPLEMENTATION_SLOT)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa8bb02ed2b2fc165296226762299c2ee3328f2a0c6e90c6fe7029fa5b01d0b60\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000d9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e805468010000000000000000900460ff1615620000765760405162dc149f60e41b815260040160405180910390fd5b80546001600160401b0390811614620000d65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b60805161466f62000103600039600081816119e401528181611a0d0152611c05015261466f6000f3fe6080604052600436106102205760003560e01c8063675926f61161012e578063b6ede540116100ab578063e349ad301161006f578063e349ad30146105bf578063e4c0aaf41461072d578063f2f4eb261461074d578063f32ab9271461076d578063fc6f8f16146107a257600080fd5b8063b6ede54014610697578063ba66fde7146106b7578063be467604146106d7578063d2b8035a146106ed578063da3beb8c1461070d57600080fd5b80637c04034e116100f25780637c04034e146105d55780638e426460146105f55780638f06f11214610615578063a7cc08fe14610635578063b34bfaa81461068157600080fd5b8063675926f61461051257806369f3f041146105325780636d4cd8ea1461057f578063751accd01461059f578063796490f9146105bf57600080fd5b80634011baa4116101bc57806354fd4d501161018057806354fd4d5014610416578063564a565d146104555780635a155ccd146104845780635c92e2f6146104c557806365540b96146104e557600080fd5b80634011baa4146103a6578063485cc955146103bb5780634b2f0ea0146103db5780634f1ef286146103ee57806352d1902d1461040157600080fd5b80630855bbe91461022557806309cc41b81461025a5780630baa64d11461027c5780630c340a241461029c5780631200aabc146102d45780631c3db16d1461030f5780631cc3423a1461034c5780632621b9a21461036c578063362c347914610386575b600080fd5b34801561023157600080fd5b506102456102403660046139f5565b6107c2565b60405190151581526020015b60405180910390f35b34801561026657600080fd5b5061027a610275366004613a9a565b61088a565b005b34801561028857600080fd5b506102456102973660046139f5565b610948565b3480156102a857600080fd5b506000546102bc906001600160a01b031681565b6040516001600160a01b039091168152602001610251565b3480156102e057600080fd5b506103016102ef3660046139f5565b60036020526000908152604090205481565b604051908152602001610251565b34801561031b57600080fd5b5061032f61032a3660046139f5565b6109bf565b604080519384529115156020840152151590820152606001610251565b34801561035857600080fd5b50610301610367366004613bc8565b610b2d565b34801561037857600080fd5b506004546102459060ff1681565b34801561039257600080fd5b506103016103a1366004613c2c565b610b6a565b3480156103b257600080fd5b5061027a610ff0565b3480156103c757600080fd5b5061027a6103d6366004613c69565b6110a1565b61027a6103e9366004613ca2565b611169565b61027a6103fc366004613cc4565b6119d0565b34801561040d57600080fd5b50610301611bf8565b34801561042257600080fd5b5061044860405180604001604052806006815260200165302e31312e3160d01b81525081565b6040516102519190613d63565b34801561046157600080fd5b506104756104703660046139f5565b611c56565b60405161025193929190613d7d565b34801561049057600080fd5b5061024561049f366004613d9e565b600560209081526000938452604080852082529284528284209052825290205460ff1681565b3480156104d157600080fd5b5061027a6104e0366004613dd7565b611d1c565b3480156104f157600080fd5b506105056105003660046139f5565b611d28565b6040516102519190613e29565b34801561051e57600080fd5b5061030161052d366004613e6d565b611dec565b34801561053e57600080fd5b5061055261054d366004613ea8565b611f2f565b604080519687529415156020870152938501929092526060840152608083015260a082015260c001610251565b34801561058b57600080fd5b5061024561059a3660046139f5565b611fe7565b3480156105ab57600080fd5b5061027a6105ba366004613ed4565b61216a565b3480156105cb57600080fd5b5061030161271081565b3480156105e157600080fd5b5061027a6105f0366004613f16565b612236565b34801561060157600080fd5b5061027a610610366004613f9a565b61224d565b34801561062157600080fd5b5061027a610630366004613f16565b612299565b34801561064157600080fd5b50610655610650366004613ea8565b61235f565b604080516001600160a01b03909516855260208501939093529183015215156060820152608001610251565b34801561068d57600080fd5b50610301614e2081565b3480156106a357600080fd5b5061027a6106b2366004613fb7565b612425565b3480156106c357600080fd5b506102456106d2366004613ea8565b6125fa565b3480156106e357600080fd5b5061030161138881565b3480156106f957600080fd5b506102bc610708366004613ca2565b612695565b34801561071957600080fd5b50610301610728366004613ca2565b6129c9565b34801561073957600080fd5b5061027a610748366004613f9a565b612b1c565b34801561075957600080fd5b506001546102bc906001600160a01b031681565b34801561077957600080fd5b5061078d610788366004613ca2565b612b68565b60408051928352602083019190915201610251565b3480156107ae57600080fd5b506103016107bd3660046139f5565b612bba565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa15801561080f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108339190614011565b91509150600061084285611d28565b9050805160001480156108815750612710611388610860858561404b565b61086a919061405e565b6108749190614075565b61087e844261404b565b10155b95945050505050565b6000878152600360205260409020546002805489929081106108ae576108ae614097565b600091825260209091206002600590920201015460ff16156108eb5760405162461bcd60e51b81526004016108e2906140ad565b60405180910390fd5b6108f788888888612be6565b84336001600160a01b0316897fbc1efa6396a4ba1a755245703b38c48fbe744ab5117d9f09f47d26ffc1df999e8787876040516109369392919061410d565b60405180910390a45050505050505050565b60008181526003602052604081205460028054839290811061096c5761096c614097565b6000918252602082206005909102018054909250829061098e9060019061404b565b8154811061099e5761099e614097565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106109eb576109eb614097565b60009182526020822060059091020180549092508290610a0d9060019061404b565b81548110610a1d57610a1d614097565b60009182526020909120600d90910201600381015460ff169450905083610a48578060010154610a4b565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614153565b5090935060049250610ace915050565b816004811115610ae057610ae06141ba565b03610b23576000610af088611d28565b90508051600103610b215780600081518110610b0e57610b0e614097565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdc9190614153565b50935050505080610c2f5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016108e2565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca691906141d0565b15610ce45760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016108e2565b600086815260036020526040812054600280549091908110610d0857610d08614097565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610d3c57610d3c614097565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb91906141eb565b5050600087815260078401602052604090205490915060ff16610e05576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610f4a565b808603610e7a576000868152600683016020526040902054610e28576000610e73565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610e69919061405e565b610e739190614075565b9450610f4a565b600081815260078301602052604090205460ff16610f4a5781600601600083600a01600181548110610eae57610eae614097565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610ee457610ee4614097565b9060005260206000200154815260200190815260200160002054610f089190614227565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610f3d919061405e565b610f479190614075565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610fe4576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60086000610ffc612f1b565b8054909150600160401b900460ff1680611023575080546001600160401b03808416911610155b156110405760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b600160006110ad612f1b565b8054909150600160401b900460ff16806110d4575080546001600160401b03808416911610155b156110f15760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b17815561111c8484612f3f565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b60008281526003602052604090205460028054849290811061118d5761118d614097565b600091825260209091206002600590920201015460ff16156111c15760405162461bcd60e51b81526004016108e2906140ad565b6000838152600360205260408120546002805490919081106111e5576111e5614097565b9060005260206000209060050201905080600101548311156112495760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016108e2565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190614011565b915091508142101580156112cd57508042105b6113125760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016108e2565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611353573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137791906141eb565b5050905086810361138c57612710915061140d565b61271061138861139c868661404b565b6113a6919061405e565b6113b09190614075565b6113ba854261404b565b106114075760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016108e2565b614e2091505b845460009086906114209060019061404b565b8154811061143057611430614097565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561148f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b3919061423a565b6114bd919061404b565b60008a815260078401602052604090205490915060ff16156115215760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016108e2565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561156b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158f919061423a565b905060006127106115a0878461405e565b6115aa9190614075565b6115b49083614227565b60008c8152600686016020526040812054919250908211156116655760008c815260068601602052604090205434906115ed908461404b565b116116125760008c815260068601602052604090205461160d908361404b565b611614565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161165c929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611691908490614227565b909155505060008c8152600686016020526040812080548392906116b6908490614227565b909155505060008c815260068601602052604090205482116117885760008c8152600686016020526040812054600987018054919290916116f8908490614227565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611993578285600901546117a5919061404b565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa1580156117f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181791906141d0565b156118305760028a01805460ff19166001179055611913565b895460038b016000611843876001614227565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016118be91815260200190565b602060405180830381865afa1580156118db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ff919061423a565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016119609392919061428d565b6000604051808303818588803b15801561197957600080fd5b505af115801561198d573d6000803e3d6000fd5b50505050505b803411156119c157336108fc6119a9833461404b565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b6119d982612f75565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480611a5757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611a4b60008051602061461a8339815191525490565b6001600160a01b031614155b15611a755760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611acf575060408051601f3d908101601f19168201909252611acc9181019061423a565b60015b611af757604051630c76093760e01b81526001600160a01b03831660048201526024016108e2565b60008051602061461a8339815191528114611b2857604051632a87526960e21b8152600481018290526024016108e2565b60008051602061461a8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611bf3576000836001600160a01b031683604051611b8f919061432c565b600060405180830381855af49150503d8060008114611bca576040519150601f19603f3d011682016040523d82523d6000602084013e611bcf565b606091505b5050905080611bf1576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611c435760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061461a83398151915290565b60028181548110611c6657600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611c9990614253565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc590614253565b8015611d125780601f10611ce757610100808354040283529160200191611d12565b820191906000526020600020905b815481529060010190602001808311611cf557829003601f168201915b5050505050905083565b611bf184848484612be6565b6000818152600360205260408120546002805460609392908110611d4e57611d4e614097565b60009182526020822060059091020180549092508290611d709060019061404b565b81548110611d8057611d80614097565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611dde57602002820191906000526020600020905b815481526020019060010190808311611dca575b505050505092505050919050565b600085815260036020526040812054600280548392908110611e1057611e10614097565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611e4457611e44614097565b90600052602060002090600d02016000018681548110611e6657611e66614097565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee891906141eb565b506003850154919350915060ff168015611f0c57508183600201541480611f0c5750805b15611f1f57612710945050505050610881565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611f6057611f60614097565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611f9457611f94614097565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061200b5761200b614097565b6000918252602082206005909102018054909250829061202d9060019061404b565b8154811061203d5761203d614097565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612098573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bc9190614153565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213b9190614348565b5050505050915050600081612151578354612157565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146121945760405162461bcd60e51b81526004016108e2906143b2565b6000836001600160a01b031683836040516121af919061432c565b60006040518083038185875af1925050503d80600081146121ec576040519150601f19603f3d011682016040523d82523d6000602084013e6121f1565b606091505b5050905080611bf15760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016108e2565b61224586868686868633612fa2565b505050505050565b6000546001600160a01b031633146122775760405162461bcd60e51b81526004016108e2906143b2565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000868152600360205260408120546002805490919081106122bd576122bd614097565b600091825260208220600590910201805490925082906122df9060019061404b565b815481106122ef576122ef614097565b90600052602060002090600d02016000018787600081811061231357612313614097565b905060200201358154811061232a5761232a614097565b60009182526020909120600490910201546001600160a01b0316905061235588888888888887612fa2565b5050505050505050565b60008060008060006002600360008a8152602001908152602001600020548154811061238d5761238d614097565b600091825260208083208a84526003600590930201918201905260408220548154919350839181106123c1576123c1614097565b90600052602060002090600d020160000187815481106123e3576123e3614097565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b0316331461244f5760405162461bcd60e51b81526004016108e2906143f4565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad2016124da858783614480565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612531573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612555919061423a565b61255f919061404b565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab58108906125e8908a908a908a9061410d565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061261e5761261e614097565b6000918252602080832087845260036005909302019182019052604082205481549193508391811061265257612652614097565b90600052602060002090600d0201600001848154811061267457612674614097565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b031633146126c25760405162461bcd60e51b81526004016108e2906143f4565b6000838152600360205260409020546002805485929081106126e6576126e6614097565b600091825260209091206002600590920201015460ff161561271a5760405162461bcd60e51b81526004016108e2906140ad565b600084815260036020526040812054600280549192918390811061274057612740614097565b60009182526020822060059091020180549092506127609060019061404b565b9050600082600001828154811061277957612779614097565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128029190614540565b60015460405163564a565d60e01b8152600481018c90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612851573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128759190614153565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018f9052604482018e90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156128d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fd9190614540565b985061290a848c8b6136a5565b156129b657604080516080810182526001600160a01b03808c1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff199586161790558c8252600581528582208b83528152858220928252919091529290922080549092161790556129bb565b600098505b505050505050505092915050565b6000828152600360205260408120546002805483929081106129ed576129ed614097565b60009182526020808320868452600360059093020191820190526040822054815491935083918110612a2157612a21614097565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015612a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa491906141eb565b5091509150826004015460001480612ad3575080158015612ad357506000828152600284016020526040902054155b15612ae5576000945050505050612b16565b8015612afa575050600401549150612b169050565b506000908152600290910160205260409020549150612b169050565b92915050565b6000546001600160a01b03163314612b465760405162461bcd60e51b81526004016108e2906143b2565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152600360205260408120546002805491929183908110612b8e57612b8e614097565b906000526020600020906005020160030160008481526020019081526020016000205490509250929050565b600060028281548110612bcf57612bcf614097565b600091825260209091206005909102015492915050565b600084815260036020526040902054600280548692908110612c0a57612c0a614097565b600091825260209091206002600590920201015460ff1615612c3e5760405162461bcd60e51b81526004016108e2906140ad565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cac9190614153565b5090935060019250612cbc915050565b816004811115612cce57612cce6141ba565b14612d2b5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016108e2565b82612d685760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016108e2565b600086815260036020526040812054600280549091908110612d8c57612d8c614097565b60009182526020822060059091020180549092508290612dae9060019061404b565b81548110612dbe57612dbe614097565b90600052602060002090600d0201905060005b86811015612eb4573382898984818110612ded57612ded614097565b9050602002013581548110612e0457612e04614097565b60009182526020909120600490910201546001600160a01b031614612e6b5760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e0060448201526064016108e2565b8582898984818110612e7f57612e7f614097565b9050602002013581548110612e9657612e96614097565b60009182526020909120600160049092020181019190915501612dd1565b5086869050816005016000828254612ecc9190614227565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612f09908b908b908b9061458f565b60405180910390a35050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b612f476139b4565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b03163314612f9f5760405162461bcd60e51b81526004016108e2906143b2565b50565b600087815260036020526040902054600280548992908110612fc657612fc6614097565b600091825260209091206002600590920201015460ff1615612ffa5760405162461bcd60e51b81526004016108e2906140ad565b60015460405163564a565d60e01b8152600481018a90526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015613044573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130689190614153565b5090935060029250613078915050565b81600481111561308a5761308a6141ba565b146130e55760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016108e2565b866131275760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016108e2565b60008981526003602052604081205460028054909190811061314b5761314b614097565b9060005260206000209060050201905080600101548711156131a65760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016108e2565b805460009082906131b99060019061404b565b815481106131c9576131c9614097565b60009182526020822060015460405163564a565d60e01b8152600d90930290910193506001600160a01b03169063564a565d9061320e908f9060040190815260200190565b60a060405180830381865afa15801561322b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324f9190614153565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156132aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ce9190614348565b505050505091505060006132e38b8b8b610b2d565b905060005b8c81101561356a576001600160a01b038916858f8f8481811061330d5761330d614097565b905060200201358154811061332457613324614097565b60009182526020909120600490910201546001600160a01b03161461338b5760405162461bcd60e51b815260206004820152601e60248201527f546865206a75726f722068617320746f206f776e2074686520766f74652e000060448201526064016108e2565b8215806133d2575081858f8f848181106133a7576133a7614097565b90506020020135815481106133be576133be614097565b906000526020600020906004020160010154145b6134525760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016108e2565b848e8e8381811061346557613465614097565b905060200201358154811061347c5761347c614097565b600091825260209091206003600490920201015460ff16156134d55760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016108e2565b8b858f8f848181106134e9576134e9614097565b905060200201358154811061350057613500614097565b60009182526020909120600260049092020101556001858f8f8481811061352957613529614097565b905060200201358154811061354057613540614097565b60009182526020909120600490910201600301805460ff19169115159190911790556001016132e8565b5050506004820180548b9250600090613584908490614227565b90915550506000888152600282016020526040812080548b92906135a9908490614227565b9091555050600181015488036135d857600381015460ff16156135d35760038101805460ff191690555b613651565b60018101546000908152600282016020526040808220548a83529120540361361a57600381015460ff166135d35760038101805460ff19166001179055613651565b60018101546000908152600282016020526040808220548a83529120541115613651576001810188905560038101805460ff191690555b87856001600160a01b03168c7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48d8d8b604051613690939291906145b3565b60405180910390a45050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156136f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137179190614153565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b0390911693506386cdecef9250889190849063fc6f8f1690602401602060405180830381865afa158015613776573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379a919061423a565b6137a4919061404b565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa1580156137e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613809919061423a565b9050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138859190614540565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156138dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390091906145e3565b50509150915082816139129190614227565b60045490831015955060ff16156139a957600087815260036020526040812054600280549192918390811061394957613949614097565b60009182526020822060059091020180549092506139699060019061404b565b90508780156139a35750600083815260056020908152604080832084845282528083206001600160a01b038d16845290915290205460ff16155b97505050505b505050509392505050565b6139bc6139db565b6139d957604051631afcd79f60e31b815260040160405180910390fd5b565b60006139e5612f1b565b54600160401b900460ff16919050565b600060208284031215613a0757600080fd5b5035919050565b60008083601f840112613a2057600080fd5b5081356001600160401b03811115613a3757600080fd5b6020830191508360208260051b8501011115613a5257600080fd5b9250929050565b60008083601f840112613a6b57600080fd5b5081356001600160401b03811115613a8257600080fd5b602083019150836020828501011115613a5257600080fd5b600080600080600080600060a0888a031215613ab557600080fd5b8735965060208801356001600160401b0380821115613ad357600080fd5b613adf8b838c01613a0e565b909850965060408a0135955060608a0135945060808a0135915080821115613b0657600080fd5b50613b138a828b01613a59565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112613b4d57600080fd5b81356001600160401b0380821115613b6757613b67613b26565b604051601f8301601f19908116603f01168101908282118183101715613b8f57613b8f613b26565b81604052838152866020858801011115613ba857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215613bdd57600080fd5b833592506020840135915060408401356001600160401b03811115613c0157600080fd5b613c0d86828701613b3c565b9150509250925092565b6001600160a01b0381168114612f9f57600080fd5b60008060008060808587031215613c4257600080fd5b843593506020850135613c5481613c17565b93969395505050506040820135916060013590565b60008060408385031215613c7c57600080fd5b8235613c8781613c17565b91506020830135613c9781613c17565b809150509250929050565b60008060408385031215613cb557600080fd5b50508035926020909101359150565b60008060408385031215613cd757600080fd5b8235613ce281613c17565b915060208301356001600160401b03811115613cfd57600080fd5b613d0985828601613b3c565b9150509250929050565b60005b83811015613d2e578181015183820152602001613d16565b50506000910152565b60008151808452613d4f816020860160208601613d13565b601f01601f19169290920160200192915050565b602081526000613d766020830184613d37565b9392505050565b83815282151560208201526060604082015260006108816060830184613d37565b600080600060608486031215613db357600080fd5b83359250602084013591506040840135613dcc81613c17565b809150509250925092565b60008060008060608587031215613ded57600080fd5b8435935060208501356001600160401b03811115613e0a57600080fd5b613e1687828801613a0e565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613e6157835183529284019291840191600101613e45565b50909695505050505050565b600080600080600060a08688031215613e8557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613ebd57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613ee957600080fd5b8335613ef481613c17565b92506020840135915060408401356001600160401b03811115613c0157600080fd5b60008060008060008060a08789031215613f2f57600080fd5b8635955060208701356001600160401b0380821115613f4d57600080fd5b613f598a838b01613a0e565b909750955060408901359450606089013593506080890135915080821115613f8057600080fd5b50613f8d89828a01613b3c565b9150509295509295509295565b600060208284031215613fac57600080fd5b8135613d7681613c17565b600080600080600060808688031215613fcf57600080fd5b853594506020860135935060408601356001600160401b03811115613ff357600080fd5b613fff88828901613a59565b96999598509660600135949350505050565b6000806040838503121561402457600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b81810381811115612b1657612b16614035565b8082028115828204841417612b1657612b16614035565b60008261409257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8381526040602082015260006108816040830184866140e4565b80516001600160601b038116811461413e57600080fd5b919050565b8051801515811461413e57600080fd5b600080600080600060a0868803121561416b57600080fd5b61417486614127565b9450602086015161418481613c17565b60408701519094506005811061419957600080fd5b92506141a760608701614143565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156141e257600080fd5b613d7682614143565b60008060006060848603121561420057600080fd5b8351925061421060208501614143565b915061421e60408501614143565b90509250925092565b80820180821115612b1657612b16614035565b60006020828403121561424c57600080fd5b5051919050565b600181811c9082168061426757607f821691505b60208210810361428757634e487b7160e01b600052602260045260246000fd5b50919050565b8381526000602084602084015260606040840152600084546142ae81614253565b80606087015260806001808416600081146142d057600181146142ec5761431c565b60ff19851660808a0152608084151560051b8a0101955061431c565b89600052602060002060005b858110156143135781548b82018601529083019088016142f8565b8a016080019650505b50939a9950505050505050505050565b6000825161433e818460208701613d13565b9190910192915050565b600080600080600080600060e0888a03121561436357600080fd5b61436c88614127565b965061437a60208901614143565b955060408801519450606088015193506080880151925060a088015191506143a460c08901614143565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611bf3576000816000526020600020601f850160051c810160208610156144615750805b601f850160051c820191505b818110156122455782815560010161446d565b6001600160401b0383111561449757614497613b26565b6144ab836144a58354614253565b83614438565b6000601f8411600181146144df57600085156144c75750838201355b600019600387901b1c1916600186901b178355614539565b600083815260209020601f19861690835b8281101561451057868501358255602094850194600190920191016144f0565b508682101561452d5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561455257600080fd5b8151613d7681613c17565b81835260006001600160fb1b0383111561457657600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006145a360408301858761455d565b9050826020830152949350505050565b6040815260006145c760408301858761455d565b82810360208401526145d98185613d37565b9695505050505050565b600080600080608085870312156145f957600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220153f069dad597f5fd2a9ff2187cde96730a89b8658626e058a78cf4db9a2e35064736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106102205760003560e01c8063675926f61161012e578063b6ede540116100ab578063e349ad301161006f578063e349ad30146105bf578063e4c0aaf41461072d578063f2f4eb261461074d578063f32ab9271461076d578063fc6f8f16146107a257600080fd5b8063b6ede54014610697578063ba66fde7146106b7578063be467604146106d7578063d2b8035a146106ed578063da3beb8c1461070d57600080fd5b80637c04034e116100f25780637c04034e146105d55780638e426460146105f55780638f06f11214610615578063a7cc08fe14610635578063b34bfaa81461068157600080fd5b8063675926f61461051257806369f3f041146105325780636d4cd8ea1461057f578063751accd01461059f578063796490f9146105bf57600080fd5b80634011baa4116101bc57806354fd4d501161018057806354fd4d5014610416578063564a565d146104555780635a155ccd146104845780635c92e2f6146104c557806365540b96146104e557600080fd5b80634011baa4146103a6578063485cc955146103bb5780634b2f0ea0146103db5780634f1ef286146103ee57806352d1902d1461040157600080fd5b80630855bbe91461022557806309cc41b81461025a5780630baa64d11461027c5780630c340a241461029c5780631200aabc146102d45780631c3db16d1461030f5780631cc3423a1461034c5780632621b9a21461036c578063362c347914610386575b600080fd5b34801561023157600080fd5b506102456102403660046139f5565b6107c2565b60405190151581526020015b60405180910390f35b34801561026657600080fd5b5061027a610275366004613a9a565b61088a565b005b34801561028857600080fd5b506102456102973660046139f5565b610948565b3480156102a857600080fd5b506000546102bc906001600160a01b031681565b6040516001600160a01b039091168152602001610251565b3480156102e057600080fd5b506103016102ef3660046139f5565b60036020526000908152604090205481565b604051908152602001610251565b34801561031b57600080fd5b5061032f61032a3660046139f5565b6109bf565b604080519384529115156020840152151590820152606001610251565b34801561035857600080fd5b50610301610367366004613bc8565b610b2d565b34801561037857600080fd5b506004546102459060ff1681565b34801561039257600080fd5b506103016103a1366004613c2c565b610b6a565b3480156103b257600080fd5b5061027a610ff0565b3480156103c757600080fd5b5061027a6103d6366004613c69565b6110a1565b61027a6103e9366004613ca2565b611169565b61027a6103fc366004613cc4565b6119d0565b34801561040d57600080fd5b50610301611bf8565b34801561042257600080fd5b5061044860405180604001604052806006815260200165302e31312e3160d01b81525081565b6040516102519190613d63565b34801561046157600080fd5b506104756104703660046139f5565b611c56565b60405161025193929190613d7d565b34801561049057600080fd5b5061024561049f366004613d9e565b600560209081526000938452604080852082529284528284209052825290205460ff1681565b3480156104d157600080fd5b5061027a6104e0366004613dd7565b611d1c565b3480156104f157600080fd5b506105056105003660046139f5565b611d28565b6040516102519190613e29565b34801561051e57600080fd5b5061030161052d366004613e6d565b611dec565b34801561053e57600080fd5b5061055261054d366004613ea8565b611f2f565b604080519687529415156020870152938501929092526060840152608083015260a082015260c001610251565b34801561058b57600080fd5b5061024561059a3660046139f5565b611fe7565b3480156105ab57600080fd5b5061027a6105ba366004613ed4565b61216a565b3480156105cb57600080fd5b5061030161271081565b3480156105e157600080fd5b5061027a6105f0366004613f16565b612236565b34801561060157600080fd5b5061027a610610366004613f9a565b61224d565b34801561062157600080fd5b5061027a610630366004613f16565b612299565b34801561064157600080fd5b50610655610650366004613ea8565b61235f565b604080516001600160a01b03909516855260208501939093529183015215156060820152608001610251565b34801561068d57600080fd5b50610301614e2081565b3480156106a357600080fd5b5061027a6106b2366004613fb7565b612425565b3480156106c357600080fd5b506102456106d2366004613ea8565b6125fa565b3480156106e357600080fd5b5061030161138881565b3480156106f957600080fd5b506102bc610708366004613ca2565b612695565b34801561071957600080fd5b50610301610728366004613ca2565b6129c9565b34801561073957600080fd5b5061027a610748366004613f9a565b612b1c565b34801561075957600080fd5b506001546102bc906001600160a01b031681565b34801561077957600080fd5b5061078d610788366004613ca2565b612b68565b60408051928352602083019190915201610251565b3480156107ae57600080fd5b506103016107bd3660046139f5565b612bba565b60015460405163afe15cfb60e01b815260048101839052600091829182916001600160a01b03169063afe15cfb906024016040805180830381865afa15801561080f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108339190614011565b91509150600061084285611d28565b9050805160001480156108815750612710611388610860858561404b565b61086a919061405e565b6108749190614075565b61087e844261404b565b10155b95945050505050565b6000878152600360205260409020546002805489929081106108ae576108ae614097565b600091825260209091206002600590920201015460ff16156108eb5760405162461bcd60e51b81526004016108e2906140ad565b60405180910390fd5b6108f788888888612be6565b84336001600160a01b0316897fbc1efa6396a4ba1a755245703b38c48fbe744ab5117d9f09f47d26ffc1df999e8787876040516109369392919061410d565b60405180910390a45050505050505050565b60008181526003602052604081205460028054839290811061096c5761096c614097565b6000918252602082206005909102018054909250829061098e9060019061404b565b8154811061099e5761099e614097565b60009182526020909120600d90910201805460059091015414949350505050565b60008060008060026003600087815260200190815260200160002054815481106109eb576109eb614097565b60009182526020822060059091020180549092508290610a0d9060019061404b565b81548110610a1d57610a1d614097565b60009182526020909120600d90910201600381015460ff169450905083610a48578060010154610a4b565b60005b60015460405163564a565d60e01b8152600481018990529196506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610a9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abe9190614153565b5090935060049250610ace915050565b816004811115610ae057610ae06141ba565b03610b23576000610af088611d28565b90508051600103610b215780600081518110610b0e57610b0e614097565b6020026020010151965060009550600194505b505b5050509193909250565b8051602091820120604080518084019590955284810193909352606080850191909152825180850390910181526080909301909152815191012090565b60015460405163564a565d60e01b81526004810186905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015610bb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdc9190614153565b50935050505080610c2f5760405162461bcd60e51b815260206004820152601b60248201527f446973707574652073686f756c64206265207265736f6c7665642e000000000060448201526064016108e2565b600160009054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca691906141d0565b15610ce45760405162461bcd60e51b815260206004820152600e60248201526d10dbdc99481a5cc81c185d5cd95960921b60448201526064016108e2565b600086815260036020526040812054600280549091908110610d0857610d08614097565b60009182526020808320888452600360059093020191820190526040822054815491935083918110610d3c57610d3c614097565b600091825260208220600154604051631c3db16d60e01b8152600481018d9052600d9390930290910193506001600160a01b031690631c3db16d90602401606060405180830381865afa158015610d97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbb91906141eb565b5050600087815260078401602052604090205490915060ff16610e05576001600160a01b038816600090815260088301602090815260408083208984529091529020549450610f4a565b808603610e7a576000868152600683016020526040902054610e28576000610e73565b600086815260068301602090815260408083205460098601546001600160a01b038d1685526008870184528285208b8652909352922054610e69919061405e565b610e739190614075565b9450610f4a565b600081815260078301602052604090205460ff16610f4a5781600601600083600a01600181548110610eae57610eae614097565b906000526020600020015481526020019081526020016000205482600601600084600a01600081548110610ee457610ee4614097565b9060005260206000200154815260200190815260200160002054610f089190614227565b60098301546001600160a01b038a16600090815260088501602090815260408083208b8452909152902054610f3d919061405e565b610f479190614075565b94505b6001600160a01b038816600090815260088301602090815260408083208984529091528120558415610fe4576040516001600160a01b0389169086156108fc029087906000818181858888f15050604080518a8152602081018a90526001600160a01b038d1694508b93508d92507f54b3cab3cb5c4aca3209db1151caff092e878011202e43a36782d4ebe0b963ae910160405180910390a45b50505050949350505050565b60086000610ffc612f1b565b8054909150600160401b900460ff1680611023575080546001600160401b03808416911610155b156110405760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b038316908117600160401b1760ff60401b191682556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050565b600160006110ad612f1b565b8054909150600160401b900460ff16806110d4575080546001600160401b03808416911610155b156110f15760405162dc149f60e41b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b17815561111c8484612f3f565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b60008281526003602052604090205460028054849290811061118d5761118d614097565b600091825260209091206002600590920201015460ff16156111c15760405162461bcd60e51b81526004016108e2906140ad565b6000838152600360205260408120546002805490919081106111e5576111e5614097565b9060005260206000209060050201905080600101548311156112495760405162461bcd60e51b815260206004820181905260248201527f5468657265206973206e6f20737563682072756c696e6720746f2066756e642e60448201526064016108e2565b60015460405163afe15cfb60e01b81526004810186905260009182916001600160a01b039091169063afe15cfb906024016040805180830381865afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190614011565b915091508142101580156112cd57508042105b6113125760405162461bcd60e51b815260206004820152601660248201527520b83832b0b6103832b934b7b21034b99037bb32b91760511b60448201526064016108e2565b604051631c3db16d60e01b81526004810187905260009081903090631c3db16d90602401606060405180830381865afa158015611353573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137791906141eb565b5050905086810361138c57612710915061140d565b61271061138861139c868661404b565b6113a6919061405e565b6113b09190614075565b6113ba854261404b565b106114075760405162461bcd60e51b815260206004820152601f60248201527f41707065616c20706572696f64206973206f76657220666f72206c6f7365720060448201526064016108e2565b614e2091505b845460009086906114209060019061404b565b8154811061143057611430614097565b60009182526020822060018054604051637e37c78b60e11b8152600481018f9052600d949094029092019450916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa15801561148f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b3919061423a565b6114bd919061404b565b60008a815260078401602052604090205490915060ff16156115215760405162461bcd60e51b815260206004820152601b60248201527f41707065616c2066656520697320616c726561647920706169642e000000000060448201526064016108e2565b600154604051632cf6413f60e11b8152600481018c90526000916001600160a01b0316906359ec827e90602401602060405180830381865afa15801561156b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158f919061423a565b905060006127106115a0878461405e565b6115aa9190614075565b6115b49083614227565b60008c8152600686016020526040812054919250908211156116655760008c815260068601602052604090205434906115ed908461404b565b116116125760008c815260068601602052604090205461160d908361404b565b611614565b345b9050336001600160a01b0316848e7fcae597f39a3ad75c2e10d46b031f023c5c2babcd58ca0491b122acda3968d4c08f8560405161165c929190918252602082015260400190565b60405180910390a45b33600090815260088601602090815260408083208f845290915281208054839290611691908490614227565b909155505060008c8152600686016020526040812080548392906116b6908490614227565b909155505060008c815260068601602052604090205482116117885760008c8152600686016020526040812054600987018054919290916116f8908490614227565b9250508190555084600a018c908060018154018082558091505060019003906000526020600020016000909190919091505560018560070160008e815260200190815260200160002060006101000a81548160ff0219169083151502179055508b848e7fed764996238e4c1c873ae3af7ae2f00f1f6f4f10b9ac7d4bbea4a764c5dea00960405160405180910390a45b600a85015460011015611993578285600901546117a5919061404b565b60098601556001546040516319b8152960e01b8152600481018f90526001600160a01b03909116906319b8152990602401602060405180830381865afa1580156117f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181791906141d0565b156118305760028a01805460ff19166001179055611913565b895460038b016000611843876001614227565b81526020019081526020016000208190555060008a6000016001816001815401808255809150500390600052602060002090600d02019050600160009054906101000a90046001600160a01b03166001600160a01b031663c71f42538f6040518263ffffffff1660e01b81526004016118be91815260200190565b602060405180830381865afa1580156118db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ff919061423a565b600b820155600301805460ff191660011790555b600160009054906101000a90046001600160a01b03166001600160a01b031663c3569902848f8d600101548e6004016040518563ffffffff1660e01b81526004016119609392919061428d565b6000604051808303818588803b15801561197957600080fd5b505af115801561198d573d6000803e3d6000fd5b50505050505b803411156119c157336108fc6119a9833461404b565b6040518115909202916000818181858888f150505050505b50505050505050505050505050565b6119d982612f75565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480611a5757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611a4b60008051602061461a8339815191525490565b6001600160a01b031614155b15611a755760405163703e46dd60e11b815260040160405180910390fd5b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611acf575060408051601f3d908101601f19168201909252611acc9181019061423a565b60015b611af757604051630c76093760e01b81526001600160a01b03831660048201526024016108e2565b60008051602061461a8339815191528114611b2857604051632a87526960e21b8152600481018290526024016108e2565b60008051602061461a8339815191528390556040516001600160a01b038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2815115611bf3576000836001600160a01b031683604051611b8f919061432c565b600060405180830381855af49150503d8060008114611bca576040519150601f19603f3d011682016040523d82523d6000602084013e611bcf565b606091505b5050905080611bf1576040516339b21b5d60e11b815260040160405180910390fd5b505b505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611c435760405163703e46dd60e11b815260040160405180910390fd5b5060008051602061461a83398151915290565b60028181548110611c6657600080fd5b600091825260209091206005909102016001810154600282015460048301805492945060ff9091169291611c9990614253565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc590614253565b8015611d125780601f10611ce757610100808354040283529160200191611d12565b820191906000526020600020905b815481529060010190602001808311611cf557829003601f168201915b5050505050905083565b611bf184848484612be6565b6000818152600360205260408120546002805460609392908110611d4e57611d4e614097565b60009182526020822060059091020180549092508290611d709060019061404b565b81548110611d8057611d80614097565b90600052602060002090600d0201905080600a01805480602002602001604051908101604052809291908181526020018280548015611dde57602002820191906000526020600020905b815481526020019060010190808311611dca575b505050505092505050919050565b600085815260036020526040812054600280548392908110611e1057611e10614097565b60009182526020808320898452600360059093020191820190526040822054815491935083918110611e4457611e44614097565b90600052602060002090600d02016000018681548110611e6657611e66614097565b600091825260208220600154604051631c3db16d60e01b815260048082018e905293909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015611ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee891906141eb565b506003850154919350915060ff168015611f0c57508183600201541480611f0c5750805b15611f1f57612710945050505050610881565b5060009998505050505050505050565b60008060008060008060006002600360008c81526020019081526020016000205481548110611f6057611f60614097565b600091825260208083208c8452600360059093020191820190526040822054815491935083918110611f9457611f94614097565b600091825260208083206001600d909302019182015460038301546004840154600585015485549f87526002909501909352604090942054909f60ff9094169e50909c50909a9950975095505050505050565b60008181526003602052604081205460028054839290811061200b5761200b614097565b6000918252602082206005909102018054909250829061202d9060019061404b565b8154811061203d5761203d614097565b60009182526020822060015460405163564a565d60e01b815260048101899052600d9390930290910193506001600160a01b03169063564a565d9060240160a060405180830381865afa158015612098573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bc9190614153565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa158015612117573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213b9190614348565b5050505050915050600081612151578354612157565b83600501545b6004909401549093149695505050505050565b6000546001600160a01b031633146121945760405162461bcd60e51b81526004016108e2906143b2565b6000836001600160a01b031683836040516121af919061432c565b60006040518083038185875af1925050503d80600081146121ec576040519150601f19603f3d011682016040523d82523d6000602084013e6121f1565b606091505b5050905080611bf15760405162461bcd60e51b8152602060048201526011602482015270155b9cdd58d8d95cdcd99d5b0818d85b1b607a1b60448201526064016108e2565b61224586868686868633612fa2565b505050505050565b6000546001600160a01b031633146122775760405162461bcd60e51b81526004016108e2906143b2565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000868152600360205260408120546002805490919081106122bd576122bd614097565b600091825260208220600590910201805490925082906122df9060019061404b565b815481106122ef576122ef614097565b90600052602060002090600d02016000018787600081811061231357612313614097565b905060200201358154811061232a5761232a614097565b60009182526020909120600490910201546001600160a01b0316905061235588888888888887612fa2565b5050505050505050565b60008060008060006002600360008a8152602001908152602001600020548154811061238d5761238d614097565b600091825260208083208a84526003600590930201918201905260408220548154919350839181106123c1576123c1614097565b90600052602060002090600d020160000187815481106123e3576123e3614097565b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169c909b5091995060ff16975095505050505050565b6001546001600160a01b0316331461244f5760405162461bcd60e51b81526004016108e2906143f4565b60028054600181018255600091909152600581027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf81018690557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8101907f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad2016124da858783614480565b50805460018054604051637e37c78b60e11b8152600481018b9052600385019260009290916001600160a01b039091169063fc6f8f1690602401602060405180830381865afa158015612531573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612555919061423a565b61255f919061404b565b81526020808201929092526040908101600090812093909355835460018181018655858552838520600b600d909302019182018890556003808301805460ff19169092179091558b855290925291829020849055905188907fd3106f74c2d30a4b9230e756a3e78bde53865d40f6af4c479bb010ebaab58108906125e8908a908a908a9061410d565b60405180910390a25050505050505050565b60008381526003602052604081205460028054839290811061261e5761261e614097565b6000918252602080832087845260036005909302019182019052604082205481549193508391811061265257612652614097565b90600052602060002090600d0201600001848154811061267457612674614097565b600091825260209091206004909102016003015460ff169695505050505050565b6001546000906001600160a01b031633146126c25760405162461bcd60e51b81526004016108e2906143f4565b6000838152600360205260409020546002805485929081106126e6576126e6614097565b600091825260209091206002600590920201015460ff161561271a5760405162461bcd60e51b81526004016108e2906140ad565b600084815260036020526040812054600280549192918390811061274057612740614097565b60009182526020822060059091020180549092506127609060019061404b565b9050600082600001828154811061277957612779614097565b90600052602060002090600d020190506000600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128029190614540565b60015460405163564a565d60e01b8152600481018c90529192506000916001600160a01b039091169063564a565d9060240160a060405180830381865afa158015612851573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128759190614153565b5050604051632638506b60e11b81526001600160601b03841660048201819052602482018f9052604482018e90529394506001600160a01b0386169250634c70a0d69150606401602060405180830381865afa1580156128d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fd9190614540565b985061290a848c8b6136a5565b156129b657604080516080810182526001600160a01b03808c1680835260006020808501828152858701838152606087018481528c5460018181018f558e8752858720995160049092029099018054919098166001600160a01b0319909116178755915186880155516002860155516003909401805494151560ff199586161790558c8252600581528582208b83528152858220928252919091529290922080549092161790556129bb565b600098505b505050505050505092915050565b6000828152600360205260408120546002805483929081106129ed576129ed614097565b60009182526020808320868452600360059093020191820190526040822054815491935083918110612a2157612a21614097565b600091825260208220600154604051631c3db16d60e01b8152600481018a9052600d93909302909101935082916001600160a01b0390911690631c3db16d90602401606060405180830381865afa158015612a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa491906141eb565b5091509150826004015460001480612ad3575080158015612ad357506000828152600284016020526040902054155b15612ae5576000945050505050612b16565b8015612afa575050600401549150612b169050565b506000908152600290910160205260409020549150612b169050565b92915050565b6000546001600160a01b03163314612b465760405162461bcd60e51b81526004016108e2906143b2565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000828152600360205260408120546002805491929183908110612b8e57612b8e614097565b906000526020600020906005020160030160008481526020019081526020016000205490509250929050565b600060028281548110612bcf57612bcf614097565b600091825260209091206005909102015492915050565b600084815260036020526040902054600280548692908110612c0a57612c0a614097565b600091825260209091206002600590920201015460ff1615612c3e5760405162461bcd60e51b81526004016108e2906140ad565b60015460405163564a565d60e01b8152600481018790526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015612c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cac9190614153565b5090935060019250612cbc915050565b816004811115612cce57612cce6141ba565b14612d2b5760405162461bcd60e51b815260206004820152602760248201527f54686520646973707574652073686f756c6420626520696e20436f6d6d6974206044820152663832b934b7b21760c91b60648201526084016108e2565b82612d685760405162461bcd60e51b815260206004820152600d60248201526c22b6b83a3c9031b7b6b6b4ba1760991b60448201526064016108e2565b600086815260036020526040812054600280549091908110612d8c57612d8c614097565b60009182526020822060059091020180549092508290612dae9060019061404b565b81548110612dbe57612dbe614097565b90600052602060002090600d0201905060005b86811015612eb4573382898984818110612ded57612ded614097565b9050602002013581548110612e0457612e04614097565b60009182526020909120600490910201546001600160a01b031614612e6b5760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c65722068617320746f206f776e2074686520766f74652e0060448201526064016108e2565b8582898984818110612e7f57612e7f614097565b9050602002013581548110612e9657612e96614097565b60009182526020909120600160049092020181019190915501612dd1565b5086869050816005016000828254612ecc9190614227565b9091555050604051339089907f05cc2f1c94966f1c961b410a50f3d3ffb64501346753a258177097ea23707f0890612f09908b908b908b9061458f565b60405180910390a35050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e90565b612f476139b4565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b6000546001600160a01b03163314612f9f5760405162461bcd60e51b81526004016108e2906143b2565b50565b600087815260036020526040902054600280548992908110612fc657612fc6614097565b600091825260209091206002600590920201015460ff1615612ffa5760405162461bcd60e51b81526004016108e2906140ad565b60015460405163564a565d60e01b8152600481018a90526000916001600160a01b03169063564a565d9060240160a060405180830381865afa158015613044573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130689190614153565b5090935060029250613078915050565b81600481111561308a5761308a6141ba565b146130e55760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652073686f756c6420626520696e20566f74652070656044820152643934b7b21760d91b60648201526084016108e2565b866131275760405162461bcd60e51b8152602060048201526012602482015271139bc81d9bdd195251081c1c9bdd9a59195960721b60448201526064016108e2565b60008981526003602052604081205460028054909190811061314b5761314b614097565b9060005260206000209060050201905080600101548711156131a65760405162461bcd60e51b815260206004820152601460248201527343686f696365206f7574206f6620626f756e647360601b60448201526064016108e2565b805460009082906131b99060019061404b565b815481106131c9576131c9614097565b60009182526020822060015460405163564a565d60e01b8152600d90930290910193506001600160a01b03169063564a565d9061320e908f9060040190815260200190565b60a060405180830381865afa15801561322b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324f9190614153565b5050600154604051630fad06e960e11b81526001600160601b03851660048201529394506000936001600160a01b039091169250631f5a0dd2915060240160e060405180830381865afa1580156132aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ce9190614348565b505050505091505060006132e38b8b8b610b2d565b905060005b8c81101561356a576001600160a01b038916858f8f8481811061330d5761330d614097565b905060200201358154811061332457613324614097565b60009182526020909120600490910201546001600160a01b03161461338b5760405162461bcd60e51b815260206004820152601e60248201527f546865206a75726f722068617320746f206f776e2074686520766f74652e000060448201526064016108e2565b8215806133d2575081858f8f848181106133a7576133a7614097565b90506020020135815481106133be576133be614097565b906000526020600020906004020160010154145b6134525760405162461bcd60e51b8152602060048201526044602482018190527f54686520766f74652068617368206d757374206d617463682074686520636f6d908201527f6d69746d656e7420696e20636f7572747320776974682068696464656e20766f6064820152633a32b99760e11b608482015260a4016108e2565b848e8e8381811061346557613465614097565b905060200201358154811061347c5761347c614097565b600091825260209091206003600490920201015460ff16156134d55760405162461bcd60e51b81526020600482015260126024820152712b37ba329030b63932b0b23c9031b0b9ba1760711b60448201526064016108e2565b8b858f8f848181106134e9576134e9614097565b905060200201358154811061350057613500614097565b60009182526020909120600260049092020101556001858f8f8481811061352957613529614097565b905060200201358154811061354057613540614097565b60009182526020909120600490910201600301805460ff19169115159190911790556001016132e8565b5050506004820180548b9250600090613584908490614227565b90915550506000888152600282016020526040812080548b92906135a9908490614227565b9091555050600181015488036135d857600381015460ff16156135d35760038101805460ff191690555b613651565b60018101546000908152600282016020526040808220548a83529120540361361a57600381015460ff166135d35760038101805460ff19166001179055613651565b60018101546000908152600282016020526040808220548a83529120541115613651576001810188905560038101805460ff191690555b87856001600160a01b03168c7fa000893c71384499023d2d7b21234f7b9e80c78e0330f357dcd667ff578bd3a48d8d8b604051613690939291906145b3565b60405180910390a45050505050505050505050565b60015460405163564a565d60e01b81526004810184905260009182916001600160a01b039091169063564a565d9060240160a060405180830381865afa1580156136f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137179190614153565b505060018054604051637e37c78b60e11b8152600481018a90529495506000946001600160a01b0390911693506386cdecef9250889190849063fc6f8f1690602401602060405180830381865afa158015613776573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379a919061423a565b6137a4919061404b565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa1580156137e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613809919061423a565b9050600080600160009054906101000a90046001600160a01b03166001600160a01b0316632e1daf2f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138859190614540565b604051631a383be960e31b81526001600160a01b0388811660048301526001600160601b0387166024830152919091169063d1c1df4890604401608060405180830381865afa1580156138dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390091906145e3565b50509150915082816139129190614227565b60045490831015955060ff16156139a957600087815260036020526040812054600280549192918390811061394957613949614097565b60009182526020822060059091020180549092506139699060019061404b565b90508780156139a35750600083815260056020908152604080832084845282528083206001600160a01b038d16845290915290205460ff16155b97505050505b505050509392505050565b6139bc6139db565b6139d957604051631afcd79f60e31b815260040160405180910390fd5b565b60006139e5612f1b565b54600160401b900460ff16919050565b600060208284031215613a0757600080fd5b5035919050565b60008083601f840112613a2057600080fd5b5081356001600160401b03811115613a3757600080fd5b6020830191508360208260051b8501011115613a5257600080fd5b9250929050565b60008083601f840112613a6b57600080fd5b5081356001600160401b03811115613a8257600080fd5b602083019150836020828501011115613a5257600080fd5b600080600080600080600060a0888a031215613ab557600080fd5b8735965060208801356001600160401b0380821115613ad357600080fd5b613adf8b838c01613a0e565b909850965060408a0135955060608a0135945060808a0135915080821115613b0657600080fd5b50613b138a828b01613a59565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112613b4d57600080fd5b81356001600160401b0380821115613b6757613b67613b26565b604051601f8301601f19908116603f01168101908282118183101715613b8f57613b8f613b26565b81604052838152866020858801011115613ba857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215613bdd57600080fd5b833592506020840135915060408401356001600160401b03811115613c0157600080fd5b613c0d86828701613b3c565b9150509250925092565b6001600160a01b0381168114612f9f57600080fd5b60008060008060808587031215613c4257600080fd5b843593506020850135613c5481613c17565b93969395505050506040820135916060013590565b60008060408385031215613c7c57600080fd5b8235613c8781613c17565b91506020830135613c9781613c17565b809150509250929050565b60008060408385031215613cb557600080fd5b50508035926020909101359150565b60008060408385031215613cd757600080fd5b8235613ce281613c17565b915060208301356001600160401b03811115613cfd57600080fd5b613d0985828601613b3c565b9150509250929050565b60005b83811015613d2e578181015183820152602001613d16565b50506000910152565b60008151808452613d4f816020860160208601613d13565b601f01601f19169290920160200192915050565b602081526000613d766020830184613d37565b9392505050565b83815282151560208201526060604082015260006108816060830184613d37565b600080600060608486031215613db357600080fd5b83359250602084013591506040840135613dcc81613c17565b809150509250925092565b60008060008060608587031215613ded57600080fd5b8435935060208501356001600160401b03811115613e0a57600080fd5b613e1687828801613a0e565b9598909750949560400135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015613e6157835183529284019291840191600101613e45565b50909695505050505050565b600080600080600060a08688031215613e8557600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600060608486031215613ebd57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215613ee957600080fd5b8335613ef481613c17565b92506020840135915060408401356001600160401b03811115613c0157600080fd5b60008060008060008060a08789031215613f2f57600080fd5b8635955060208701356001600160401b0380821115613f4d57600080fd5b613f598a838b01613a0e565b909750955060408901359450606089013593506080890135915080821115613f8057600080fd5b50613f8d89828a01613b3c565b9150509295509295509295565b600060208284031215613fac57600080fd5b8135613d7681613c17565b600080600080600060808688031215613fcf57600080fd5b853594506020860135935060408601356001600160401b03811115613ff357600080fd5b613fff88828901613a59565b96999598509660600135949350505050565b6000806040838503121561402457600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b81810381811115612b1657612b16614035565b8082028115828204841417612b1657612b16614035565b60008261409257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252601e908201527f44697370757465206a756d70656420746f206120706172656e7420444b210000604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8381526040602082015260006108816040830184866140e4565b80516001600160601b038116811461413e57600080fd5b919050565b8051801515811461413e57600080fd5b600080600080600060a0868803121561416b57600080fd5b61417486614127565b9450602086015161418481613c17565b60408701519094506005811061419957600080fd5b92506141a760608701614143565b9150608086015190509295509295909350565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156141e257600080fd5b613d7682614143565b60008060006060848603121561420057600080fd5b8351925061421060208501614143565b915061421e60408501614143565b90509250925092565b80820180821115612b1657612b16614035565b60006020828403121561424c57600080fd5b5051919050565b600181811c9082168061426757607f821691505b60208210810361428757634e487b7160e01b600052602260045260246000fd5b50919050565b8381526000602084602084015260606040840152600084546142ae81614253565b80606087015260806001808416600081146142d057600181146142ec5761431c565b60ff19851660808a0152608084151560051b8a0101955061431c565b89600052602060002060005b858110156143135781548b82018601529083019088016142f8565b8a016080019650505b50939a9950505050505050505050565b6000825161433e818460208701613d13565b9190910192915050565b600080600080600080600060e0888a03121561436357600080fd5b61436c88614127565b965061437a60208901614143565b955060408801519450606088015193506080880151925060a088015191506143a460c08901614143565b905092959891949750929550565b60208082526022908201527f416363657373206e6f7420616c6c6f7765643a20476f7665726e6f72206f6e6c6040820152613c9760f11b606082015260800190565b60208082526024908201527f416363657373206e6f7420616c6c6f7765643a204b6c65726f73436f7265206f60408201526337363c9760e11b606082015260800190565b601f821115611bf3576000816000526020600020601f850160051c810160208610156144615750805b601f850160051c820191505b818110156122455782815560010161446d565b6001600160401b0383111561449757614497613b26565b6144ab836144a58354614253565b83614438565b6000601f8411600181146144df57600085156144c75750838201355b600019600387901b1c1916600186901b178355614539565b600083815260209020601f19861690835b8281101561451057868501358255602094850194600190920191016144f0565b508682101561452d5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60006020828403121561455257600080fd5b8151613d7681613c17565b81835260006001600160fb1b0383111561457657600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006145a360408301858761455d565b9050826020830152949350505050565b6040815260006145c760408301858761455d565b82810360208401526145d98185613d37565b9695505050505050565b600080600080608085870312156145f957600080fd5b50508251602084015160408501516060909501519196909550909250905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220153f069dad597f5fd2a9ff2187cde96730a89b8658626e058a78cf4db9a2e35064736f6c63430008180033", "devdoc": { "errors": { "AlreadyInitialized()": [ @@ -1147,12 +1269,14 @@ "_voteIDs": "The identifiers of the votes in the dispute." } }, - "CommitCastShutter(bytes32,bytes32,bytes)": { + "CommitCastShutter(uint256,address,bytes32,bytes32,bytes)": { "details": "Emitted when a vote is cast.", "params": { "_commit": "The commitment hash.", + "_coreDisputeID": "The identifier of the dispute in the Arbitrator contract.", "_encryptedVote": "The Shutter encrypted vote.", - "_identity": "The Shutter identity used for encryption." + "_identity": "The Shutter identity used for encryption.", + "_juror": "The address of the juror casting the vote commitment." } }, "Contribution(uint256,uint256,uint256,address,uint256)": { @@ -1420,7 +1544,7 @@ "storageLayout": { "storage": [ { - "astId": 3945, + "astId": 19100, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "governor", "offset": 0, @@ -1428,23 +1552,23 @@ "type": "t_address" }, { - "astId": 3948, + "astId": 19103, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "core", "offset": 0, "slot": "1", - "type": "t_contract(KlerosCore)165" + "type": "t_contract(KlerosCore)8475" }, { - "astId": 3952, + "astId": 19107, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "disputes", "offset": 0, "slot": "2", - "type": "t_array(t_struct(Dispute)3880_storage)dyn_storage" + "type": "t_array(t_struct(Dispute)19035_storage)dyn_storage" }, { - "astId": 3956, + "astId": 19111, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "coreDisputeIDToLocal", "offset": 0, @@ -1452,12 +1576,20 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3958, + "astId": 19113, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "singleDrawPerJuror", "offset": 0, "slot": "4", "type": "t_bool" + }, + { + "astId": 19121, + "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", + "label": "alreadyDrawn", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_address,t_bool)))" } ], "types": { @@ -1466,20 +1598,20 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_struct(Dispute)3880_storage)dyn_storage": { - "base": "t_struct(Dispute)3880_storage", + "t_array(t_struct(Dispute)19035_storage)dyn_storage": { + "base": "t_struct(Dispute)19035_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Dispute[]", "numberOfBytes": "32" }, - "t_array(t_struct(Round)3922_storage)dyn_storage": { - "base": "t_struct(Round)3922_storage", + "t_array(t_struct(Round)19077_storage)dyn_storage": { + "base": "t_struct(Round)19077_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Round[]", "numberOfBytes": "32" }, - "t_array(t_struct(Vote)3931_storage)dyn_storage": { - "base": "t_struct(Vote)3931_storage", + "t_array(t_struct(Vote)19086_storage)dyn_storage": { + "base": "t_struct(Vote)19086_storage", "encoding": "dynamic_array", "label": "struct DisputeKitClassicBase.Vote[]", "numberOfBytes": "32" @@ -1505,7 +1637,7 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_contract(KlerosCore)165": { + "t_contract(KlerosCore)8475": { "encoding": "inplace", "label": "contract KlerosCore", "numberOfBytes": "20" @@ -1531,6 +1663,20 @@ "numberOfBytes": "32", "value": "t_bool" }, + "t_mapping(t_uint256,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_uint256,t_mapping(t_uint256,t_mapping(t_address,t_bool)))": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => mapping(uint256 => mapping(address => bool)))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_mapping(t_address,t_bool))" + }, "t_mapping(t_uint256,t_uint256)": { "encoding": "mapping", "key": "t_uint256", @@ -1538,20 +1684,20 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Dispute)3880_storage": { + "t_struct(Dispute)19035_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Dispute", "members": [ { - "astId": 3869, + "astId": 19024, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "rounds", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Round)3922_storage)dyn_storage" + "type": "t_array(t_struct(Round)19077_storage)dyn_storage" }, { - "astId": 3871, + "astId": 19026, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "numberOfChoices", "offset": 0, @@ -1559,7 +1705,7 @@ "type": "t_uint256" }, { - "astId": 3873, + "astId": 19028, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "jumped", "offset": 0, @@ -1567,7 +1713,7 @@ "type": "t_bool" }, { - "astId": 3877, + "astId": 19032, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "coreRoundIDToLocal", "offset": 0, @@ -1575,7 +1721,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3879, + "astId": 19034, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "extraData", "offset": 0, @@ -1585,20 +1731,20 @@ ], "numberOfBytes": "160" }, - "t_struct(Round)3922_storage": { + "t_struct(Round)19077_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Round", "members": [ { - "astId": 3884, + "astId": 19039, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "votes", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Vote)3931_storage)dyn_storage" + "type": "t_array(t_struct(Vote)19086_storage)dyn_storage" }, { - "astId": 3886, + "astId": 19041, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "winningChoice", "offset": 0, @@ -1606,7 +1752,7 @@ "type": "t_uint256" }, { - "astId": 3890, + "astId": 19045, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "counts", "offset": 0, @@ -1614,7 +1760,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3892, + "astId": 19047, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "tied", "offset": 0, @@ -1622,7 +1768,7 @@ "type": "t_bool" }, { - "astId": 3894, + "astId": 19049, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "totalVoted", "offset": 0, @@ -1630,7 +1776,7 @@ "type": "t_uint256" }, { - "astId": 3896, + "astId": 19051, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "totalCommitted", "offset": 0, @@ -1638,7 +1784,7 @@ "type": "t_uint256" }, { - "astId": 3900, + "astId": 19055, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "paidFees", "offset": 0, @@ -1646,7 +1792,7 @@ "type": "t_mapping(t_uint256,t_uint256)" }, { - "astId": 3904, + "astId": 19059, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "hasPaid", "offset": 0, @@ -1654,7 +1800,7 @@ "type": "t_mapping(t_uint256,t_bool)" }, { - "astId": 3910, + "astId": 19065, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "contributions", "offset": 0, @@ -1662,7 +1808,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 3912, + "astId": 19067, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "feeRewards", "offset": 0, @@ -1670,7 +1816,7 @@ "type": "t_uint256" }, { - "astId": 3915, + "astId": 19070, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "fundedChoices", "offset": 0, @@ -1678,7 +1824,7 @@ "type": "t_array(t_uint256)dyn_storage" }, { - "astId": 3917, + "astId": 19072, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "nbVotes", "offset": 0, @@ -1686,7 +1832,7 @@ "type": "t_uint256" }, { - "astId": 3921, + "astId": 19076, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "alreadyDrawn", "offset": 0, @@ -1696,12 +1842,12 @@ ], "numberOfBytes": "416" }, - "t_struct(Vote)3931_storage": { + "t_struct(Vote)19086_storage": { "encoding": "inplace", "label": "struct DisputeKitClassicBase.Vote", "members": [ { - "astId": 3924, + "astId": 19079, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "account", "offset": 0, @@ -1709,7 +1855,7 @@ "type": "t_address" }, { - "astId": 3926, + "astId": 19081, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "commit", "offset": 0, @@ -1717,7 +1863,7 @@ "type": "t_bytes32" }, { - "astId": 3928, + "astId": 19083, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "choice", "offset": 0, @@ -1725,7 +1871,7 @@ "type": "t_uint256" }, { - "astId": 3930, + "astId": 19085, "contract": "src/arbitration/dispute-kits/DisputeKitShutter.sol:DisputeKitShutter", "label": "voted", "offset": 0, diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol index 95b225e91..6c799a4cb 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol @@ -11,7 +11,7 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol"; /// - an incentive system: equal split between coherent votes, /// - an appeal system: fund 2 choices only, vote on any choice. contract DisputeKitClassic is DisputeKitClassicBase { - string public constant override version = "0.10.0"; + string public constant override version = "0.11.0"; // ************************************* // // * Constructor * // @@ -29,7 +29,7 @@ contract DisputeKitClassic is DisputeKitClassicBase { __DisputeKitClassicBase_initialize(_governor, _core); } - function initialize6() external reinitializer(6) { + function initialize7() external reinitializer(7) { // NOP } diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol index 2aa85ca7a..3541ab8ae 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol @@ -38,6 +38,7 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi uint256 feeRewards; // Sum of reimbursable appeal fees available to the parties that made contributions to the ruling that ultimately wins a dispute. uint256[] fundedChoices; // Stores the choices that are fully funded. uint256 nbVotes; // Maximal number of votes this dispute can get. + //mapping(address drawnAddress => bool) alreadyDrawn; // DEPRECATED: DO NOT COMMIT } struct Vote { @@ -280,7 +281,7 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi uint256 _salt, string memory _justification ) external { - _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification); + _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification, msg.sender); } function _castVote( @@ -288,7 +289,8 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi uint256[] calldata _voteIDs, uint256 _choice, uint256 _salt, - string memory _justification + string memory _justification, + address _juror ) internal notJumped(_coreDisputeID) { (, , KlerosCore.Period period, , ) = core.disputes(_coreDisputeID); require(period == KlerosCoreBase.Period.vote, "The dispute should be in Vote period."); @@ -298,21 +300,23 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi require(_choice <= dispute.numberOfChoices, "Choice out of bounds"); Round storage round = dispute.rounds[dispute.rounds.length - 1]; - (uint96 courtID, , , , ) = core.disputes(_coreDisputeID); - (, bool hiddenVotes, , , , , ) = core.courts(courtID); - bytes32 voteHash = hashVote(_choice, _salt, _justification); - - // Save the votes. - for (uint256 i = 0; i < _voteIDs.length; i++) { - require(round.votes[_voteIDs[i]].account == msg.sender, "The caller has to own the vote."); - require( - !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash, - "The vote hash must match the commitment in courts with hidden votes." - ); - require(!round.votes[_voteIDs[i]].voted, "Vote already cast."); - round.votes[_voteIDs[i]].choice = _choice; - round.votes[_voteIDs[i]].voted = true; - } + { + (uint96 courtID, , , , ) = core.disputes(_coreDisputeID); + (, bool hiddenVotes, , , , , ) = core.courts(courtID); + bytes32 voteHash = hashVote(_choice, _salt, _justification); + + // Save the votes. + for (uint256 i = 0; i < _voteIDs.length; i++) { + require(round.votes[_voteIDs[i]].account == _juror, "The juror has to own the vote."); + require( + !hiddenVotes || round.votes[_voteIDs[i]].commit == voteHash, + "The vote hash must match the commitment in courts with hidden votes." + ); + require(!round.votes[_voteIDs[i]].voted, "Vote already cast."); + round.votes[_voteIDs[i]].choice = _choice; + round.votes[_voteIDs[i]].voted = true; + } + } // Workaround stack too deep round.totalVoted += _voteIDs.length; @@ -330,7 +334,7 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi round.tied = false; } } - emit VoteCast(_coreDisputeID, msg.sender, _voteIDs, _choice, _justification); + emit VoteCast(_coreDisputeID, _juror, _voteIDs, _choice, _justification); } /// @dev Manages contributions, and appeals a dispute if at least two choices are fully funded. @@ -623,6 +627,32 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi ); } + /// @dev Returns the number of rounds in a dispute. + /// @param _localDisputeID The ID of the dispute in the Dispute Kit. + /// @return The number of rounds in the dispute. + function getNumberOfRounds(uint256 _localDisputeID) external view returns (uint256) { + return disputes[_localDisputeID].rounds.length; + } + + /// @dev Returns the local dispute ID and round ID for a given core dispute ID and core round ID. + /// @param _coreDisputeID The ID of the dispute in Kleros Core. + /// @param _coreRoundID The ID of the round in Kleros Core. + /// @return localDisputeID The ID of the dispute in the Dispute Kit. + /// @return localRoundID The ID of the round in the Dispute Kit. + function getLocalDisputeRoundID( + uint256 _coreDisputeID, + uint256 _coreRoundID + ) external view returns (uint256 localDisputeID, uint256 localRoundID) { + localDisputeID = coreDisputeIDToLocal[_coreDisputeID]; + localRoundID = disputes[localDisputeID].coreRoundIDToLocal[_coreRoundID]; + } + + /// @dev Returns the vote information for a given vote ID. + /// @param _coreDisputeID The ID of the dispute in Kleros Core. + /// @param _coreRoundID The ID of the round in Kleros Core. + /// @param _voteID The ID of the vote. + /// @return account The address of the juror who cast the vote. + /// @return commit The commit of the vote. function getVoteInfo( uint256 _coreDisputeID, uint256 _coreRoundID, diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol index 2289f0481..320463722 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitShutter.sol @@ -12,17 +12,25 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol"; /// - an appeal system: fund 2 choices only, vote on any choice. /// Added functionality: an Shutter-specific event emitted when a vote is cast. contract DisputeKitShutter is DisputeKitClassicBase { - string public constant override version = "0.9.3"; + string public constant override version = "0.11.1"; // ************************************* // // * Events * // // ************************************* // /// @dev Emitted when a vote is cast. + /// @param _coreDisputeID The identifier of the dispute in the Arbitrator contract. + /// @param _juror The address of the juror casting the vote commitment. /// @param _commit The commitment hash. /// @param _identity The Shutter identity used for encryption. /// @param _encryptedVote The Shutter encrypted vote. - event CommitCastShutter(bytes32 indexed _commit, bytes32 _identity, bytes _encryptedVote); + event CommitCastShutter( + uint256 indexed _coreDisputeID, + address indexed _juror, + bytes32 indexed _commit, + bytes32 _identity, + bytes _encryptedVote + ); // ************************************* // // * Constructor * // @@ -40,7 +48,7 @@ contract DisputeKitShutter is DisputeKitClassicBase { __DisputeKitClassicBase_initialize(_governor, _core); } - function initialize5() external reinitializer(5) { + function initialize8() external reinitializer(8) { // NOP } @@ -75,7 +83,21 @@ contract DisputeKitShutter is DisputeKitClassicBase { bytes calldata _encryptedVote ) external notJumped(_coreDisputeID) { _castCommit(_coreDisputeID, _voteIDs, _commit); - emit CommitCastShutter(_commit, _identity, _encryptedVote); + emit CommitCastShutter(_coreDisputeID, msg.sender, _commit, _identity, _encryptedVote); + } + + function castVoteShutter( + uint256 _coreDisputeID, + uint256[] calldata _voteIDs, + uint256 _choice, + uint256 _salt, + string memory _justification + ) external { + Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]]; + address juror = dispute.rounds[dispute.rounds.length - 1].votes[_voteIDs[0]].account; + + // _castVote() ensures that all the _voteIDs do belong to `juror` + _castVote(_coreDisputeID, _voteIDs, _choice, _salt, _justification, juror); } // ************************************* //